2026-01-27 17:35:45 -05:00
---
name : zero-trust
description : Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.
license : MIT
metadata :
author : devops-skills
version : "1.0"
---
# Zero Trust Architecture
Implement "never trust, always verify" security model.
2026-03-24 18:02:50 -04:00
## 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
## 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
2026-01-27 17:35:45 -05:00
## Core Principles
```yaml
zero_trust_principles :
2026-03-24 18:02:50 -04:00
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 containment
2026-01-27 17:35:45 -05:00
```
2026-03-24 18:02:50 -04:00
## BeyondCorp Implementation
### Cloudflare Access Configuration
```bash
# 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"]
}'
# 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" } }
]
}'
# 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 }
}'
```
### 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" ]
}
}
```
## Identity-Aware Proxy with OAuth2 Proxy
2026-01-27 17:35:45 -05:00
```yaml
2026-03-24 18:02:50 -04:00
# 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
---
# 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
```
## Service Mesh mTLS (Istio)
```yaml
# Enforce strict mTLS across the mesh
2026-01-27 17:35:45 -05:00
apiVersion : security.istio.io/v1beta1
kind : PeerAuthentication
metadata :
name : default
2026-03-24 18:02:50 -04:00
namespace : istio-system
2026-01-27 17:35:45 -05:00
spec :
mtls :
mode : STRICT
---
2026-03-24 18:02:50 -04:00
# Authorization policy: frontend can call backend
2026-01-27 17:35:45 -05:00
apiVersion : security.istio.io/v1beta1
kind : AuthorizationPolicy
metadata :
2026-03-24 18:02:50 -04:00
name : backend-access
namespace : default
2026-01-27 17:35:45 -05:00
spec :
selector :
matchLabels :
app : backend
2026-03-24 18:02:50 -04:00
action : ALLOW
2026-01-27 17:35:45 -05:00
rules :
2026-03-24 18:02:50 -04:00
- from :
- source :
principals : [ "cluster.local/ns/default/sa/frontend" ]
to :
- operation :
methods : [ "GET" , "POST" ]
paths : [ "/api/*" ]
---
# Default deny all in namespace
apiVersion : security.istio.io/v1beta1
kind : AuthorizationPolicy
metadata :
name : deny-all
namespace : production
spec : {}
2026-01-27 17:35:45 -05:00
```
2026-03-24 18:02:50 -04:00
## Micro-Segmentation with Kubernetes Network Policies
2026-01-27 17:35:45 -05:00
```yaml
2026-03-24 18:02:50 -04:00
# Default deny all traffic in namespace
2026-01-27 17:35:45 -05:00
apiVersion : networking.k8s.io/v1
kind : NetworkPolicy
metadata :
2026-03-24 18:02:50 -04:00
name : default-deny-all
namespace : production
2026-01-27 17:35:45 -05:00
spec :
podSelector : {}
policyTypes :
2026-03-24 18:02:50 -04:00
- Ingress
- Egress
---
# 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
---
# 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
---
# 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
```
## OPA Policy for Access Decisions
```rego
# 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
}
2026-01-27 17:35:45 -05:00
```
## Implementation Steps
2026-03-24 18:02:50 -04:00
1. **Inventory assets and data flows** - Map every application, service, and data store
2. **Deploy identity provider** - Centralize authentication with SSO and MFA
3. **Implement identity-aware proxy** - Route all access through authentication layer
4. **Enable mTLS for service mesh** - Encrypt and authenticate all service communication
5. **Apply network policies** - Default deny with explicit allow rules
6. **Add device posture checks** - Verify device compliance before granting access
7. **Deploy continuous monitoring** - Log and analyze all access decisions
8. **Iterate and refine** - Review policies based on monitoring data
2026-01-27 17:35:45 -05:00
2026-03-24 18:02:50 -04:00
## Troubleshooting
2026-01-27 17:35:45 -05:00
2026-03-24 18:02:50 -04:00
| 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 `istioctl proxy-config secret` ; verify CA chain |
| Network policy blocking legitimate traffic | Missing egress or ingress rule | Use `kubectl describe networkpolicy` ; verify pod labels match selectors |
| 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 `--email-domain` flag or update group membership |
2026-01-27 17:35:45 -05:00
## Related Skills
- [service-mesh ](../../../infrastructure/networking/service-mesh/ ) - mTLS implementation
- [kubernetes-hardening ](../../hardening/kubernetes-hardening/ ) - K8s security
2026-03-24 18:02:50 -04:00
- [vpn-setup ](../vpn-setup/ ) - Traditional VPN (contrast with zero trust)