Files
at-container-registry/examples/verification/kubernetes-webhook.yaml
2025-10-31 21:03:33 -05:00

260 lines
6.2 KiB
YAML

# Kubernetes Admission Webhook for ATProto Signature Verification
#
# This example shows how to deploy a validating admission webhook that
# verifies ATProto signatures before allowing pods to be created.
#
# Prerequisites:
# 1. Build and push the webhook image (see examples/webhook/ for code)
# 2. Generate TLS certificates for the webhook
# 3. Create trust policy ConfigMap
#
# Usage:
# kubectl apply -f kubernetes-webhook.yaml
# kubectl label namespace production atcr-verify=enabled
---
apiVersion: v1
kind: Namespace
metadata:
name: atcr-system
---
# ConfigMap with trust policy
apiVersion: v1
kind: ConfigMap
metadata:
name: atcr-trust-policy
namespace: atcr-system
data:
policy.yaml: |
version: 1.0
# Global settings
defaultAction: enforce # enforce, audit, or allow
# Policies by image pattern
policies:
- name: production-images
scope: "atcr.io/*/prod-*"
require:
signature: true
trustedDIDs:
- did:plc:your-org-devops
- did:plc:your-org-security
minSignatures: 1
action: enforce
- name: staging-images
scope: "atcr.io/*/staging-*"
require:
signature: true
trustedDIDs:
- did:plc:your-org-devops
- did:plc:your-org-security
- did:plc:your-developers
action: enforce
- name: dev-images
scope: "atcr.io/*/dev-*"
require:
signature: false
action: audit # Log but don't block
# Trusted DIDs configuration
trustedDIDs:
did:plc:your-org-devops:
name: "DevOps Team"
validFrom: "2024-01-01T00:00:00Z"
expiresAt: null
did:plc:your-org-security:
name: "Security Team"
validFrom: "2024-01-01T00:00:00Z"
expiresAt: null
did:plc:your-developers:
name: "Developer Team"
validFrom: "2024-06-01T00:00:00Z"
expiresAt: null
---
# Service for webhook
apiVersion: v1
kind: Service
metadata:
name: atcr-verify-webhook
namespace: atcr-system
spec:
selector:
app: atcr-verify-webhook
ports:
- name: https
port: 443
targetPort: 8443
---
# Deployment for webhook
apiVersion: apps/v1
kind: Deployment
metadata:
name: atcr-verify-webhook
namespace: atcr-system
spec:
replicas: 2
selector:
matchLabels:
app: atcr-verify-webhook
template:
metadata:
labels:
app: atcr-verify-webhook
spec:
containers:
- name: webhook
image: atcr.io/atcr/verify-webhook:latest
imagePullPolicy: Always
ports:
- containerPort: 8443
name: https
env:
- name: TLS_CERT_FILE
value: /etc/webhook/certs/tls.crt
- name: TLS_KEY_FILE
value: /etc/webhook/certs/tls.key
- name: POLICY_FILE
value: /etc/webhook/policy/policy.yaml
- name: LOG_LEVEL
value: info
volumeMounts:
- name: webhook-certs
mountPath: /etc/webhook/certs
readOnly: true
- name: policy
mountPath: /etc/webhook/policy
readOnly: true
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /healthz
port: 8443
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: 8443
scheme: HTTPS
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: webhook-certs
secret:
secretName: atcr-verify-webhook-certs
- name: policy
configMap:
name: atcr-trust-policy
---
# ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: atcr-verify
webhooks:
- name: verify.atcr.io
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
# Client configuration
clientConfig:
service:
name: atcr-verify-webhook
namespace: atcr-system
path: /validate
port: 443
# CA bundle for webhook TLS (base64-encoded CA cert)
# Generate with: cat ca.crt | base64 -w 0
caBundle: LS0tLS1CRUdJTi... # Replace with your CA bundle
# Rules - what to validate
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
scope: "Namespaced"
# Namespace selector - only validate labeled namespaces
namespaceSelector:
matchExpressions:
- key: atcr-verify
operator: In
values: ["enabled", "enforce"]
# Failure policy - what to do if webhook fails
failurePolicy: Fail # Reject pods if webhook is unavailable
# Timeout
timeoutSeconds: 10
# Match policy
matchPolicy: Equivalent
---
# Example: Label a namespace to enable verification
# kubectl label namespace production atcr-verify=enabled
---
# RBAC for webhook
apiVersion: v1
kind: ServiceAccount
metadata:
name: atcr-verify-webhook
namespace: atcr-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: atcr-verify-webhook
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: atcr-verify-webhook
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: atcr-verify-webhook
subjects:
- kind: ServiceAccount
name: atcr-verify-webhook
namespace: atcr-system
---
# Secret for TLS certificates
# Generate certificates with:
# openssl req -x509 -newkey rsa:4096 -keyout tls.key -out tls.crt \
# -days 365 -nodes -subj "/CN=atcr-verify-webhook.atcr-system.svc"
#
# Create secret with:
# kubectl create secret tls atcr-verify-webhook-certs \
# --cert=tls.crt --key=tls.key -n atcr-system
#
# (Commented out - create manually with your certs)
# apiVersion: v1
# kind: Secret
# metadata:
# name: atcr-verify-webhook-certs
# namespace: atcr-system
# type: kubernetes.io/tls
# data:
# tls.crt: <base64-encoded-cert>
# tls.key: <base64-encoded-key>