Skip to content
Published on

Zero Trust 아키텍처 완전 가이드 2025: Never Trust Always Verify, BeyondCorp, SASE

Authors

목차

1. 왜 Zero Trust인가: 경계 보안의 종말

1.1 전통적 경계 보안 모델의 한계

전통적인 네트워크 보안은 "성과 해자(Castle and Moat)" 모델을 기반으로 했습니다. 방화벽 안쪽은 신뢰하고, 바깥쪽은 불신하는 단순한 구조였습니다.

전통적 경계 보안 모델:

  [인터넷]  ──── [방화벽] ──── [내부 네트워크 (신뢰 영역)]
     │                              │
   불신 영역                    모든 것이 신뢰됨
     │                              │
  VPN으로만                    자유로운 이동
   접근 가능                   (Lateral Movement)

하지만 이 모델은 다음과 같은 현실에서 무너졌습니다.

경계가 사라진 이유:

변화 요인영향
클라우드 전환데이터와 애플리케이션이 내부 네트워크 밖으로 이동
원격/하이브리드 근무직원이 어디서든 접속. VPN 과부하
SaaS 확산비즈니스 데이터가 수십 개 SaaS에 분산
BYOD관리되지 않는 개인 디바이스로 업무
API 경제서비스 간 통신이 네트워크 경계를 넘어 확장
공급망 공격신뢰했던 내부 소프트웨어가 공격 벡터로 변환

1.2 실제 침해 사례에서 배우는 교훈

침해 패턴 (경계 보안 실패):

1. 초기 침투
   피싱 이메일 → 직원 1명의 계정 탈취

2. 내부 이동 (Lateral Movement)
   신뢰된 내부 네트워크에서 자유롭게 이동
   → 다른 서버, DB에 무제한 접근

3. 권한 상승
   내부 네트워크이므로 추가 인증 없음
   → 관리자 권한 획득

4. 데이터 유출
   내부에서 외부로의 통신은 느슨하게 관리
   → 대량 데이터 유출

SolarWinds 공급망 공격(2020), Colonial Pipeline 랜섬웨어(2021) 등은 모두 "내부는 안전하다"는 가정이 얼마나 위험한지 보여준 사례입니다.

1.3 Zero Trust의 등장

Zero Trust는 2010년 Forrester Research의 John Kindervag가 제안한 보안 모델입니다.

핵심 철학은 단순합니다: "Never Trust, Always Verify" (절대 신뢰하지 말고, 항상 검증하라)

Zero Trust 기본 원칙:

┌─────────────────────────────────────────────────┐
Zero Trust Architecture│                                                  │
1. 명시적 검증 (Verify Explicitly)│     → 모든 접근 요청을 인증 + 인가                │
│     → 사용자, 디바이스, 위치, 행동 패턴 검증      │
│                                                  │
2. 최소 권한 (Least Privilege Access)│     → 필요한 최소한의 권한만 부여                  │
│     → Just-In-Time, Just-Enough-Access│                                                  │
3. 침해 가정 (Assume Breach)│     → 이미 내부가 뚫렸다고 가정                    │
│     → 폭발 반경(Blast Radius) 최소화              │
│     → 마이크로세그멘테이션으로 격리                │
└─────────────────────────────────────────────────┘

2. NIST 800-207: Zero Trust 프레임워크 표준

2.1 NIST Zero Trust 아키텍처 개요

NIST SP 800-207은 Zero Trust를 구현하기 위한 표준 프레임워크입니다.

NIST 800-207 Zero Trust Architecture:

  [사용자/디바이스]
  ┌──────────────┐     ┌──────────────────────┐
PEP         │────▶│  PDP (Policy Engine)Policy      │◀────│  + Policy AdminEnforcement │     │                       │
Point       │     │  결정 기준:  └──────┬───────┘     │  - 사용자 ID         │             │  - 디바이스 상태       │
         ▼             │  - 네트워크 위치       │
  ┌──────────────┐     │  - 요청 리소스         │
Enterprise  │     │  - 시간/행동 패턴      │
Resources   │     └──────────────────────┘
  └──────────────┘              │
                    ┌──────────────────────┐
Data Sources:- CDM (자산 관리)- Threat Intel- Activity Logs- Compliance- SIEM/SOAR                    └──────────────────────┘

2.2 핵심 컴포넌트

Policy Engine (PE): 접근 허용/거부를 결정하는 두뇌입니다.

# Policy Engine 의사결정 예시
policy_evaluation:
  input:
    user: "engineer@company.com"
    device_trust_score: 85
    location: "South Korea"
    resource: "production-database"
    time: "2025-03-15T14:30:00Z"
    mfa_verified: true
    risk_score: "low"

  rules:
    - name: "prod-db-access"
      conditions:
        - user.role IN ["sre", "dba"]
        - device.trust_score >= 80
        - device.os_patched == true
        - mfa.verified == true
        - risk.score IN ["low", "medium"]
      action: "allow"
      session_controls:
        max_duration: "4h"
        require_reauthentication: true
        log_all_queries: true

  decision: "ALLOW with session controls"

Policy Enforcement Point (PEP): 실제로 접근을 제어하는 게이트입니다.

PEP 동작 흐름:

  요청 → [PEP] → 정책 확인 요청 → [PDP]
                              허용/거부 결정
          [PEP] ← 결정 수신 ←─────────┘
       허용 시 → 리소스 접근 (암호화 채널)
       거부 시 → 접근 차단 + 로깅

