# 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: # tls.key: