> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hexr.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Pod Architecture

> Every agent deploys as a Kubernetes Pod with four containers: your agent code, Envoy mTLS proxy, A2A sidecar, and PID mapper.

## Pod Structure

When you run `hexr deploy`, your agent becomes a Kubernetes Pod with exactly four containers plus an init container:

<Tabs>
  <Tab title="Containers">
    <Steps>
      <Step title="Init: install-hexr-sdk" icon="download">
        Installs the Hexr SDK from private PyPI into a shared volume. Ensures the SDK version
        matches what was used during `hexr build`.
      </Step>

      <Step title="agent · :8080" icon="robot">
        **Your Python code.** Runs your `@hexr_agent`-decorated function. Listens on `:8080`
        for inbound A2A bridge calls. Connects to SPIRE Workload API for SVID.
      </Step>

      <Step title="envoy-sidecar · :15001 / :15006" icon="shield-halved">
        **mTLS proxy.** Terminates inbound TLS on `:15006`, initiates outbound mTLS on `:15001`.
        Loads X.509-SVIDs via SPIRE SDS. Routes `/.well-known/*` and `/a2a` traffic.
      </Step>

      <Step title="a2a-sidecar · :8090" icon="arrows-left-right">
        **Agent communication.** JSON-RPC 2.0 dispatch (`message/send`, `message/stream`,
        `tasks/get`, `tasks/cancel`). Task state persisted in Valkey with SETNX idempotency.
      </Step>

      <Step title="pid-mapper · hostPID: true" icon="fingerprint">
        **Identity mapper.** Reads `/proc` with host PID namespace access. Maps container PIDs
        to host PIDs. Writes enriched process context JSON for SPIRE workload attestation.
      </Step>
    </Steps>
  </Tab>

  <Tab title="Shared Volumes">
    | Volume                 | Mount Path            | Who Reads                  | Who Writes                 |
    | ---------------------- | --------------------- | -------------------------- | -------------------------- |
    | **spire-agent-socket** | `/run/spire/sockets/` | Agent, Envoy, A2A          | SPIRE Agent (DaemonSet)    |
    | **hexr-context**       | `/tmp/hexr-context/`  | PID Mapper                 | Agent (marker files)       |
    | **host-hexr-context**  | `/host-hexr-context/` | File Collector (DaemonSet) | PID Mapper (enriched JSON) |
  </Tab>

  <Tab title="Pod Manifest">
    ```yaml theme={null}
    # Generated by hexr build (simplified)
    apiVersion: v1
    kind: Pod
    metadata:
      name: acme-research-analyst
      namespace: tenant-acme-corp
      labels:
        hexr.io/managed: "true"
        hexr.io/tenant: "acme-corp"
        hexr.io/agent-name: "research-analyst"
    spec:
      hostPID: true  # Required for per-process identity
      initContainers:
        - name: install-hexr-sdk
      containers:
        - name: agent           # Your code (:8080)
        - name: envoy-sidecar   # mTLS proxy (:15001/:15006)
        - name: a2a-sidecar     # Agent comms (:8090)
        - name: pid-mapper      # PID → SPIFFE mapper
    ```
  </Tab>
</Tabs>

***

## Container Details

### 1. Agent Container

Your Python code with the Hexr SDK. This is the only container you write code for.

| Property     | Value                                                                             |
| ------------ | --------------------------------------------------------------------------------- |
| **Port**     | `:8080` (A2A bridge listener)                                                     |
| **Volumes**  | SPIRE socket, hexr-context, shared site-packages                                  |
| **Env vars** | `HEXR_FRAMEWORK`, `HEXR_TENANT`, `HEXR_AGENT_NAME`, `OTEL_EXPORTER_OTLP_ENDPOINT` |

```python theme={null}
# What runs inside this container
@hexr_agent(name="research-analyst", tenant="acme-corp")
def analyze(topic: str):
    s3 = hexr_tool("aws_s3")          # → Envoy → Credential Injector → STS
    client = hexr_llm(openai.OpenAI()) # → OTel spans emitted
    # ... your agent logic
```

### 2. Envoy Sidecar

Transparent mTLS proxy. Handles all network traffic in and out of the pod.

| Property         | Value                                                           |
| ---------------- | --------------------------------------------------------------- |
| **Inbound**      | `:15006` — terminates TLS, forwards plain HTTP to agent/sidecar |
| **Outbound**     | `:15001` — initiates mTLS to other pods and services            |
| **Certificates** | X.509-SVID from SPIRE via SDS (Secret Discovery Service)        |
| **Routes**       | `/.well-known/*` → Agent Card ConfigMap, `/a2a` → A2A Sidecar   |

<Info>
  Envoy uses `syscall.Exec` PID inheritance — the envoy process "becomes" the proxy
  while maintaining the correct PID for SPIRE attestation. This is a novel technique
  described in the Hexr patent application.
</Info>

### 3. A2A Sidecar