2.3 Zero Trust 성숙도 모델

CISA Zero Trust 성숙도 모델:

Level 1: Traditional (전통적)
├── 정적 보안 정책
├── 수동 프로비저닝
└── 제한적 가시성

Level 2: Advanced (고도화)
├── 일부 자동화된 정책
├── 중앙화된 ID 관리
├── 기본 분석

Level 3: Optimal (최적)
├── 완전 자동화된 정책
├── 지속적 검증
├── AI/ML 기반 분석
└── 동적 정책 적용

5개 핵심 영역:
┌────────────┬────────────┬────────────┬────────────┬────────────┐
IdentityDevicesNetworksApps/Data│            │            │            │  Workloads │            │
├────────────┼────────────┼────────────┼────────────┼────────────┤
MFA, SSOMDM, EDRMicro-SDLC       │ 분류,Conditional│ 디바이스   │ SegmentDAST/SASTDLP,Access     │ 인벤토리   │ 암호화     │ Runtime    │ 암호화     │
└────────────┴────────────┴────────────┴────────────┴────────────┘

3. Google BeyondCorp: Zero Trust의 실제 구현

3.1 BeyondCorp 탄생 배경

Google은 2009년 Operation Aurora 공격 이후 내부 네트워크 보안을 근본적으로 재설계했습니다. 그 결과가 BeyondCorp입니다.

BeyondCorp 핵심 원칙:

1. 네트워크 위치로 신뢰를 결정하지 않음
   → 회사 사무실 = 카페 Wi-Fi (동일하게 취급)

2. 접근 권한은 사용자 + 디바이스에 의해 결정
누구(Who) + 무엇(What device) + 어떤 상태(Health)

3. 모든 접근은 인증, 인가, 암호화
VPN 불필요. 인터넷을 통해 직접 접근

4. 접근 정책은 동적이고 지속적으로 평가
   → 한 번 인증으로 끝나지 않음

3.2 BeyondCorp 아키텍처

BeyondCorp Architecture:

  [직원 디바이스]
        (인터넷 - 어디서든)
  ┌──────────────────┐
Access Proxy     │ ← 모든 요청의 진입점
    (Identity-AwareProxy)  └────────┬─────────┘
    ┌──────┴──────┐
    ▼              ▼
┌────────┐   ┌────────────┐
Access │   │ DeviceControl│InventoryEngine │   │ Service└───┬────┘   └─────┬──────┘
    │              │
    ▼              ▼
┌────────────────────────┐
Trust Evaluation│                         │
User Identity ────────┤
Device State ─────────┤
Access Policy ────────┤
Context (time, loc) ──┤
│                         │
│  → Trust Score 계산     │
│  → 접근 허용/거부 결정  │
└────────────────────────┘

3.3 Identity-Aware Proxy (IAP) 구현

Google Cloud IAP를 사용한 구현 예시입니다.

# GCP IAP 설정 예시
# iap-config.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: iap-backend-config
spec:
  iap:
    enabled: true
    oauthclientCredentials:
      secretName: iap-oauth-secret
  securityPolicy:
    name: "rate-limit-policy"
  healthCheck:
    requestPath: /healthz
    port: 8080
# IAP를 통한 접근 검증 (서버 사이드)
from google.auth.transport import requests
from google.oauth2 import id_token

def verify_iap_jwt(iap_jwt, expected_audience):
    """IAP JWT 토큰을 검증하여 사용자 ID를 반환"""
    try:
        decoded_jwt = id_token.verify_token(
            iap_jwt,
            requests.Request(),
            audience=expected_audience,
            certs_url="https://www.gstatic.com/iap/verify/public_key"
        )
        return {
            "email": decoded_jwt["email"],
            "sub": decoded_jwt["sub"],
            "access_levels": decoded_jwt.get("google", {}).get(
                "access_levels", []
            )
        }
    except Exception as e:
        print(f"JWT verification failed: {e}")
        return None

# 접근 레벨 기반 정책 적용
def check_access_policy(user_info, resource):
    """사용자의 접근 레벨과 리소스 정책을 비교"""
    required_levels = get_resource_policy(resource)
    user_levels = set(user_info.get("access_levels", []))

    if required_levels.issubset(user_levels):
        return True
    return False

3.4 BeyondCorp 마이그레이션 단계

Google의 BeyondCorp 전환 과정 (8):

Phase 1: 가시성 확보 (Visibility)
├── 모든 디바이스 인벤토리 구축
├── 모든 사용자 접근 패턴 분석
└── 기존 VPN 트래픽 모니터링

Phase 2: 접근 프록시 구축
├── Identity-Aware Proxy 배포
├── 내부 애플리케이션을 프록시 뒤로 이동
└── 인증서 기반 디바이스 인증

Phase 3: 정책 엔진 구축
├── 동적 접근 정책 정의
├── 디바이스 신뢰도 점수 시스템
└── 컨텍스트 기반 접근 제어

Phase 4: VPN 제거
├── 점진적 VPN 트래픽 감소
├── 모든 앱을 프록시 기반으로 전환
└── VPN 완전 폐기

Phase 5: 지속적 개선
├── ML 기반 이상 탐지
├── 실시간 리스크 평가
└── 자동 대응 (SOAR 통합)

4. Identity 중심 보안

4.1 IAM (Identity and Access Management) 아키텍처

현대적 IAM 아키텍처:

  ┌─────────────────────────────────────────┐
