9.1 KiB
9.1 KiB
id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
| id | title | category | status | source_trust_level | verification_status | created_at | updated_at | tags | tech_stack | applied_in | aliases | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| security-zero-trust | Zero Trust — Never trust / Always verify | Coding | draft | B | conceptual | 2026-05-09 | 2026-05-09 |
|
|
|
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 (가장 빠른 시작)
# 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)
# 모든 device 에 install
tailscale up --auth-key=...
# 자동 mesh — 모든 device 끼리 직접 connect
# WireGuard 기반
# 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
// 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)
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)
Identity propagation
// 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)
# 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)
// 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.
SSO + SAML / OIDC
// 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
// 매 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.