---
id: security-zero-trust
title: Zero Trust — Never trust / Always verify
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [security, zero-trust, vibe-coding]
tech_stack: { language: "Various", applicable_to: ["Security"] }
applied_in: []
aliases: [Zero Trust, BeyondCorp, perimeterless, SSO, MFA, identity-based]
---

# Zero Trust

> "Trust no one, verify everything". **Network perimeter X — identity + context every request**. Google BeyondCorp, Cloudflare Access, Tailscale.

## 📖 핵심 개념
- 옛: Network perimeter (VPN, internal = trusted).
- Zero trust: 매 request 가 identity + context.
- Continuous verification.
- Least privilege.

## 💻 코드 패턴

### 옛 vs new
```
옛 (perimeter):
- VPN connect
- Internal network = trusted
- 모든 service 가 trust

Zero trust:
- 매 request 가 인증 + 권한
- "Internal" / "external" 없음
- Public internet 가도 안전
```

### Components
```
1. Identity provider (Google, Okta, Auth0, Azure AD)
2. Device trust (managed device check)
3. Access proxy (Cloudflare Access, Zscaler)
4. Service authentication (mTLS, signed)
5. Policy engine (allowlist + context)
6. Continuous monitoring
```

### Cloudflare Access (가장 빠른 시작)
```yaml
# Application
- Domain: internal.example.com
- Identity: Google + Okta
- Policy:
  - Email domain @company.com
  - 2FA required
  - Device: managed
  - Country: US, KR, JP
```

```
사용자:
1. Visit internal.example.com
2. Cloudflare 가 Google login
3. Policy check (email, 2FA, device)
4. 통과 → tunnel to actual service
```

→ VPN 없이 internal app access. 1시간 setup.

### Tailscale (mesh VPN, modern)
```bash
# 모든 device 에 install
tailscale up --auth-key=...

# 자동 mesh — 모든 device 끼리 직접 connect
# WireGuard 기반
```

```yaml
# ACL
{
  "groups": {
    "group:admins": ["alice@", "bob@"],
    "group:dev": ["dev-team@"],
  },
  "acls": [
    { "action": "accept", "src": ["group:admins"], "dst": ["*:*"] },
    { "action": "accept", "src": ["group:dev"], "dst": ["dev-server:22"] },
  ],
}
```

→ Private network without VPN concentrator.

### mTLS (service-to-service)
```
[[Security_mTLS_Patterns]]:

Service A → Service B:
- A 의 cert + B 가 검증 (양방)
- 없으면 connection refuse

→ Zero trust within cluster.
```

### Identity 매 request
```ts
// Middleware
app.use(async (req, res, next) => {
  const token = req.headers.authorization?.replace('Bearer ', '');
  if (!token) return res.status(401).end();
  
  const user = await verifyJwt(token);
  if (!user) return res.status(401).end();
  
  req.user = user;
  next();
});

// 매 endpoint 가 user 검증.
// "Internal network 이라 안전" 가정 X.
```

### Context-aware (BeyondCorp)
```ts
function checkAccess(user: User, request: Request, resource: Resource): boolean {
  // 1. Identity
  if (!user.authenticated) return false;
  
  // 2. Device trust
  const device = getDevice(request);
  if (!device.managed || !device.encrypted) return false;
  
  // 3. Network (location, but not exclusive)
  if (request.ip === 'tor' || isHighRiskCountry(request.geoIp)) return false;
  
  // 4. Behavior (anomaly)
  if (anomalyScore(user, request) > 0.8) return false;
  
  // 5. Resource (least privilege)
  if (!user.permissions.includes(resource.requiredPermission)) return false;
  
  return true;
}
```

→ Multi-factor decision.

### Service mesh (mTLS within K8s)
```
Istio / Linkerd:
- 모든 service 간 mTLS 자동
- AuthorizationPolicy 가 access
- 사용자 identity propagate (header)
```

→ [[DevOps_Service_Mesh_Deep]].

### Identity propagation
```ts
// User 가 frontend → API → backend service
// 매 hop 에 identity propagate

// Frontend → API
const r = await fetch('/api/orders', {
  headers: { 'Authorization': `Bearer ${userToken}` },
});

// API → Backend service
async function getOrders(req) {
  const userId = req.user.id;
  
  // mTLS auth + user header
  return fetch('http://orders-service/list', {
    headers: {
      'X-User-ID': userId,
      'X-Trace-ID': req.headers['x-trace-id'],
    },
  });
}

// Backend service 가 user-scoped query
async function listOrders(userId: string) {
  return db.orders.findMany({ where: { userId } });
}
```

### Workload identity
```
Service-to-service auth:
- mTLS cert
- SPIFFE / SPIRE
- IAM role (cloud)
- AWS IRSA (K8s + IAM)
```

```yaml
# K8s ServiceAccount + IAM
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::123:role/my-app
```

→ Pod 가 IAM role 자동.

### Secret access (need-to-know)
```ts
// Vault / Doppler / 1Password
const secret = await vault.read(`apps/${env}/db-password`);

// Token-based access:
// - Service A token: read apps/prod/db-password
// - Service B token: read apps/prod/api-key
// - 다른 거 안 됨
```

→ Least privilege.