Identity Provider (IdP)  │                                          │
  │  ┌──────────┐  ┌──────────┐  ┌────────┐│
  │  │ User     │  │ Directory│MFA    ││
  │  │ Store    │  │ Service  │  │ Engine ││
 (DB) (LDAP/   │  │        ││
  │  │          │  │  SCIM)   │  │        ││
  │  └──────────┘  └──────────┘  └────────┘│
  │                                          │
  │  ┌──────────┐  ┌──────────┐  ┌────────┐│
  │  │ SSO      │  │ OAuth2/  │  │ Risk   ││
  │  │ Engine   │  │ OIDC     │  │ Engine ││
 (SAML)   │  │ Server   │  │        ││
  │  └──────────┘  └──────────┘  └────────┘│
  └─────────────────────────────────────────┘
           │              │
      ┌────┴────┐    ┌───┴────┐
      ▼         ▼    ▼        ▼
   [SaaS]   [Internal] [Cloud]  [API]
    Apps      Apps      Infra   Services

4.2 Conditional Access Policy

# Conditional Access 정책 엔진 구현 예시
from dataclasses import dataclass
from enum import Enum
from typing import List, Optional

class RiskLevel(Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"

@dataclass
class AccessContext:
    user_id: str
    user_role: str
    device_compliant: bool
    device_managed: bool
    mfa_completed: bool
    mfa_method: str  # "phishing_resistant", "push", "sms"
    location: str  # "corporate", "home", "unknown"
    ip_reputation: str  # "trusted", "suspicious", "malicious"
    risk_score: float  # 0.0 - 1.0
    resource_sensitivity: str  # "public", "internal", "confidential", "restricted"

class ConditionalAccessEngine:
    def evaluate(self, ctx: AccessContext) -> dict:
        """접근 요청을 평가하여 결정을 반환"""

        # Rule 1: 악성 IP는 무조건 차단
        if ctx.ip_reputation == "malicious":
            return self._deny("Malicious IP detected")

        # Rule 2: 고위험 리소스 접근
        if ctx.resource_sensitivity == "restricted":
            if not ctx.mfa_completed:
                return self._step_up("Require MFA for restricted resource")
            if ctx.mfa_method != "phishing_resistant":
                return self._step_up("Require phishing-resistant MFA (FIDO2)")
            if not ctx.device_managed:
                return self._deny("Managed device required for restricted access")

        # Rule 3: 위험 점수 기반 동적 정책
        if ctx.risk_score > 0.8:
            return self._deny("Risk score too high")
        elif ctx.risk_score > 0.5:
            if not ctx.mfa_completed:
                return self._step_up("Elevated risk - MFA required")
            return self._allow_limited(session_duration="1h")

        # Rule 4: 비관리 디바이스
        if not ctx.device_managed:
            if ctx.resource_sensitivity in ["confidential", "restricted"]:
                return self._deny("Managed device required")
            return self._allow_limited(
                session_duration="4h",
                block_download=True
            )

        return self._allow()

    def _allow(self):
        return {"decision": "allow", "session_duration": "8h"}

    def _allow_limited(self, **kwargs):
        return {"decision": "allow_limited", **kwargs}

    def _deny(self, reason: str):
        return {"decision": "deny", "reason": reason}

    def _step_up(self, reason: str):
        return {"decision": "step_up_auth", "reason": reason}

4.3 Multi-Factor Authentication (MFA) 전략

MFA 강도 피라미드:

   가장 강력 ▲
             │  ┌─────────────────────────┐
             │  │  FIDO2/WebAuthn         │ ← 하드웨어  (YubiKey)
  (피싱 방지)패스키 (Passkey)
             │  └─────────────────────────┘
             │  ┌─────────────────────────┐
             │  │  인증서 기반            │ ← 디바이스 인증서
  (Certificate-based)    │   스마트카드
             │  └─────────────────────────┘
             │  ┌─────────────────────────┐
             │  │  앱 기반 Push/TOTP      │ ← Authenticator             │  │                         │   시간 기반 OTP
             │  └─────────────────────────┘
             │  ┌─────────────────────────┐
             │  │  SMS/Email OTP          │ ← SIM 스와핑 취약
   가장 약함 │    (피싱 가능)            │   이메일 탈취 시 무력화
             ▼  └─────────────────────────┘
# Okta Conditional MFA 설정 예시
authentication_policies:
  - name: "High Security Resources"
    conditions:
      applications:
        - "production-admin"
        - "financial-systems"
        - "customer-data-platform"
    actions:
      require_mfa: true
      allowed_factors:
        - "fido2_webauthn"
        - "okta_verify_push"
      factor_lifetime: "1h"
      re_authentication_frequency: "every_request"

  - name: "Standard Resources"
    conditions:
      applications:
        - "email"
        - "chat"
        - "wiki"
    actions:
      require_mfa: true
      allowed_factors:
        - "fido2_webauthn"
        - "okta_verify_push"
        - "okta_verify_totp"
      factor_lifetime: "12h"
      re_authentication_frequency: "every_sign_on"

  - name: "Unknown Location Policy"
    conditions:
      network_zones:
        exclude:
          - "corporate_network"
          - "known_vpn_endpoints"
    actions:
      require_mfa: true
      allowed_factors:
        - "fido2_webauthn"
      session_lifetime: "4h"

5. Device Trust: 디바이스 신뢰도 평가

5.1 디바이스 포스처 평가 아키텍처

Device Trust 평가 흐름:

  [디바이스] → 에이전트가 상태 수집
  ┌──────────────────────────────────┐
Device Trust Signal  │                                  │
OS 버전/패치 상태 ─────── 20%  │  디스크 암호화 ────────── 15%  │  방화벽 활성화 ────────── 10%EDR 설치/실행 ────────── 20%MDM 관리 상태 ────────── 15%  │  인증서 유효성 ────────── 10%  │  최근 보안 스캔 ───────── 10%  │                                  │
  │  → Trust Score: 0-100  └──────────────────────────────────┘
  접근 정책에 Trust Score 반영
  Score >= 80Full Access
  Score >= 60Limited Access
  Score < 60Block + 안내

5.2 디바이스 인증서 기반 인증

# 디바이스 인증서 검증 로직
import ssl
from cryptography import x509
from cryptography.x509.oid import NameOID

class DeviceCertificateValidator:
    def __init__(self, ca_cert_path: str, crl_url: str):
        self.ca_cert = self._load_cert(ca_cert_path)
        self.crl_url = crl_url

    def validate_device(self, client_cert_pem: bytes) -> dict:
        """디바이스 인증서를 검증하고 디바이스 정보를 반환"""
        try:
            cert = x509.load_pem_x509_certificate(client_cert_pem)

            # 1. 유효기간 확인
            self._check_validity(cert)

            # 2. CA 서명 확인
            self._verify_signature(cert)

            # 3. CRL (인증서 폐기 목록) 확인
            self._check_revocation(cert)

            # 4. 디바이스 정보 추출
            device_info = {
                "device_id": cert.subject.get_attributes_for_oid(
                    NameOID.COMMON_NAME
                )[0].value,
                "org": cert.subject.get_attributes_for_oid(
                    NameOID.ORGANIZATION_NAME
                )[0].value,
                "serial": str(cert.serial_number),
                "not_after": cert.not_valid_after_utc.isoformat(),
                "verified": True
            }

            return device_info

        except Exception as e:
            return {"verified": False, "error": str(e)}

5.3 EDR/MDM 통합

# Microsoft Intune 컴플라이언스 정책 예시
compliance_policy:
  name: "Zero Trust Device Compliance"
  platforms:
    - windows
    - macos
    - ios
    - android

  windows_rules:
    os_minimum_version: "10.0.19045"  # Windows 10 22H2+
    bitlocker_required: true
    secure_boot_required: true
    tpm_required: true
    firewall_required: true
    antivirus_required: true
    antivirus_signatures_up_to_date: true
    defender_for_endpoint_risk_level: "medium_or_below"

  macos_rules:
    os_minimum_version: "14.0"  # Sonoma+
    filevault_required: true
    firewall_required: true
    gatekeeper_required: true
    system_integrity_protection: true

  non_compliance_actions:
    - action: "notify_user"
      grace_period_hours: 0
      message: "디바이스가 보안 정책을 충족하지 않습니다"
    - action: "mark_non_compliant"
      grace_period_hours: 24
    - action: "block_access"
      grace_period_hours: 72
    - action: "retire_device"
      grace_period_hours: 720  # 30일

6. 마이크로세그멘테이션

6.1 네트워크 세그멘테이션 진화

세그멘테이션 진화:

1. 전통적: VLAN 기반
   ┌──────────┐  ┌──────────┐  ┌──────────┐
VLAN 10 │  │  VLAN 20 │  │  VLAN 30     (개발)  (운영)  (DB)   └──────────┘  └──────────┘  └──────────┘
   → 같은 VLAN 내 자유 통신 (문제!)

2. 방화벽 기반: Zone 세그멘테이션
   ┌──────────┐     ┌──────────┐
Trust   │─FW─▶│  DMZ     │─FW─▶ Internet
Zone    │     │  Zone   └──────────┘     └──────────┘
Zone 간 제어, Zone자유 (부족)

3. 마이크로세그멘테이션: 워크로드 수준
   ┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
A │─│B │ │C │─│D │ │E   └──┘ └──┘ └──┘ └──┘ └──┘
     │         │
     └────X────┘  ← AC 간 통신 차단
   → 워크로드 간 개별 정책 (이상적)

6.2 Kubernetes NetworkPolicy

# 1. 기본 정책: 모든 트래픽 차단 (Default Deny)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
# 2. 프론트엔드 → 백엔드 API만 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-api
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend-api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080
---
# 3. 백엔드 API → DB만 허용
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: backend-api
      ports:
        - protocol: TCP
          port: 5432
---
# 4. DNS 접근 허용 (모든 Pod)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53

6.3 Service Mesh mTLS (Istio)

# Istio PeerAuthentication: 전체 메시에 mTLS 강제
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT  # mTLS 필수. 평문 트래픽 거부
---
# AuthorizationPolicy: 서비스 간 접근 제어
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: payment-service-policy
  namespace: production
spec:
  selector:
    matchLabels:
      app: payment-service
  rules:
    # Rule 1: order-service만 결제 API 호출 허용
    - from:
        - source:
            principals:
              - "cluster.local/ns/production/sa/order-service"
      to:
        - operation:
            methods: ["POST"]
            paths: ["/api/v1/payments", "/api/v1/payments/*"]
    # Rule 2: 모니터링 서비스는 health check만 허용
    - from:
        - source:
            principals:
              - "cluster.local/ns/monitoring/sa/prometheus"
      to:
        - operation:
            methods: ["GET"]
            paths: ["/health", "/metrics"]
  # 나머지 모든 접근은 암묵적으로 거부됨

7. ZTNA vs VPN 비교

7.1 근본적 차이점

VPN (전통적):

  [사용자] ──VPN 터널──▶ [회사 네트워크 전체에 접근]
                    모든 내부 리소스 노출
                    (불필요한 서버도 보임)

ZTNA (Zero Trust):

  [사용자] ──암호화 채널──▶ [허가된 앱 A만 접근]
                    나머지 네트워크는 보이지 않음
                    (Dark Cloud 원칙)

7.2 상세 비교표

항목VPNZTNA
접근 범위네트워크 전체 (과도한 접근)특정 애플리케이션만 (최소 권한)
인증초기 1회 인증지속적 인증/검증
디바이스 검사제한적 또는 없음디바이스 포스처 실시간 평가
사용자 경험느림, VPN 클라이언트 필요빠름, 투명한 접근
확장성VPN 서버 병목클라우드 기반 무제한 확장
네트워크 가시성내부 네트워크 노출앱 수준만 노출 (Dark Cloud)
Lateral Movement가능 (네트워크 접근)불가능 (앱 격리)
성능모든 트래픽이 VPN 경유직접 접근 (Split Tunnel)
관리 복잡도높음 (HW/SW 관리)낮음 (SaaS 기반)
비용HW 어플라이언스 + 라이선스사용자 기반 구독

7.3 ZTNA 구현 예시 (Cloudflare Access)

# Cloudflare Access 정책 예시
application:
  name: "Internal Dashboard"
  domain: "dashboard.company.com"
  type: "self_hosted"

  identity_providers:
    - name: "Okta"
      type: "saml"
    - name: "GitHub"
      type: "oauth"

  policies:
    - name: "Allow Engineering"
      decision: "allow"
      include:
        - group: "engineering@company.com"
      require:
        - mfa: true
        - device_posture:
            - serial_number_check: true
            - disk_encryption: true
            - os_version:
                operator: ">="
                version: "14.0"

    - name: "Block Countries"
      decision: "block"
      include:
        - country:
            - "KP"
            - "IR"
            - "SY"

  session_duration: "12h"
  cors_headers:
    allowed_origins: ["https://dashboard.company.com"]
    allowed_methods: ["GET", "POST"]

8. SASE (Secure Access Service Edge) 아키텍처

8.1 SASE 개요

SASE = 네트워크(SD-WAN) + 보안(SSE)을 클라우드에서 통합

  ┌─────────────────────────────────────────────────────┐
SASE Platform  │                                                      │
  │  ┌─────────────────┐  ┌──────────────────────────┐  │
  │  │   SD-WAN         │  │   SSE (Security)          │  │
  │  │                  │  │                           │  │
  │  │  - WAN 최적화    │  │  - ZTNA                  │  │
  │  │  - 트래픽 제어   │  │  - CASB (Cloud Access    │  │
  │  │  - QoS           │  │         Security Broker)  │  │
  │  │  - 멀티링크      │  │  - SWG (Secure Web GW)   │  │
  │  │                  │  │  - FWaaS (FW as Service)  │  │
  │  │                  │  │  - DLP (Data Loss Prev.)  │  │
  │  └─────────────────┘  └──────────────────────────┘  │
  │                                                      │
  │  ┌──────────────────────────────────────────────┐   │
  │  │  공통 기능: 통합 정책, 통합 콘솔, API 통합    │   │
  │  └──────────────────────────────────────────────┘   │
  └─────────────────────────────────────────────────────┘
         │              │              │
    ┌────┴────┐   ┌────┴────┐   ┌────┴────┐
    │ 본사    │   │ 지사    │   │ 원격    │
     (HQ)(Branch) (Remote)    └─────────┘   └─────────┘   └─────────┘

8.2 SASE 구성 요소 상세

ZTNA (Zero Trust Network Access):
├── 사용자/디바이스 인증
├── 앱 수준 접근 제어
├── 컨텍스트 기반 정책
└── VPN 대체

CASB (Cloud Access Security Broker):
├── Shadow IT 발견
├── SaaS 데이터 보호 (DLP)
├── 이상 행동 탐지 (UEBA)
└── 컴플라이언스 모니터링

SWG (Secure Web Gateway):
├── URL 필터링
├── 멀웨어 차단
├── SSL/TLS 검사
└── 콘텐츠 필터링

FWaaS (Firewall as a Service):
├── L3-L7 방화벽
├── IPS/IDS
├── DNS 보안
└── 클라우드 기반 확장

8.3 SASE 벤더 비교

벤더강점ZTNACASBSWGSD-WAN
Zscaler보안 전문, 글로벌 엣지OOO파트너
Palo Alto (Prisma)통합 보안 플랫폼OOOO
Cloudflare One개발자 친화적, 글로벌 네트워크OOOO
NetskopeCASB/DLP 최강OOO파트너
Cisco (Umbrella + Viptela)엔터프라이즈 네트워크 강점OOOO

9. Zero Trust for Kubernetes

9.1 K8s Zero Trust 아키텍처

Kubernetes Zero Trust 계층:

Layer 1: Cluster Access
├── RBAC (Role-Based Access Control)
├── OIDC 인증 (kubectl + IdP)
├── Admission Control (OPA/Kyverno)
└── API Server Audit Logging

Layer 2: Pod-to-Pod Communication
├── NetworkPolicy (기본 L3/L4)
├── Service Mesh mTLS (L7)
├── DNS Policy
└── Egress Control

Layer 3: Workload Identity
├── ServiceAccount Token (Projected)
├── SPIFFE/SPIRE
├── Workload Identity Federation
└── Secret Management (Vault)

Layer 4: Data Protection
├── Encryption at Rest (etcd)
├── Encryption in Transit (TLS)
├── Secret Encryption (KMS)
└── PodSecurity Standards

9.2 OPA/Gatekeeper 정책

# OPA Gatekeeper: Pod Security 강제
# ConstraintTemplate 정의
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredsecuritycontext
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredSecurityContext
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredsecuritycontext

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.securityContext.runAsNonRoot
          msg := sprintf(
            "Container '%v' must set runAsNonRoot to true",
            [container.name]
          )
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          not container.securityContext.readOnlyRootFilesystem
          msg := sprintf(
            "Container '%v' must set readOnlyRootFilesystem to true",
            [container.name]
          )
        }

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          container.securityContext.privileged
          msg := sprintf(
            "Container '%v' must not be privileged",
            [container.name]
          )
        }
