438 lines
9.1 KiB
Markdown
438 lines
9.1 KiB
Markdown
---
|
|
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]]
|