Diffhold pre-alpha

Quickstart

Install Diffhold on a local kind cluster, load an example policy and watch it allow, deny and hold agent calls. About 10 minutes.

The source and image are not public yet. They will be at the v0.1 release, and until then these steps need a checkout of the source. They build the image locally, so no pull secret is needed.

1. Create a cluster and build the image

kind create cluster --name diffhold --image kindest/node:v1.35.0
cd diffhold                    # your checkout of the source
make build                     # bin/diffhold, used below
docker build -t diffhold:dev .
kind load docker-image diffhold:dev --name diffhold

2. Create an agent identity

Agents act through a ServiceAccount in an agent namespace (agents by default). Its RBAC is the hard ceiling: Diffhold can only narrow it. The test fixtures create the agents/agent-sre-bot ServiceAccount, a role for it in team-a, a sample Deployment and an approver ServiceAccount oncall/alice.

kubectl apply -f test/e2e/fixtures.yaml

3. Install the chart

helm install diffhold charts/diffhold -n diffhold-system --create-namespace \
  --set image.repository=diffhold --set image.tag=dev --set image.pullPolicy=Never --wait

The chart generates the webhook CA, the gRPC server and gateway client certificates, the admin token, the grant signing key and the audit signing key, and keeps all of them across upgrades.

4. Load a policy

kubectl apply -f examples/agentpolicy.yaml
kubectl -n diffhold-system get agentpolicies
NAME      AGENTS    MODE      READY   AGE
sre-bot   sre-bot   enforce   True    4s

Check the policy offline at any time, and run its test suite:

bin/diffhold policy check examples/agentpolicy.yaml
bin/diffhold test examples/agentpolicy_test.yaml      # 10/10 passed

5. Connect a gateway

Point agentgateway's guardrail processor at diffhold.diffhold-system.svc:9000 with the client certificate from Secret diffhold-gateway-client. See Connect agentgateway.

To try the full path without a gateway, run the end-to-end suite. It calls Diffhold over mTLS the way agentgateway does, uses the returned tokens against the API server and checks every result:

DIFFHOLD_E2E_CONTEXT=kind-diffhold hack/e2e-helm.sh

6. Approve a held call

kubectl -n diffhold-system port-forward svc/diffhold 9001 &
kubectl -n diffhold-system get secret diffhold-gateway-client -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
kubectl -n diffhold-system get secret diffhold-admin -o jsonpath='{.data.token}' | base64 -d > admin.token
export DIFFHOLD_ADMIN=https://localhost:9001 DIFFHOLD_CA_FILE=ca.crt
TLS="--tls-server-name diffhold.diffhold-system.svc"
bin/diffhold approvals list $TLS --token-file admin.token

kubectl create token alice -n oncall --audience diffhold > alice.token
bin/diffhold approvals approve CALL_ID $TLS --token-file alice.token

Check that no agent ServiceAccount can switch Diffhold off:

bin/diffhold permissions check agents/agent-sre-bot --context kind-diffhold      # OK    agents/agent-sre-bot

The agent retries the same call and it goes through once. See Approvals.

Uninstall

helm uninstall diffhold -n diffhold-system

A pre-delete hook revokes every outstanding per-call token before the webhook goes away. Helm leaves the CRD in place.