
This page follows [Quickstart](/get-started/quickstart/). You have built the
`dvx` binary, and you have an enclave that a broker converges: the state that
[Register an enclave](/guides/register-an-enclave/) produces. To author agents
you authenticate to the controlplane's operator API with the shared operator
flags: `--zitadel-key` plus `--issuer` (or `--token-file`), and `--ca-cert`
pointing at the CA that verifies the controlplane's serving cert.

## Create the agent

An agent is desired state. `dvx agent create` records the intent through the
operator API, and the enclave's broker reconciles it into a namespace, a Pod,
and a metadata socket. You never touch Kubernetes to create an agent, and the
agent image is yours to choose.

{{< terminal title="dvx" prompt="$" >}}
$ dvx agent create \
    --controlplane https://cp.example.com \
    --org dev-org \
    --uid first-agent --name first-agent \
    --enclave daevix-dev \
    --image curlimages/curl:8.11.1 \
    --command /bin/sh --command -c --command 'sleep 3600'
POST /api/v1/orgs/dev-org/agents -> 201
{
  "uid": "first-agent",
  "org_id": "dev-org",
  "name": "first-agent",
  "enclave_id": "c359fcbd890f...",
  "image": "curlimages/curl:8.11.1",
  "command": ["/bin/sh", "-c", "sleep 3600"]
}
{{< /terminal >}}

`--enclave` takes a registered enclave. `--uid` names the agent; it becomes
part of the agent's Kubernetes namespace and its metadata socket. Omit it and
the controlplane generates a memorable one, such as `nostalgic-otter`.
`--command` repeats one token per entrypoint word.

## Watch the enclave reconcile

The broker pulls the desired state on its next pull and provisions the
workload. The pod carries the agent uid in the `dvx.io/agent-uid` label, and
the broker forms its namespace from the enclave's 12-character id prefix plus
the uid.

{{< terminal title="sh" prompt="$" >}}
$ kubectl wait --for=condition=Ready pod -l dvx.io/agent-uid=first-agent -A --timeout=150s
$ kubectl get pods -A -l dvx.io/agent-uid=first-agent
NAMESPACE                  NAME          READY   STATUS    RESTARTS   AGE
c359fcbd890f-first-agent   first-agent   1/1     Running   0          20s
{{< /terminal >}}

## Read the agent's identity

Each agent pod mounts a unix socket at `/run/dvx/imds.sock`. The socket is the
IMDS-like metadata service, and it is the only interface that the agent talks
to.
The service resolves the caller's identity from *which* socket the request
arrived on, never from anything that the agent presents. Ask it for the identity:

{{< terminal title="sh" prompt="$" >}}
$ kubectl exec -n c359fcbd890f-first-agent first-agent -c agent -- \
    curl -s --unix-socket /run/dvx/imds.sock http://imds/v1/identity
{"agent_id":"first-agent","agent_name":"first-agent","enclave_id":"c359fcbd890f...","org_id":"dev-org"}
{{< /terminal >}}

The imds mints a short-lived identity token on demand over the same socket,
so the agent
never holds a standing credential:

{{< terminal title="sh" prompt="$" >}}
$ kubectl exec -n c359fcbd890f-first-agent first-agent -c agent -- \
    curl -s --unix-socket /run/dvx/imds.sock http://imds/v1/identity/token
{"token":"dvx-tok-first-agent-...","token_type":"Bearer","expires_in":300}
{{< /terminal >}}

A request on a socket with no registered agent receives a 403. If the agent is
deleted, deregistration stops the service immediately.

## See default-deny egress

The agent's egress is default-deny. Watch a request to a destination that no
policy allows fail, without any per-agent configuration:

{{< terminal title="sh" prompt="$" >}}
$ kubectl exec -n c359fcbd890f-first-agent first-agent -c agent -- \
    curl -s -m 20 https://www.wikipedia.org
curl: (56) OpenSSL SSL_read: SSL_ERROR_SYSCALL
{{< /terminal >}}

The gateway refused the connection and wrote a `gateway.egress` deny row to
the enclave's audit stream. Only destinations that policy allows are reachable;
see
[Author and pull policy](/guides/author-and-pull-policy/) to allow one.

## Remove the agent

Deleting the desired state tears the workload down. The broker removes the
namespace, the pod, and the socket, and the metadata service stops serving the
agent at once.

{{< terminal title="dvx" prompt="$" >}}
$ dvx agent delete \
    --controlplane https://cp.example.com \
    --org dev-org --uid first-agent
DELETE /api/v1/orgs/dev-org/agents/first-agent -> 204
{{< /terminal >}}

Next, govern what the agent may say and fetch:
[Author and pull policy](/guides/author-and-pull-policy/), or walk the full
operator path in [Run an agent against a local enclave](/guides/run-an-agent-locally/).