Implements the Agent-to-Agent protocol for inter-agent communication.

| Property      | Value                                                          |
| ------------- | -------------------------------------------------------------- |
| **Port**      | `:8090` (JSON-RPC 2.0 endpoint)                                |
| **Protocol**  | `message/send`, `message/stream`, `tasks/get`, `tasks/cancel`  |
| **State**     | Valkey-backed task store with SETNX idempotency                |
| **Discovery** | Serves Agent Card at `/.well-known/agent.json` via Envoy route |

### 4. PID Mapper

Maps container PIDs to host PIDs for per-process SPIFFE identity.

| Property     | Value                                                                     |
| ------------ | ------------------------------------------------------------------------- |
| **Requires** | `hostPID: true` on the Pod spec                                           |
| **Reads**    | `/tmp/hexr-context/` — marker files written by agent process              |
| **Writes**   | `/host-hexr-context/` — context JSON with host PIDs for SPIRE attestation |

<Steps>
  <Step title="Agent writes marker" icon="pen">
    When the agent process starts, the SDK writes a marker file to `/tmp/hexr-context/`:

    ```json theme={null}
    {"agent_name": "content-crew", "tenant": "acme-corp", "role": "researcher", "container_pid": 42}
    ```
  </Step>

  <Step title="PID Mapper translates" icon="arrows-rotate">
    The PID Mapper reads `/proc` to map the container PID (42) to the host PID (83721).
    Writes the enriched JSON to `/host-hexr-context/`.
  </Step>

  <Step title="File Collector forwards" icon="share-from-square">
    The File Collector DaemonSet reads from the hostPath volume and forwards the context
    to the Auto-Registrar via gRPC.
  </Step>

  <Step title="Auto-Registrar creates entry" icon="id-card">
    The Auto-Registrar calls SPIRE Server's `CreateEntry` API with per-process selectors
    (`k8s:pod-uid`, `hexr:process-role`).
  </Step>

  <Step title="SVID issued" icon="certificate">
    The agent process fetches its X.509-SVID from the SPIRE Workload API, receiving a
    certificate with its per-process SPIFFE ID.
  </Step>
</Steps>

***

## Shared Volumes

Three volumes connect the containers:

| Volume               | Mount Path            | Purpose                                                                      |
| -------------------- | --------------------- | ---------------------------------------------------------------------------- |
| `spire-agent-socket` | `/run/spire/sockets/` | SPIRE Workload API socket. Agent + Envoy use this for SVID requests.         |
| `hexr-context`       | `/tmp/hexr-context/`  | Agent writes process identity markers. PID Mapper reads them.                |
| `host-hexr-context`  | `/host-hexr-context/` | PID Mapper writes host-PID-enriched context. File Collector reads from host. |

***

## Init Container

Before the main containers start, an init container installs the Hexr SDK:

```yaml theme={null}
initContainers:
  - name: install-hexr-sdk
    image: python:3.11-slim
    command: ["pip", "install", "--target=/shared/site-packages", "hexr"]
    env:
      - name: PIP_INDEX_URL
        value: "https://pypi.hexr.cloud/simple/"  # Private PyPI
    volumeMounts:
      - name: shared-packages
        mountPath: /shared/site-packages
```

This ensures the SDK version matches what was used during `hexr build`, regardless of what's baked into the agent image.

***

## Network Flow

How a `hexr_tool("aws_s3")` call flows through the pod:

<Steps>
  <Step title="Agent calls hexr_tool('aws_s3')" icon="code">
    SDK checks L1 in-memory cache, then L2 Valkey cache. Both miss.
  </Step>

  <Step title="Agent → Envoy (localhost)" icon="arrow-right">
    Agent sends `POST /exchange` to the Envoy sidecar over localhost (plaintext, same pod).
  </Step>

  <Step title="Envoy → Credential Injector (mTLS)" icon="lock">
    Envoy initiates **mutual TLS** to the Credential Injector in `hexr-system`,
    attaching the agent's X.509-SVID as the client certificate.
  </Step>

  <Step title="Credential Injector verifies + checks OPA" icon="shield-check">
    CI verifies the JWT-SVID via SPIRE Workload API, then queries OPA:
    "Can this SPIFFE ID access `aws_s3`?"
  </Step>

  <Step title="STS exchange" icon="right-left">
    CI calls `AssumeRoleWithWebIdentity` on AWS STS, presenting the JWT-SVID
    as the web identity token. AWS trusts Hexr's OIDC endpoint.
  </Step>

  <Step title="Credentials returned + cached" icon="key">
    Temporary AWS credentials (15min TTL) flow back through Envoy to the agent.
    Stored in L1 + L2 cache. SDK creates an authenticated `boto3` S3 client.
  </Step>
</Steps>

Subsequent calls hit the **L1 in-memory cache** (\~0.001ms) or **L2 Valkey cache** (\~1-3ms), avoiding the full exchange round-trip.
