Quickstart
Run your first sandboxed agent end-to-end in about a minute.
This walks through CLRK end-to-end against a local k3s container - install the CLI, boot a controller-manager + worker, dispatch an Anthropic-calling agent, and confirm the proxy injected the API key on the way out.
Docker running on the host, an Anthropic API key in your shell, and macOS or Linux. You
do not need an existing Kubernetes cluster - clrk dev ships its own k3s.
Install the CLI
The CLI is a single static Go binary. Build it from a clone of the repo - you'll reuse that same clone for the example manifests below.
git clone https://github.com/apoxy-dev/clrk.git
cd clrk
go build -o /usr/local/bin/clrk ./cmd/clrkConfirm it's on your $PATH:
clrk --helpProvide an API key
The example agent calls api.anthropic.com. Put your key into the shell - clrk dev
will read it from the environment and never write it to the manifests.
export ANTHROPIC_API_KEY=sk-ant-...Boot the local stack
From the clone you built in step 1, start the dev stack with the example manifests:
clrk dev \
--apply _examples/echo-bot/manifests \
--secret anthropic-credentials=ANTHROPIC_API_KEY:api-keyWhat this does, in order:
- Runs a host-readiness check (Docker daemon,
/dev/net/tun, IPv6, image pullable). - Brings up a k3d cluster (docker container
k3d-clrk-dev-server-0, plus aclrk-registrycontainer when a local registry is enabled), then applies the controller-manager as a Deployment in theclrknamespace and a default WorkerPool whose reconciler creates thedefault-workersDeployment in thedefaultnamespace. The controller-manager and workers run as in-cluster pods, not sibling docker containers. - Writes a host-side kubeconfig to
~/.clrk/kubeconfig.host(apiserver published onhttps://localhost:<dynamically-allocated-port>- read the server URL from the kubeconfig). - Materializes the
anthropic-credentialsSecret from your shell env. The--secretflag takesNAME=ENVVAR[:KEY]; we set:api-keyexplicitly so theCredentialInjectionPolicycan name it. - Server-side-applies the echo-bot manifests once the apiserver is reachable.
Roughly thirty seconds in, the TUI settles when k3d-clrk-dev-server-0,
controller-manager, and worker-0 are all running.
Watch it run
Point kubectl (or clrk) at the local apiserver and confirm the resources reconciled:
export KUBECONFIG=~/.clrk/kubeconfig.host
# The DaemonAgent the example installed.
clrk agents get echo-bot
# The egress proxy in front of it.
kubectl get egressgateway echo-bot
# The Secret clrk dev materialized from your shell env.
kubectl get secret anthropic-credentialsOnce the first cycle fires (about five seconds in), the TUI's otel-logs pane carries
one structured line per call:
15:04:05.123 POST api.anthropic.com/v1/messages 200 540ms req=312B resp=1024B provider=anthropic model=claude-haiku-4-5 input_tokens=12 output_tokens=24 route=default/anthropic trace=a1b2c3d4The matching span lands in otel-traces. These records are emitted by the
EgressGateway's ext_proc - the same surface that emits to your real OTLP collector in
production.
Verify the agent never saw the key
The example installs a CredentialInjectionPolicy that attaches the
anthropic-credentials Secret to the AIProviderRoute. The agent makes its POST with
no x-api-key header; the proxy inserts the real value as the request leaves the
sandbox.
Confirm it through the captured telemetry - the agent runs in an isolated gVisor sandbox, so its process environment is not visible from the worker pod's namespace:
# Anthropic accepted the call, which only happens if the proxy injected the key.
clrk agents logs echo-bot --tail 20
# Expect a 200 response body with the model's reply.A 200 here proves the proxy supplied the credential: the agent sent its POST with no
x-api-key header, and the request still succeeded. Open the matching span in
otel-traces and the captured x-api-key header attribute
(http.request.header.x-api-key) shows as [redacted] - telemetry never carries the
real secret either.
Tear down
Ctrl-C the dev TUI to stop the local cluster. State persists under ~/.clrk/; the
next clrk dev reattaches to it. For a clean slate:
rm -rf ~/.clrkNext steps
- Local development - every flag on
clrk devand how to iterate on the controller and worker binaries. - Core concepts - the CRDs you just applied, what each one controls, and how they fit together.
- Run your first agent - the same example, explored in detail, with the full architecture diagram.
- Package a custom agent - turn a script into a
TaskAgentand trigger it over HTTP or cron.