---
# Constraint 적용
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredSecurityContext
metadata:
  name: must-have-security-context
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    namespaces:
      - "production"
      - "staging"
  enforcementAction: deny

9.3 Kyverno 정책

# Kyverno: 이미지 서명 검증 + 레지스트리 제한
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signatures
spec:
  validationFailureAction: Enforce
  background: false
  rules:
    - name: verify-cosign-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "registry.company.com/*"
          attestors:
            - entries:
                - keys:
                    publicKeys: |
                      -----BEGIN PUBLIC KEY-----
                      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...
                      -----END PUBLIC KEY-----
    - name: restrict-registries
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Only approved registries are allowed"
        pattern:
          spec:
            containers:
              - image: "registry.company.com/* | gcr.io/company-project/*"

9.4 SPIFFE/SPIRE Workload Identity

SPIFFE/SPIRE 아키텍처:

  ┌──────────────────────────────┐
SPIRE Server  │                              │
- CA (인증서 발급)- Registration API- Node/Workload Attestation  └──────────┬───────────────────┘
    ┌────────┴────────┐
    ▼                 ▼
┌──────────┐   ┌──────────┐
SPIRE   │   │  SPIREAgent   │   │  Agent (Node 1) (Node 2)└────┬─────┘   └────┬─────┘
     │               │
  ┌──┴──┐         ┌──┴──┐
  │Pod A│         │Pod C  │Pod B│         │Pod D  └─────┘         └─────┘

