Your agent on Kubernetes
Your first agent runs unchanged in a pod. Two lines differ.
# on your laptop
client = Client("http://127.0.0.1:8080", api_key="rem-token")
# in a pod
client = Client("http://kslate-gateway.kslate.svc",
token_file="/var/run/secrets/kslate/token")decide, Write, Agent, run(), the rejections, the claims and the
checkpoints are all identical. So is the class: the SharedContext you
kubectl apply is the same document, with the same spec, that
--policy reads from a file.
Why a token file and not a key
token_file is re-read on every request. A projected ServiceAccount
token is rotated by the kubelet, so a value read once at startup would
expire; reading the file each time picks up the rotation.
The identity that lands on every write is then
sa:<namespace>/<name>, proved by the Kubernetes API rather than
asserted by your pod — which is why it is worth more than an API key.
Identity strength covers what the
difference buys you.
Mounting the token
An agent pod authenticates as its own ServiceAccount. Mount a projected
token with audience kslate:
volumes:
- name: kslate-token
projected:
sources:
- serviceAccountToken: {audience: kslate, expirationSeconds: 3600, path: token}
volumeMounts:
- {name: kslate-token, mountPath: /var/run/secrets/kslate}The ServiceAccount must appear in a role of the class as
sa:<namespace>/<name>, exactly as apikey:<name> did on your laptop.
That is the same identities list from adding a second
agent.
One copy per pod is not one identity per pod
Every pod of one Deployment shares its ServiceAccount, so kslate sees them as a single identity. A claim from the identity that already owns a task is a re-claim, not contention — so scaling a Deployment to three replicas does not give you three workers competing safely for tasks. Give each worker its own identity, or run them as separate Deployments with separate ServiceAccounts. One identity, not one process has the shape of a role that covers a fleet.
In Go
client := kslate.NewWithTokenSource("http://kslate-gateway.kslate.svc",
kslate.TokenFile("/var/run/secrets/kslate/token"))The Go agent page has the rest.
Next
- kagent to connect an agent you cannot modify, as a sidecar or over MCP.
- Honest limits before a real network: traffic is plaintext unless you enable TLS.