Skip to main content
skill CX Codex

zero-trust — Claude Code skill: what it does, how to install

Implements zero-trust network architecture with identity-based access, micro-segmentation, and continuous verification. Helps replace traditional VPNs with BeyondCorp-style controls.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill zero-trust -a claude-code
Open on GitHub

What zero-trust does

This skill guides the implementation of the "never trust, always verify" model. It shifts infrastructure defense away from legacy perimeter VPNs toward continuous identity verification and explicit authorization for every request.

The skill covers multiple architecture layers with concrete configuration examples. For edge application security, it includes Cloudflare Access setups using API calls and Terraform. For cluster environments, it supplies deployment manifests for oauth2-proxy paired with Nginx Ingress, along with Istio configurations for strict service-to-service mTLS.

These patterns will not work in isolation. You must have an identity provider supporting OIDC or SAML, such as Okta, Azure AD, or Google Workspace, along with an existing proxy or Kubernetes cluster.

What it helps with

  • replace perimeter VPN setups with BeyondCorp access
  • configure Cloudflare Access policies and device posture checks
  • deploy oauth2-proxy for Kubernetes Ingress authentication
  • enforce strict mTLS communication between microservices

Example prompts for the agent

  • Configure oauth2-proxy with OIDC for an internal Kubernetes Ingress.
  • Generate Terraform manifests for Cloudflare Access policies.
  • Set up strict mutual TLS in Istio to secure service traffic.

How to install zero-trust

1Skills CLI (Vercel)

npx skills add BagelHole/DevOps-Security-Agent-Skills --skill zero-trust -a claude-code

2Manually: put the files in place

~/.claude/skills/zero-trust/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/zero-trust/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about zero-trust

How to install zero-trust in Claude Code?

Run npx skills add BagelHole/DevOps-Security-Agent-Skills --skill zero-trust -a claude-code.

What does the zero-trust skill do?

It provides configuration guides and manifests for identity-based security. The skill covers Cloudflare Access, Terraform policies, Kubernetes oauth2-proxy deployments, and Istio mTLS.

What prerequisites are needed for this architecture?

You need an identity provider compatible with OIDC or SAML, such as Okta, Azure AD, or Google Workspace. Workload-level configurations also require a Kubernetes cluster and a proxy or service mesh.

Source text

SKILL.md · MIT
---
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.

## 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

## 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 containment
```

## 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 = ["[email protected]"]
  }
}
```

## Identity-Aware Proxy with OAuth2 Proxy

```yaml
# 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
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
---
# 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/*"]
---
# Default deny all in namespace
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
  namespace: production
spec: {}
```

## Micro-Segmentation with Kubernetes Network Policies

```yaml
# 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
---
# 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
}
```

## Implementation Steps

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

## 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 `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 |

## Related Skills

- [service-mesh](../../../infrastructure/networking/service-mesh/) - mTLS implementation
- [kubernetes-hardening](../../hardening/kubernetes-hardening/) - K8s security
- [vpn-setup](../vpn-setup/) - Traditional VPN (contrast with zero trust)

© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills

Similar skills

All skills for Security →

From the same set129

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor