Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.
npx skills add https://github.com/BagelHole/DevOps-Security-Agent-Skills --skill zero-trust
Implement "never trust, always verify" security model.
Use this skill when:
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
# 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 }
}'
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]"]
}
}
# 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
# 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: {}
# 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
# 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
}
| 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 |
Integration with protocols.io API for managing scientific protocols. This skill should be used when working with protocols.io to search, create, update, or publish protocols; manage protocol steps and materials; handle discussions and comments; organize workspaces; upload and manage files; or integrate protocols.io functionality into workflows. Applicable for protocol discovery, collaborative protocol development, experiment tracking, lab protocol management, and scientific documentation.
Analyzes job descriptions and generates tailored resumes that highlight relevant experience, skills, and achievements to maximize interview chances
Generate Excalidraw diagrams from natural language descriptions. Use when asked to "create a diagram", "make a flowchart", "visualize a process", "draw a system architecture", "create a mind map", or "generate an Excalidraw file". Supports flowcharts, relationship diagrams, mind maps, and system architecture diagrams. Outputs .excalidraw JSON files that can be opened directly in Excalidraw.
Build and distribute Expo development clients locally or via TestFlight
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Data structure for annotated matrices in single-cell analysis. Use when working with .h5ad files or integrating with the scverse ecosystem. This is the data format skill—for analysis workflows use scanpy; for probabilistic models use scvi-tools; for population-scale queries use cellxgene-census.
Benchling R&D platform integration. Access registry (DNA, proteins), inventory, ELN entries, workflows via API, build Benchling Apps, query Data Warehouse, for lab data management automation.
Comprehensive molecular biology toolkit. Use for sequence manipulation, file parsing (FASTA/GenBank/PDB), phylogenetics, and programmatic NCBI/PubMed access (Bio.Entrez). Best for batch processing, custom bioinformatics pipelines, BLAST automation. For quick lookups use gget; for multi-service integration use bioservices.
Take bagelhole/zero-trust from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.