Pod는 SVID (SPIFFE Verifiable Identity Document)를 받음:
  spiffe://company.com/ns/production/sa/payment-service
# SPIRE Registration 예시
apiVersion: spire.spiffe.io/v1alpha1
kind: ClusterSPIFFEID
metadata:
  name: payment-service-id
spec:
  spiffeIDTemplate: >-
    spiffe://company.com/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}
  podSelector:
    matchLabels:
      app: payment-service
  namespaceSelector:
    matchLabels:
      environment: production
  dnsNameTemplates:
    - "{{ .PodSpec.ServiceAccountName }}.{{ .PodMeta.Namespace }}.svc.cluster.local"
  ttl: "1h"
  jwtTTL: "5m"

10. Zero Trust 구현 로드맵 (5단계)

10.1 전체 로드맵

Phase 1: 가시성 확보 (1-3개월)
├── 자산 인벤토리 (사용자, 디바이스,, 데이터)
├── 네트워크 흐름 매핑
├── 접근 패턴 분석
├── 현재 보안 갭 평가
└── 성공 지표(KPI) 정의

Phase 2: Identity Foundation (3-6개월)
├── 중앙화된 IdP 구축/통합
├── SSO 구현 (SAML/OIDC)
├── MFA 전체 적용
├── Conditional Access 정책
└── 디바이스 등록 및 관리