### Continuous monitoring
```
- Anomaly detection (사용 패턴)
- New device alert
- Unusual location
- Failed auth attempts
- Data exfiltration patterns

Tools: Splunk, Datadog SIEM, Elastic SIEM, Panther.
```

### Just-in-time access
```
사용자 가 sensitive resource 필요:
1. Request access (reason 명시)
2. Approval (manager / on-call)
3. Time-limited grant (1 hour)
4. Auto revoke
5. Audit log

Tools: AWS SSM Session Manager, ConductorOne, Sym, Opal.
```

→ Standing permission 안 — temporary 만.

### Endpoint security
```
Device trust:
- MDM (Mobile Device Management)
- Disk encryption
- OS up-to-date
- Antivirus active

Tools: Jamf, Kandji, Intune.
```

### Phishing-resistant MFA
```
Phishable:
- SMS (SIM swap)
- TOTP (man-in-the-middle)

Phishing-resistant:
- WebAuthn / Passkey
- FIDO2 hardware key
- Smart card

→ Modern MFA = Passkey.
```

→ [[Security_2FA_TOTP_WebAuthn]].

### SSO + SAML / OIDC
```ts
// Server
import { Strategy as SamlStrategy } from 'passport-saml';

passport.use(new SamlStrategy({
  entryPoint: 'https://idp.example.com/sso',
  issuer: 'my-app',
  cert: '...',
}, (profile, done) => {
  done(null, { id: profile.nameID, email: profile.email });
}));
```

→ 회사 IdP (Okta, Azure AD) 가 모든 app 의 auth.

### SCIM (자동 provision)
```
사용자 hire / fire:
1. HR system 변경
2. SCIM 가 모든 app 에 propagate
3. Account auto create / disable

→ 손으로 매 app deactivate 안 함.
```

### Migration to zero trust
```
Phase 1 (Quick wins):
- SSO 모든 app
- MFA 강제
- VPN 제거 (Cloudflare Access)

Phase 2:
- Service mesh (mTLS)
- Workload identity
- Secret manager

Phase 3:
- Just-in-time access
- Continuous monitoring
- Endpoint trust
```

### Cost
```
Cloudflare Access: $3/user/month
Tailscale: $5/user/month
Okta: $2-15/user/month
Auth0: $23/month + per user
Vault: self-host or HashiCorp Cloud
```

### Common 오해
```
"Zero trust = always more secure"
실제: 잘 implement 시 더 안전. 잘못 implement = 비슷.

"Zero trust = no VPN"
실제: VPN 가 component 가능 (Tailscale 등).

"Zero trust = expensive"
실제: SaaS 가 cheap. 큰 enterprise 는 다양 layer.
```

### NIST 800-207 (US standard)
```
Tenets:
1. All data sources / services = resources.
2. All communication = secured (location 무관).
3. Per-session access (no persistent).
4. Dynamic policy.
5. Asset integrity monitor.
6. All authentication / authorization = dynamic, strict.
7. As much information collected as possible.
```

→ Government / compliance-heavy.

### Network 분리는 여전 가치
```
Zero trust = identity-based.
Defense in depth = network 도.

Best:
- Zero trust (identity)
- + Network 분리 (defense)
- + Least privilege
- + 모든 layer 검증
```

### Logging / audit
```ts
// 매 access decision log
log.info('access', {
  userId,
  resource,
  action,
  decision: 'allowed',
  reason: 'admin role',
  context: { ip, device, country, time },
});
```

→ Forensic + compliance.

### Identity provider (IdP) 선택
```
Workforce:
- Okta: best ecosystem
- Azure AD: Microsoft 365 stack
- Google Workspace: Google stack
- Auth0 / Keycloak: developer-friendly

Customer:
- Auth0
- Clerk
- Cognito
- Supabase Auth

→ B2B (workforce) vs B2C (customer) 다름.
```

### Compliance 와 link
```
SOC 2: identity, access control 강제
HIPAA: PHI access control
PCI DSS: cardholder data
GDPR: data subject rights

→ Zero trust 가 자연 align.
```

## 🤔 의사결정 기준
| 상황 | 추천 |
|---|---|
| 작은 startup | Cloudflare Access (빠른) |
| K8s | Service mesh + Tailscale |
| Enterprise | Okta / Azure AD + Vault + ZTNA |
| Internal app 만 | Cloudflare Access / Pomerium |
| 모든 접근 | NIST 800-207 framework |

## ❌ 안티패턴
- **VPN 만 + internal trust**: 옛 — 침투 시 모두 위험.
- **MFA SMS only**: SIM swap.
- **Standing admin permission**: just-in-time 권장.
- **Audit log 없음**: forensic 어려움.
- **Workload identity 무**: hardcoded secret.
- **Endpoint 무 trust**: 어떤 device 도 access.
- **모든 거 한 번에 migrate**: 점진.

## 🤖 LLM 활용 힌트
- Cloudflare Access / Tailscale = quick zero trust.
- mTLS + workload identity = service.
- Phishing-resistant MFA (Passkey).
- Just-in-time + audit log.

## 🔗 관련 문서
- [[Security_OAuth_Flows]]
- [[Security_mTLS_Patterns]]
- [[Security_2FA_TOTP_WebAuthn]]
