zero-trust
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseZero Trust Architecture
零信任架构
Implement "never trust, always verify" security model.
实施「永不信任,始终验证」的安全模型。
When to Use This Skill
适用场景
Use this skill when:
- Replacing traditional perimeter-based VPN access models
- Implementing BeyondCorp-style access to internal applications
- Securing multi-cloud or hybrid-cloud environments
- Enforcing identity-based access for every service interaction
- Meeting compliance requirements for continuous verification and least privilege
- Adopting micro-segmentation for Kubernetes or cloud workloads
在以下场景中使用本技能:
- 替换传统基于边界的VPN访问模型
- 为内部应用实施BeyondCorp风格的访问控制
- 保护多云或混合云环境
- 为每个服务交互强制实施基于身份的访问
- 满足持续验证和最小权限的合规要求
- 为Kubernetes或云工作负载采用微分段
Prerequisites
前置条件
- Identity provider (IdP) supporting OIDC/SAML (Okta, Azure AD, Google Workspace)
- Service mesh or proxy infrastructure (Istio, Envoy, Cloudflare Access)
- Device management/MDM solution for device posture checks
- Kubernetes cluster for workload-level examples
- Understanding of mTLS, RBAC, and network policies
- 支持OIDC/SAML的身份提供商(IdP)(如Okta、Azure AD、Google Workspace)
- 服务网格或代理基础设施(如Istio、Envoy、Cloudflare Access)
- 用于设备状态检查的设备管理/MDM解决方案
- 用于工作负载级示例的Kubernetes集群
- 了解mTLS、RBAC和网络策略
Core Principles
核心原则
yaml
zero_trust_principles:
verify_explicitly:
description: "Authenticate and authorize every access request"
controls:
- Strong multi-factor authentication
- Identity-aware proxy for all applications
- Service-to-service mTLS
- API token validation on every request
least_privilege:
description: "Grant minimum access needed for the task"
controls:
- Just-in-time (JIT) access provisioning
- Time-bounded access grants
- Role-based access with fine-grained permissions
- Regular access reviews and certification
assume_breach:
description: "Design systems expecting compromise has occurred"
controls:
- Micro-segmentation between all services
- End-to-end encryption (data in transit and at rest)
- Continuous monitoring and anomaly detection
- Blast radius containmentyaml
zero_trust_principles:
verify_explicitly:
description: "Authenticate and authorize every access request"
controls:
- Strong multi-factor authentication
- Identity-aware proxy for all applications
- Service-to-service mTLS
- API token validation on every request
least_privilege:
description: "Grant minimum access needed for the task"
controls:
- Just-in-time (JIT) access provisioning
- Time-bounded access grants
- Role-based access with fine-grained permissions
- Regular access reviews and certification
assume_breach:
description: "Design systems expecting compromise has occurred"
controls:
- Micro-segmentation between all services
- End-to-end encryption (data in transit and at rest)
- Continuous monitoring and anomaly detection
- Blast radius containmentBeyondCorp Implementation
BeyondCorp 实施方案
Cloudflare Access Configuration
Cloudflare Access 配置
bash
undefinedbash
undefinedCreate an Access application for an internal service
Create an Access application for an internal service
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/access/apps"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Internal Dashboard", "domain": "dashboard.internal.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["google-workspace-idp-id"] }'
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Internal Dashboard", "domain": "dashboard.internal.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["google-workspace-idp-id"] }'
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/access/apps"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Internal Dashboard", "domain": "dashboard.internal.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["google-workspace-idp-id"] }'
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Internal Dashboard", "domain": "dashboard.internal.example.com", "type": "self_hosted", "session_duration": "12h", "auto_redirect_to_identity": true, "allowed_idps": ["google-workspace-idp-id"] }'
Create an Access policy
Create an Access policy
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/access/apps/${APP_ID}/policies"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Engineering team access", "decision": "allow", "include": [ { "group": { "id": "engineering-group-id" } } ], "require": [ { "login_method": { "id": "google-workspace-idp-id" } } ], "exclude": [ { "geo": { "country_code": "KP" } } ] }'
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Engineering team access", "decision": "allow", "include": [ { "group": { "id": "engineering-group-id" } } ], "require": [ { "login_method": { "id": "google-workspace-idp-id" } } ], "exclude": [ { "geo": { "country_code": "KP" } } ] }'
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/access/apps/${APP_ID}/policies"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Engineering team access", "decision": "allow", "include": [ { "group": { "id": "engineering-group-id" } } ], "require": [ { "login_method": { "id": "google-workspace-idp-id" } } ], "exclude": [ { "geo": { "country_code": "KP" } } ] }'
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Engineering team access", "decision": "allow", "include": [ { "group": { "id": "engineering-group-id" } } ], "require": [ { "login_method": { "id": "google-workspace-idp-id" } } ], "exclude": [ { "geo": { "country_code": "KP" } } ] }'
Create a device posture rule
Create a device posture rule
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/devices/posture"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Require disk encryption", "type": "disk_encryption", "match": { "platform": "linux" }, "schedule": "1h", "input": { "requireAll": true } }'
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Require disk encryption", "type": "disk_encryption", "match": { "platform": "linux" }, "schedule": "1h", "input": { "requireAll": true } }'
undefinedcurl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/devices/posture"
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Require disk encryption", "type": "disk_encryption", "match": { "platform": "linux" }, "schedule": "1h", "input": { "requireAll": true } }'
-H "Authorization: Bearer ${CF_TOKEN}"
-H "Content-Type: application/json"
-d '{ "name": "Require disk encryption", "type": "disk_encryption", "match": { "platform": "linux" }, "schedule": "1h", "input": { "requireAll": true } }'
undefinedCloudflare Access Terraform
Cloudflare Access Terraform
hcl
resource "cloudflare_access_application" "dashboard" {
account_id = var.cloudflare_account_id
name = "Internal Dashboard"
domain = "dashboard.internal.example.com"
type = "self_hosted"
session_duration = "12h"
auto_redirect_to_identity = true
}
resource "cloudflare_access_policy" "engineering" {
account_id = var.cloudflare_account_id
application_id = cloudflare_access_application.dashboard.id
name = "Engineering team"
precedence = 1
decision = "allow"
include {
group = [cloudflare_access_group.engineering.id]
}
require {
login_method = [var.google_idp_id]
}
}
resource "cloudflare_access_group" "engineering" {
account_id = var.cloudflare_account_id
name = "Engineering"
include {
email_domain = ["example.com"]
}
require {
group = ["engineering@example.com"]
}
}hcl
resource "cloudflare_access_application" "dashboard" {
account_id = var.cloudflare_account_id
name = "Internal Dashboard"
domain = "dashboard.internal.example.com"
type = "self_hosted"
session_duration = "12h"
auto_redirect_to_identity = true
}
resource "cloudflare_access_policy" "engineering" {
account_id = var.cloudflare_account_id
application_id = cloudflare_access_application.dashboard.id
name = "Engineering team"
precedence = 1
decision = "allow"
include {
group = [cloudflare_access_group.engineering.id]
}
require {
login_method = [var.google_idp_id]
}
}
resource "cloudflare_access_group" "engineering" {
account_id = var.cloudflare_account_id
name = "Engineering"
include {
email_domain = ["example.com"]
}
require {
group = ["engineering@example.com"]
}
}Identity-Aware Proxy with OAuth2 Proxy
基于身份的代理(OAuth2 Proxy)
yaml
undefinedyaml
undefinedoauth2-proxy deployment for protecting internal services
oauth2-proxy deployment for protecting internal services
apiVersion: apps/v1 kind: Deployment metadata: name: oauth2-proxy namespace: auth spec: replicas: 2 selector: matchLabels: app: oauth2-proxy template: metadata: labels: app: oauth2-proxy spec: containers: - name: oauth2-proxy image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0 args: - --provider=oidc - --oidc-issuer-url=https://accounts.google.com - --client-id=$(CLIENT_ID) - --client-secret=$(CLIENT_SECRET) - --email-domain=example.com - --upstream=http://internal-service.default.svc:8080 - --http-address=0.0.0.0:4180 - --cookie-secret=$(COOKIE_SECRET) - --cookie-secure=true - --cookie-httponly=true - --cookie-samesite=lax - --set-xauthrequest=true - --pass-access-token=true - --skip-provider-button=true - --session-store-type=redis - --redis-connection-url=redis://redis.auth.svc:6379 env: - name: CLIENT_ID valueFrom: secretKeyRef: name: oauth2-proxy key: client-id - name: CLIENT_SECRET valueFrom: secretKeyRef: name: oauth2-proxy key: client-secret - name: COOKIE_SECRET valueFrom: secretKeyRef: name: oauth2-proxy key: cookie-secret ports: - containerPort: 4180
apiVersion: apps/v1 kind: Deployment metadata: name: oauth2-proxy namespace: auth spec: replicas: 2 selector: matchLabels: app: oauth2-proxy template: metadata: labels: app: oauth2-proxy spec: containers: - name: oauth2-proxy image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0 args: - --provider=oidc - --oidc-issuer-url=https://accounts.google.com - --client-id=$(CLIENT_ID) - --client-secret=$(CLIENT_SECRET) - --email-domain=example.com - --upstream=http://internal-service.default.svc:8080 - --http-address=0.0.0.0:4180 - --cookie-secret=$(COOKIE_SECRET) - --cookie-secure=true - --cookie-httponly=true - --cookie-samesite=lax - --set-xauthrequest=true - --pass-access-token=true - --skip-provider-button=true - --session-store-type=redis - --redis-connection-url=redis://redis.auth.svc:6379 env: - name: CLIENT_ID valueFrom: secretKeyRef: name: oauth2-proxy key: client-id - name: CLIENT_SECRET valueFrom: secretKeyRef: name: oauth2-proxy key: client-secret - name: COOKIE_SECRET valueFrom: secretKeyRef: name: oauth2-proxy key: cookie-secret ports: - containerPort: 4180
Ingress routing through oauth2-proxy
Ingress routing through oauth2-proxy
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: internal-service
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.example.com/oauth2/start?rd=$scheme://$host$request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email"
spec:
rules:
- host: dashboard.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: internal-service
port:
number: 8080
undefinedapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: internal-service
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://auth.example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://auth.example.com/oauth2/start?rd=$scheme://$host$request_uri"
nginx.ingress.kubernetes.io/auth-response-headers: "X-Auth-Request-User,X-Auth-Request-Email"
spec:
rules:
- host: dashboard.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: internal-service
port:
number: 8080
undefinedService Mesh mTLS (Istio)
服务网格mTLS(Istio)
yaml
undefinedyaml
undefinedEnforce strict mTLS across the mesh
Enforce strict mTLS across the mesh
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT
Authorization policy: frontend can call backend
Authorization policy: frontend can call backend
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: backend-access namespace: default spec: selector: matchLabels: app: backend action: ALLOW rules: - from: - source: principals: ["cluster.local/ns/default/sa/frontend"] to: - operation: methods: ["GET", "POST"] paths: ["/api/*"]
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: backend-access namespace: default spec: selector: matchLabels: app: backend action: ALLOW rules: - from: - source: principals: ["cluster.local/ns/default/sa/frontend"] to: - operation: methods: ["GET", "POST"] paths: ["/api/*"]
Default deny all in namespace
Default deny all in namespace
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: production
spec: {}
undefinedapiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: production
spec: {}
undefinedMicro-Segmentation with Kubernetes Network Policies
Kubernetes网络策略实现微分段
yaml
undefinedyaml
undefinedDefault deny all traffic in namespace
Default deny all traffic in namespace
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all namespace: production spec: podSelector: {} policyTypes: - Ingress - Egress
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all namespace: production spec: podSelector: {} policyTypes: - Ingress - Egress
Allow DNS resolution for all pods
Allow DNS resolution for all pods
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns namespace: production spec: podSelector: {} policyTypes: - Egress egress: - to: [] ports: - protocol: UDP port: 53 - protocol: TCP port: 53
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns namespace: production spec: podSelector: {} policyTypes: - Egress egress: - to: [] ports: - protocol: UDP port: 53 - protocol: TCP port: 53
Frontend: allow ingress from ingress controller, egress to backend
Frontend: allow ingress from ingress controller, egress to backend
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: frontend-policy namespace: production spec: podSelector: matchLabels: app: frontend policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: ingress-nginx ports: - protocol: TCP port: 8080 egress: - to: - podSelector: matchLabels: app: backend ports: - protocol: TCP port: 8080
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: frontend-policy namespace: production spec: podSelector: matchLabels: app: frontend policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: ingress-nginx ports: - protocol: TCP port: 8080 egress: - to: - podSelector: matchLabels: app: backend ports: - protocol: TCP port: 8080
Database: allow from backend only, no egress
Database: allow from backend only, no egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
undefinedapiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database-policy
namespace: production
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 5432
undefinedOPA Policy for Access Decisions
用于访问决策的OPA策略
rego
undefinedrego
undefinedpolicy.rego - Zero trust access decision
policy.rego - Zero trust access decision
package zerotrust.access
import rego.v1
default allow := false
allow if {
identity_verified
device_compliant
authorized_for_resource
risk_acceptable
}
identity_verified if {
input.identity.authenticated == true
input.identity.mfa_verified == true
time.now_ns() < input.identity.session_expires_ns
}
device_compliant if {
input.device.encryption_enabled == true
input.device.os_updated == true
input.device.firewall_enabled == true
input.device.certificate_valid == true
}
authorized_for_resource if {
some role in input.identity.roles
some permission in data.role_permissions[role]
permission == input.resource.required_permission
}
risk_acceptable if {
input.risk.score < 70
not input.risk.active_threat
}
step_up_required if {
input.risk.score >= 50
input.risk.score < 70
not input.identity.recent_mfa
}
undefinedpackage zerotrust.access
import rego.v1
default allow := false
allow if {
identity_verified
device_compliant
authorized_for_resource
risk_acceptable
}
identity_verified if {
input.identity.authenticated == true
input.identity.mfa_verified == true
time.now_ns() < input.identity.session_expires_ns
}
device_compliant if {
input.device.encryption_enabled == true
input.device.os_updated == true
input.device.firewall_enabled == true
input.device.certificate_valid == true
}
authorized_for_resource if {
some role in input.identity.roles
some permission in data.role_permissions[role]
permission == input.resource.required_permission
}
risk_acceptable if {
input.risk.score < 70
not input.risk.active_threat
}
step_up_required if {
input.risk.score >= 50
input.risk.score < 70
not input.identity.recent_mfa
}
undefinedImplementation Steps
实施步骤
- Inventory assets and data flows - Map every application, service, and data store
- Deploy identity provider - Centralize authentication with SSO and MFA
- Implement identity-aware proxy - Route all access through authentication layer
- Enable mTLS for service mesh - Encrypt and authenticate all service communication
- Apply network policies - Default deny with explicit allow rules
- Add device posture checks - Verify device compliance before granting access
- Deploy continuous monitoring - Log and analyze all access decisions
- Iterate and refine - Review policies based on monitoring data
- 资产和数据流盘点 - 梳理所有应用、服务和数据存储
- 部署身份提供商 - 通过SSO和MFA集中认证
- 实施基于身份的代理 - 将所有访问路由到认证层
- 为服务网格启用mTLS - 加密并认证所有服务通信
- 应用网络策略 - 默认拒绝,仅显式允许必要流量
- 添加设备状态检查 - 在授予访问权限前验证设备合规性
- 部署持续监控 - 记录并分析所有访问决策
- 迭代优化 - 根据监控数据调整策略
Troubleshooting
故障排查
| Problem | Cause | Solution |
|---|---|---|
| Users cannot access internal apps | Identity provider misconfigured | Verify OIDC/SAML settings; check redirect URIs |
| mTLS connections failing | Certificate expired or wrong CA | Check cert expiry with |
| Network policy blocking legitimate traffic | Missing egress or ingress rule | Use |
| Device posture check fails | MDM agent not reporting | Verify device agent is running; check compliance dashboard |
| OAuth2 proxy returns 403 | User email domain not in allow-list | Add domain to |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 用户无法访问内部应用 | 身份提供商配置错误 | 验证OIDC/SAML设置;检查重定向URI |
| mTLS连接失败 | 证书过期或CA错误 | 使用 |
| 网络策略阻止合法流量 | 缺少出口或入口规则 | 使用 |
| 设备状态检查失败 | MDM代理未上报数据 | 验证设备代理是否运行;检查合规性仪表板 |
| OAuth2 proxy返回403 | 用户邮箱域名不在允许列表 | 将域名添加到 |
Related Skills
相关技能
- service-mesh - mTLS implementation
- kubernetes-hardening - K8s security
- vpn-setup - Traditional VPN (contrast with zero trust)
- service-mesh - mTLS实现
- kubernetes-hardening - K8s安全加固
- vpn-setup - 传统VPN(与零信任对比)