Phase 3: 네트워크 세그멘테이션 (6-12개월)
├── 마이크로세그멘테이션 설계
├── East-West 트래픽 제어
├── DNS 보안
├── 암호화 통신 (mTLS)
└── ZTNA 파일럿 (VPN 대체 시작)

Phase 4: 워크로드 보안 (12-18개월)
├── 애플리케이션 수준 접근 제어
├── API 보안 (인증, 레이트 리밋)
├── 데이터 분류 및 DLP
├── CI/CD 파이프라인 보안
└── 런타임 보안 (CWPP)

Phase 5: 자동화 및 최적화 (18-24개월)
├── SOAR 통합 (자동 대응)
├── ML 기반 이상 탐지
├── 지속적 컴플라이언스 모니터링
├── 자동 정책 최적화
└── VPN 완전 폐기

10.2 각 단계별 핵심 활동

# Phase 1 상세 체크리스트
phase_1_visibility:
  asset_inventory:
    - action: "모든 사용자 계정 식별"
      tools: ["IdP export", "AD/LDAP query"]
      kpi: "식별률 >= 99%"
    - action: "모든 디바이스 식별"
      tools: ["MDM", "NAC", "네트워크 스캔"]
      kpi: "관리 디바이스 비율 >= 90%"
    - action: "모든 애플리케이션 매핑"
      tools: ["CASB discovery", "네트워크 분석"]
      kpi: "Shadow IT 발견율"
    - action: "데이터 흐름 매핑"
      tools: ["DLP 스캔", "네트워크 탭"]
      kpi: "민감 데이터 위치 파악률"

  network_mapping:
    - action: "East-West 트래픽 분석"
      tools: ["NetFlow", "Service Mesh 텔레메트리"]
    - action: "외부 통신 패턴 분석"
      tools: ["방화벽 로그", "프록시 로그"]
    - action: "의존성 그래프 생성"
      tools: ["서비스 디스커버리", "APM"]

  gap_assessment:
    - "현재 인증 방식 감사"
    - "네트워크 세그멘테이션 수준 평가"
    - "암호화 적용 범위 확인"
    - "로깅/모니터링 커버리지 평가"

