Getting startedGuidesReferenceChangelog
Apoxy:// Docs / Getting started / Quickstart

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.

Prereqs

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.

$terminalSH
git clone https://github.com/apoxy-dev/clrk.git cd clrk go build -o /usr/local/bin/clrk ./cmd/clrk

Confirm it's on your $PATH:

$terminalSH
clrk --help

Provide 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.

$terminalSH
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:

$terminalSH
clrk dev \ --apply _examples/echo-bot/manifests \ --secret anthropic-credentials=ANTHROPIC_API_KEY:api-key

What this does, in order:

  1. Runs a host-readiness check (Docker daemon, /dev/net/tun, IPv6, image pullable).
  2. Brings up a k3d cluster (docker container k3d-clrk-dev-server-0, plus a clrk-registry container when a local registry is enabled), then applies the controller-manager as a Deployment in the clrk namespace and a default WorkerPool whose reconciler creates the default-workers Deployment in the default namespace. The controller-manager and workers run as in-cluster pods, not sibling docker containers.
  3. Writes a host-side kubeconfig to ~/.clrk/kubeconfig.host (apiserver published on https://localhost:<dynamically-allocated-port> - read the server URL from the kubeconfig).
  4. Materializes the anthropic-credentials Secret from your shell env. The --secret flag takes NAME=ENVVAR[:KEY]; we set :api-key explicitly so the CredentialInjectionPolicy can name it.
  5. 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:

$terminalSH
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-credentials

Once the first cycle fires (about five seconds in), the TUI's otel-logs pane carries one structured line per call:

$terminalTXT
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=a1b2c3d4

The 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:

$terminalSH
# 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:

$terminalSH
rm -rf ~/.clrk

Next steps

  • Local development - every flag on clrk dev and 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 TaskAgent and trigger it over HTTP or cron.