zero-trust-patterns
Zero-Trust security patterns — mTLS between microservices (Istio/SPIFFE), SPIRE workload identity, OPA/Envoy authorization, NetworkPolicy default-deny-all, short-lived credentials, service mesh security, and Kubernetes RBAC hardening.
Best use case
zero-trust-patterns is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Zero-Trust security patterns — mTLS between microservices (Istio/SPIFFE), SPIRE workload identity, OPA/Envoy authorization, NetworkPolicy default-deny-all, short-lived credentials, service mesh security, and Kubernetes RBAC hardening.
Teams using zero-trust-patterns should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/zero-trust-patterns/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How zero-trust-patterns Compares
| Feature / Agent | zero-trust-patterns | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Zero-Trust security patterns — mTLS between microservices (Istio/SPIFFE), SPIRE workload identity, OPA/Envoy authorization, NetworkPolicy default-deny-all, short-lived credentials, service mesh security, and Kubernetes RBAC hardening.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Zero-Trust Patterns
## When to Activate
- Designing service-to-service communication in Kubernetes or cloud environments
- Implementing mTLS between microservices
- Setting up SPIFFE/SPIRE for workload identity
- Configuring Istio or Linkerd service mesh
- Writing Kubernetes NetworkPolicies
- Reviewing east-west traffic security
- Building BeyondCorp-style access controls
- Auditing existing cluster network policies for trust boundary gaps
---
## Core Principles (NIST SP 800-207)
Zero-Trust Architecture operates on four pillars:
1. **Never trust, always verify** — even traffic from within the private network is untrusted. Every connection requires authentication and authorization.
2. **Explicit verification** — identity + device + context checked at every request (not just at the perimeter).
3. **Least Privilege Access** — minimal rights, just enough to complete the task, scoped to the operation.
4. **Assume Breach** — design to minimize lateral movement when an attacker is already inside the network.
---
## Service Identity with SPIFFE/SPIRE
**SPIFFE** (Secure Production Identity Framework for Everyone) is the standard for cryptographic service identities.
### SVID Format
```
spiffe://trust-domain/path/to/workload
# Example:
spiffe://prod.example.com/ns/payments/sa/checkout-service
```
### SPIRE Server + Agent Setup
```yaml
# spire-server.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: spire-server
namespace: spire
spec:
replicas: 1
selector:
matchLabels:
app: spire-server
template:
spec:
containers:
- name: spire-server
image: ghcr.io/spiffe/spire-server:1.9.0
args:
- -config
- /run/spire/config/server.conf
volumeMounts:
- name: spire-config
mountPath: /run/spire/config
- name: spire-data
mountPath: /run/spire/data
```
```hcl
# server.conf
server {
bind_address = "0.0.0.0"
bind_port = "8081"
trust_domain = "prod.example.com"
data_dir = "/run/spire/data"
log_level = "INFO"
# JWT SVIDs for service-to-service auth
jwt_issuer = "https://spire-server.spire.svc.cluster.local"
}
plugins {
DataStore "sql" {
plugin_data {
database_type = "sqlite3"
connection_string = "/run/spire/data/datastore.sqlite3"
}
}
NodeAttestor "k8s_psat" {
plugin_data {
clusters = {
"my-cluster" = {
service_account_allow_list = ["spire:spire-agent"]
}
}
}
}
KeyManager "memory" {
plugin_data {}
}
}
```
### Workload Registration
```bash
# Register a workload (checkout-service in payments namespace)
kubectl exec -n spire spire-server-0 -- \
/opt/spire/bin/spire-server entry create \
-spiffeID spiffe://prod.example.com/ns/payments/sa/checkout-service \
-parentID spiffe://prod.example.com/k8s-node/node1 \
-selector k8s:ns:payments \
-selector k8s:sa:checkout-service
```
### Retrieving SVIDs from Workload API (Go)
```go
import (
"github.com/spiffe/go-spiffe/v2/workloadapi"
"github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig"
)
func newTLSConfig(ctx context.Context) (*tls.Config, error) {
source, err := workloadapi.NewX509Source(ctx)
if err != nil {
return nil, fmt.Errorf("create x509 source: %w", err)
}
// TLS config that automatically rotates certificates
return tlsconfig.MTLSClientConfig(source, source, tlsconfig.AuthorizeAny()), nil
}
```
---
## Istio Service Mesh
### Installation
```bash
# Install Istio with ambient mode (no sidecars, ztunnel at node level)
istioctl install --set profile=ambient
# Or with sidecar mode (traditional)
istioctl install --set profile=default
# Enable sidecar injection for a namespace
kubectl label namespace payments istio-injection=enabled
```
### Enforce Strict mTLS Namespace-Wide
```yaml
# peer-authentication.yaml — enforce mTLS for entire namespace
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: payments
spec:
mtls:
mode: STRICT # Reject all non-mTLS traffic. Never leave on PERMISSIVE in production.
```
### Authorization Policies (Default-Deny + Allowlist)
```yaml
# Step 1: Default deny ALL ingress in namespace
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: payments
spec: {} # Empty spec = deny all
---
# Step 2: Explicitly allow checkout → payment-processor
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-checkout-to-processor
namespace: payments
spec:
selector:
matchLabels:
app: payment-processor
rules:
- from:
- source:
principals:
- "cluster.local/ns/payments/sa/checkout-service" # SPIFFE-based identity
to:
- operation:
methods: ["POST"]
paths: ["/v1/payments"]
```
### Traffic Management
```yaml
# VirtualService: retry + timeout
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: payment-processor
namespace: payments
spec:
hosts:
- payment-processor
http:
- retries:
attempts: 3
perTryTimeout: 2s
retryOn: gateway-error,connect-failure,retriable-4xx
timeout: 10s
route:
- destination:
host: payment-processor
```
### Observability (Zero-Code)
```bash
# Prometheus metrics auto-collected: request_total, request_duration_ms, etc.
# Jaeger traces: every request gets a trace ID automatically
# View live traffic between services
istioctl proxy-config log payment-processor-pod --level debug
# Kiali topology graph
kubectl port-forward svc/kiali -n istio-system 20001:20001
```
---
## Linkerd (Lightweight Alternative)
Choose Linkerd over Istio for: smaller teams, simpler operational model, better performance, no CRD explosion.
```bash
# Install Linkerd
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
# Inject into deployment (or annotate namespace)
kubectl annotate namespace payments linkerd.io/inject=enabled
# Verify mTLS is working
linkerd viz tap deploy/checkout-service -n payments
# Traffic tap shows real-time encrypted traffic
linkerd viz edges deployment -n payments
```
```yaml
# Linkerd Server (equivalent to Istio AuthorizationPolicy)
apiVersion: policy.linkerd.io/v1beta3
kind: Server
metadata:
name: payment-processor
namespace: payments
spec:
podSelector:
matchLabels:
app: payment-processor
port: 8080
proxyProtocol: HTTP/2
---
apiVersion: policy.linkerd.io/v1beta3
kind: MeshTLSAuthentication
metadata:
name: checkout-service-authn
namespace: payments
spec:
identities:
- "checkout-service.payments.serviceaccount.identity.linkerd.cluster.local"
---
apiVersion: policy.linkerd.io/v1beta3
kind: AuthorizationPolicy
metadata:
name: checkout-to-processor
namespace: payments
spec:
targetRef:
group: policy.linkerd.io
kind: Server
name: payment-processor
requiredAuthenticationRefs:
- name: checkout-service-authn
kind: MeshTLSAuthentication
group: policy.linkerd.io
```
---
## Kubernetes NetworkPolicies
NetworkPolicies are the Layer-3/4 firewall — always use them even with a service mesh.
### Pattern: Default Deny All, then Allowlist
```yaml
# 1. Default deny all ingress AND egress in namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: payments
spec:
podSelector: {} # applies to ALL pods in namespace
policyTypes:
- Ingress
- Egress
```
```yaml
# 2. Allow checkout → payment-processor on port 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-checkout-to-processor
namespace: payments
spec:
podSelector:
matchLabels:
app: payment-processor
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: checkout-service
ports:
- protocol: TCP
port: 8080
```
```yaml
# 3. Allow DNS resolution (required for all pods)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: payments
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
```
### Cilium — Layer-7 NetworkPolicies (HTTP-aware)
```yaml
# Block all HTTP except POST /v1/payments
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: l7-payment-processor
namespace: payments
spec:
endpointSelector:
matchLabels:
app: payment-processor
ingress:
- fromEndpoints:
- matchLabels:
app: checkout-service
toPorts:
- ports:
- port: "8080"
protocol: TCP
rules:
http:
- method: POST
path: /v1/payments
```
---
## East-West Traffic Security
### Secrets: Never in Environment Variables
```yaml
# WRONG: Secret as environment variable
env:
- name: DB_PASSWORD
value: "supersecret" # visible in pod spec, logs, ps aux
# WRONG: Even from k8s secret (still exposed as env var)
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
```
```yaml
# CORRECT: Vault Agent Sidecar (secrets never touch etcd)
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-db: "secret/payments/db"
vault.hashicorp.com/role: "checkout-service"
vault.hashicorp.com/agent-inject-template-db: |
{{- with secret "secret/payments/db" -}}
DB_PASSWORD={{ .Data.data.password }}
{{- end }}
```
```yaml
# CORRECT: External Secrets Operator (ESO) — syncs from AWS Secrets Manager / GCP Secret Manager
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-secret
namespace: payments
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets-manager
kind: ClusterSecretStore
target:
name: db-credentials
creationPolicy: Owner
data:
- secretKey: DB_PASSWORD
remoteRef:
key: prod/payments/db
property: password
```
### Kubernetes Token Volume Projection (Audience-Bound, Short-Lived)
```yaml
volumes:
- name: vault-token
projected:
sources:
- serviceAccountToken:
audience: vault # audience-bound, not usable for anything else
expirationSeconds: 3600 # short-lived
path: token
```
---
## Zero-Trust for APIs — BeyondCorp Pattern
```
User Request
│
▼
Identity-Aware Proxy (IAP / Verified Access)
│ checks:
│ - Identity (Google/OIDC token)
│ - Device trust (MDM-enrolled, cert-based)
│ - Context (IP reputation, time of day)
│
▼ [Allow or Deny]
Backend Service (no direct internet exposure)
```
### AWS Verified Access Example
```hcl
# Terraform: AWS Verified Access endpoint
resource "aws_verifiedaccess_endpoint" "internal_api" {
verified_access_group_id = aws_verifiedaccess_group.main.id
endpoint_type = "load-balancer"
attachment_type = "vpc"
load_balancer_options {
load_balancer_arn = aws_lb.internal.arn
port = 443
protocol = "https"
subnet_ids = var.private_subnet_ids
}
security_group_ids = [aws_security_group.verified_access.id]
}
resource "aws_verifiedaccess_trust_provider" "oidc" {
trust_provider_type = "user"
user_trust_provider_type = "oidc"
oidc_options {
issuer = "https://accounts.google.com"
authorization_endpoint = "https://accounts.google.com/o/oauth2/v2/auth"
token_endpoint = "https://oauth2.googleapis.com/token"
client_id = var.oauth_client_id
client_secret = var.oauth_client_secret
scope = "openid email"
}
}
```
---
## Zero-Trust Checklist
Before deploying any new service:
- [ ] Service identity: SPIFFE SVID or Kubernetes Service Account Token with audience binding?
- [ ] mTLS: `PeerAuthentication` set to `STRICT` (not `PERMISSIVE`) in production?
- [ ] Authorization: `deny-all` policy exists, explicit allowlist for each route?
- [ ] NetworkPolicy: `default-deny-all` in namespace, per-service allowlist?
- [ ] Secrets: stored in Vault/ESO — not in env vars or k8s Secret mounted as env?
- [ ] Egress: only required external endpoints whitelisted?
- [ ] East-west: no plain HTTP between services in the mesh?
- [ ] Observability: mTLS telemetry visible in Prometheus/Jaeger/Kiali?
---
## Tool Reference
| Tool | Purpose |
|------|---------|
| `SPIRE` | SPIFFE reference implementation — workload identity |
| `Istio` | Full-featured service mesh — mTLS, traffic management, observability |
| `Linkerd` | Lightweight service mesh — simpler, better performance |
| `Cilium` | eBPF-based CNI — Layer-7 NetworkPolicies, identity-aware routing |
| `Vault` | Secret management — dynamic secrets, lease-based rotation |
| `External Secrets Operator` | Sync secrets from AWS/GCP/Azure into k8s |
| `OPA/Gatekeeper` | Policy enforcement — enforce Zero-Trust rules as admission webhooks |
| `cert-manager` | Automate certificate rotation for mTLS |
---
## Related Skills
- `kubernetes-patterns` — base k8s patterns (Deployments, Services, Ingress)
- `devsecops-patterns` — SAST/DAST/OPA policy automation
- `auth-patterns` — user authentication (JWT, OAuth2) — different from service identity
- `supply-chain-security` — SBOM, SLSA, Sigstore for artifact trustRelated Skills
webrtc-patterns
WebRTC patterns — peer connection setup, ICE/STUN/TURN configuration, signaling server design, SFU vs mesh topology, screen sharing, media track management, and reconnect/ICE restart handling.
webhook-patterns
Webhook patterns for receiving, verifying (HMAC), and idempotently processing third-party events. Covers Stripe, GitHub, and generic webhook patterns, delivery guarantees, retry handling, and testing.
wasm-patterns
WebAssembly patterns: wasm-pack, wasm-bindgen (JS↔Wasm interop), WASI, Component Model, wasm-opt, Rust-to-WASM compilation, JS integration (web workers, streaming instantiation), and production deployment (CDN, Content-Type headers).
ux-micro-patterns
UX micro-patterns for every product state: Empty States, Loading States (skeleton screens, spinners, optimistic UI), Error States, Success States, Confirmation Dialogs, Onboarding Flows, and Progressive Disclosure. These patterns apply to every feature — done wrong, they're the biggest source of user confusion.
typescript-patterns
TypeScript patterns — type system best practices, strict mode, utility types, generics, discriminated unions, error handling with Result types, and module organization. Core patterns for production TypeScript.
typescript-patterns-advanced
Advanced TypeScript — mapped types, template literal types, conditional types, infer, type guards, decorators, async patterns, testing with Vitest/Jest, and performance. Extends typescript-patterns.
typescript-monorepo-patterns
TypeScript monorepo patterns with Turborepo + pnpm workspaces. Covers package structure, shared configs, task pipeline caching, build orchestration, and publishing strategy.
terraform-patterns
Infrastructure as Code with Terraform — project structure, remote state, modules, workspace strategy, AWS/GCP patterns, CI/CD integration, and security hardening. The standard for managing production infrastructure.
swiftui-patterns
SwiftUI architecture patterns, state management with @Observable, view composition, navigation, performance optimization, and modern iOS/macOS UI best practices.
swift-patterns
Core Swift patterns — value vs reference types, protocols, generics, optionals, Result, error handling, Codable, and module organization. Foundation for all Swift development.
swift-patterns-advanced
Advanced Swift patterns — property wrappers, result builders, Combine basics, opaque & existential types, macro system, advanced generics, and performance optimization. Extends swift-patterns.
storybook-patterns
Storybook patterns: CSF3 (meta satisfies Meta, play functions, @storybook/test), addon ecosystem (a11y, interactions, docs), MSW integration for API mocking, Chromatic CI, storybook-test-runner for Jest/Playwright execution, and Storybook as living documentation.