11. 도구 비교: Zscaler vs Cloudflare vs Tailscale

11.1 상세 비교

항목ZscalerCloudflare Zero TrustTailscale
유형Enterprise SASEDeveloper-friendly SASEWireGuard mesh VPN
ZTNAZscaler Private AccessCloudflare AccessTailscale SSH/ACL
SWGZscaler Internet AccessCloudflare GatewayN/A
CASBO (인라인 + API)O (기본)N/A
글로벌 엣지150+ 데이터센터310+ 도시P2P (DERP relay)
에이전트Zscaler Client ConnectorWARP ClientTailscale Client
가격엔터프라이즈 (높음)무료 50명, 이후 사용자당무료 3명, 이후 사용자당
설정 복잡도높음중간낮음
K8s 통합OO (Tunnel)O (Operator)
적합 대상대기업중소기업-대기업스타트업-중소기업

11.2 Tailscale ACL 정책

{
  "acls": [
    {
      "action": "accept",
      "src": ["group:engineering"],
      "dst": [
        "tag:dev-server:22",
        "tag:staging-server:*",
        "tag:monitoring:3000,9090"
      ]
    },
    {
      "action": "accept",
      "src": ["group:sre"],
      "dst": [
        "tag:production-server:*",
        "tag:database:5432",
        "tag:monitoring:*"
      ]
    },
    {
      "action": "accept",
      "src": ["group:data-team"],
      "dst": [
        "tag:data-warehouse:5439",
        "tag:jupyter:8888"
      ]
    }
  ],
  "groups": {
    "group:engineering": ["user1@company.com", "user2@company.com"],
    "group:sre": ["sre1@company.com", "sre2@company.com"],
    "group:data-team": ["analyst@company.com"]
  },
  "tagOwners": {
    "tag:production-server": ["group:sre"],
    "tag:dev-server": ["group:engineering"],
    "tag:staging-server": ["group:engineering"],
    "tag:database": ["group:sre"],
    "tag:monitoring": ["group:sre"],
    "tag:data-warehouse": ["group:data-team"],
    "tag:jupyter": ["group:data-team"]
  },
  "ssh": [
    {
      "action": "accept",
      "src": ["group:sre"],
      "dst": ["tag:production-server"],
      "users": ["root", "ubuntu"]
    },
    {
      "action": "accept",
      "src": ["group:engineering"],
      "dst": ["tag:dev-server"],
      "users": ["autogroup:nonroot"]
    }
  ]
}

11.3 Twingate 설정 예시

# Twingate Terraform 설정
resource "twingate_remote_network" "production" {
  name = "Production Network"
}

resource "twingate_connector" "prod_connector" {
  remote_network_id = twingate_remote_network.production.id
  name              = "prod-connector-1"
}

resource "twingate_resource" "prod_api" {
  name              = "Production API"
  address           = "api.internal.company.com"
  remote_network_id = twingate_remote_network.production.id

  protocols {
    allow_icmp = false
    tcp {
      policy = "RESTRICTED"
      ports  = ["443", "8443"]
    }
    udp {
      policy = "DENY_ALL"
    }
  }

  access {
    group_ids = [twingate_group.engineering.id]
  }
}

resource "twingate_group" "engineering" {
  name = "Engineering Team"
}

12. 도전 과제와 함정

12.1 일반적인 실수

Zero Trust 구현 시 흔한 실수:

1. "VPN을 ZTNA로 교체하면 끝" 사고
Zero Trust는 제품이 아니라 전략
   → 네트워크, ID, 디바이스,, 데이터 모든 계층 필요

2. 한 번에 모든 것을 바꾸려는 시도
   → 점진적 전환이 필수
   → 가장 높은 위험부터 우선 적용

3. 사용자 경험 무시
   → 보안이 너무 불편하면 우회 시도 발생
SSO + 패스키로 보안과 편의성 양립

4. "내부 = 신뢰" 가정이 코드에 박혀 있음
IP 기반 접근 제어를 ID 기반으로 전환 필요
   → 레거시 앱 마이그레이션 계획 수립

5. 가시성 없이 정책 적용
   → 먼저 모니터링 모드로 트래픽 파악
   → 이후 점진적으로 차단 정책 적용

6. DevOps/CI/CD 파이프라인 간과
   → 서비스 계정, API 키도 Zero Trust 대상
Workload Identity 도입

12.2 성공 지표 (KPI)

zero_trust_kpis:
  identity:
    - metric: "MFA 적용률"
      target: "100%"
      current_industry_avg: "64%"
    - metric: "피싱 방지 MFA (FIDO2) 비율"
      target: ">= 80%"
    - metric: "SSO 적용 앱 비율"
      target: ">= 95%"
    - metric: "고아 계정 수"
      target: "0"

  device:
    - metric: "관리 디바이스 비율"
      target: ">= 95%"
    - metric: "패치 적용 SLA 준수율"
      target: ">= 90%"
    - metric: "디바이스 컴플라이언스 비율"
      target: ">= 90%"

  network:
    - metric: "마이크로세그멘테이션 적용률"
      target: ">= 80%"
    - metric: "mTLS 적용 서비스 비율"
      target: ">= 95%"
    - metric: "VPN 사용자 수"
      target: "0 (ZTNA로 완전 전환)"

  incident:
    - metric: "Lateral Movement 탐지 시간"
      target: "< 1시간"
    - metric: "침해 시 영향 범위"
      target: "단일 마이크로세그먼트 이하"
    - metric: "MTTD (Mean Time To Detect)"
      target: "< 24시간"

13. 퀴즈

Q1. Zero Trust의 3가지 핵심 원칙은 무엇인가요?

답: Zero Trust의 3가지 핵심 원칙은 다음과 같습니다:

  1. 명시적 검증 (Verify Explicitly): 모든 접근 요청에 대해 사용자, 디바이스, 위치, 행동 패턴 등을 항상 인증하고 인가합니다.

  2. 최소 권한 (Least Privilege Access): 필요한 최소한의 권한만 부여합니다. Just-In-Time(JIT)과 Just-Enough-Access(JEA)를 적용합니다.

  3. 침해 가정 (Assume Breach): 이미 내부가 침해되었다고 가정하고, 폭발 반경(Blast Radius)을 최소화하기 위해 마이크로세그멘테이션을 적용합니다.

Q2. ZTNA와 VPN의 핵심 차이점은 무엇인가요?

답: 핵심 차이점은 접근 범위와 인증 방식입니다.

  • VPN: 인증 후 네트워크 전체에 접근을 제공합니다. 한 번 연결되면 내부 리소스에 자유롭게 이동할 수 있어 Lateral Movement 위험이 있습니다.

  • ZTNA: 개별 애플리케이션 수준에서만 접근을 허용합니다(Dark Cloud 원칙). 지속적으로 사용자와 디바이스를 검증하며, 나머지 네트워크는 보이지 않습니다.

ZTNA는 성능(직접 접근), 보안(앱 격리), 확장성(클라우드 기반) 면에서 우수합니다.

Q3. Google BeyondCorp의 핵심 아이디어와 기존 보안과의 차이점은?

답: BeyondCorp의 핵심 아이디어는 "네트워크 위치가 신뢰를 결정하지 않는다"는 것입니다.

기존 모델에서는 사무실 네트워크에 연결되면 내부 리소스에 접근할 수 있었지만, BeyondCorp에서는 사무실이든 카페든 동일한 검증을 거칩니다.

핵심 구성 요소:

  • Identity-Aware Proxy: 모든 요청의 진입점으로 신원 확인
  • Device Inventory Service: 디바이스 상태를 실시간으로 관리
  • Access Control Engine: 사용자 + 디바이스 + 컨텍스트로 접근 결정
  • Trust Evaluation: 동적 Trust Score 기반 의사 결정

Google은 약 8년에 걸쳐 VPN을 완전히 제거하고 BeyondCorp로 전환했습니다.

Q4. 마이크로세그멘테이션이란 무엇이며, Kubernetes에서 어떻게 구현하나요?

답: 마이크로세그멘테이션은 네트워크를 워크로드 수준의 세밀한 단위로 분리하여, 각 워크로드 간 최소 필요 통신만 허용하는 기술입니다.

Kubernetes에서의 구현 방법:

  1. NetworkPolicy: 기본 L3/L4 수준의 Pod 간 트래픽 제어. Default Deny 정책을 먼저 적용하고, 필요한 통신만 명시적으로 허용합니다.
  2. Service Mesh (Istio): L7 수준의 제어. PeerAuthentication으로 mTLS를 강제하고, AuthorizationPolicy로 서비스 간 접근을 세밀하게 제어합니다.
  3. OPA/Gatekeeper 또는 Kyverno: 정책을 코드로 관리하여 보안 표준을 강제합니다.
Q5. SASE의 핵심 구성 요소와 각각의 역할은?

답: SASE(Secure Access Service Edge)는 네트워크와 보안을 클라우드에서 통합합니다.

핵심 구성 요소:

  1. SD-WAN: WAN 최적화, 트래픽 제어, QoS 관리. 여러 링크를 지능적으로 활용합니다.
  2. ZTNA: 사용자/디바이스 인증 후 앱 수준 접근 제어. VPN 대체합니다.
  3. CASB: Shadow IT 발견, SaaS 데이터 보호, 이상 행동 탐지, 컴플라이언스 모니터링을 수행합니다.
  4. SWG: URL 필터링, 멀웨어 차단, SSL/TLS 검사, 콘텐츠 필터링을 수행합니다.
  5. FWaaS: L3-L7 방화벽, IPS/IDS, DNS 보안을 클라우드에서 제공합니다.
  6. DLP: 민감 데이터 유출 방지를 수행합니다.

이 모든 구성 요소가 통합 정책과 콘솔로 관리됩니다.

14. 참고 자료

  1. NIST SP 800-207: Zero Trust Architecture
  2. Google BeyondCorp Papers
  3. CISA Zero Trust Maturity Model
  4. Forrester Zero Trust eXtended Framework
  5. Cloudflare Zero Trust Documentation
  6. Zscaler Zero Trust Exchange
  7. Tailscale Documentation
  8. Istio Security Documentation
  9. SPIFFE/SPIRE Documentation
  10. Kubernetes Network Policies
  11. OPA Gatekeeper
  12. Kyverno Documentation
  13. Microsoft Zero Trust Deployment Guide
  14. Gartner SASE Framework