Skip to main content
When you run hexr deploy, Hexr doesn’t just schedule your Python code on Kubernetes — it builds a complete, secured runtime around it. Your agent becomes a pod with four containers, each with a specific role: your code, a mutual TLS proxy, an agent communication handler, and a process identity mapper. Together they give your agent cryptographic identity, encrypted networking, and agent-to-agent communication without any extra code from you.

Pod structure

Init: install-hexr-sdk

Before your agent starts, an init container installs the Hexr SDK from the private PyPI registry into a shared volume. This ensures the SDK version always matches what was used during hexr build, regardless of what’s in your container image.

agent container

Your Python code. Runs your @hexr_agent-decorated function. Handles inbound A2A bridge calls and connects to the SPIRE Workload API to fetch its SVID.

envoy-sidecar

Your mTLS proxy. Handles all inbound and outbound TLS. Loads X.509-SVIDs directly from SPIRE. All traffic in and out of your pod goes through this container — you never manage certificates yourself.

a2a-sidecar

Agent communication. Implements the Agent-to-Agent protocol with JSON-RPC 2.0 dispatch — message/send, message/stream, tasks/get, tasks/cancel. Task state is persisted so tasks survive restarts.

pid-mapper · hostPID: true

Your identity mapper. Reads /proc to map container PIDs to host PIDs, then writes enriched process context JSON that SPIRE uses for workload attestation. This is what enables per-process SPIFFE identities — one identity per agent role, not one per pod.

Container details

1. Agent container

Your Python code with the Hexr SDK. This is the only container you write code for — everything else is generated and managed by Hexr.
PropertyValue
VolumesSPIRE socket, hexr-context, shared site-packages
Env varsHEXR_FRAMEWORK, HEXR_TENANT, HEXR_AGENT_NAME (all set by hexr deploy)
# 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 automatically
    # ... your agent logic

2. Envoy sidecar

Transparent mTLS proxy. Handles all network traffic in and out of the pod — your agent code sends and receives plain HTTP on localhost while Envoy handles the encryption boundary.
PropertyValue
Inbound:15006 — terminates TLS, forwards plain HTTP to agent or A2A sidecar
Outbound:15001 — initiates mTLS to other pods and platform services
CertificatesX.509-SVID loaded from SPIRE via SDS (Secret Discovery Service)
Routes/.well-known/* → Agent Card ConfigMap, /a2a → A2A sidecar
Your agent never handles TLS certificates directly. Envoy fetches them from SPIRE automatically, rotates them without downtime, and presents them on every outbound connection.

3. A2A sidecar

Implements the Agent-to-Agent protocol so your agents can call other Hexr agents by name over authenticated, encrypted connections.
PropertyValue
Protocolmessage/send, message/stream, tasks/get, tasks/cancel (JSON-RPC 2.0)
StateTasks persisted with idempotent creation so duplicates are safe
DiscoveryServes the Agent Card at /.well-known/agent.json

4. PID mapper

Maps container PIDs to host PIDs so SPIRE can issue a unique SPIFFE identity to each agent process — not just the pod as a whole.
PropertyValue
RequireshostPID: true on the pod spec
Reads/tmp/hexr-context/ — marker files written by your agent process
Writes/host-hexr-context/ — context JSON with host PIDs for SPIRE attestation
How the identity is established at startup:

Agent writes marker

When your agent process starts, the SDK writes a marker file to /tmp/hexr-context/:
{"agent_name": "content-crew", "tenant": "acme-corp", "role": "researcher", "container_pid": 42}

PID Mapper translates

The PID Mapper reads /proc to map the container PID (42) to the host PID (83721) and writes the enriched JSON to /host-hexr-context/.

File Collector forwards

The File Collector DaemonSet reads from the hostPath volume and forwards the context to the Auto-Registrar over gRPC.

Auto-Registrar creates entry

The Auto-Registrar calls SPIRE Server’s CreateEntry API with per-process selectors (k8s:pod-uid, hexr:process-role).

SVID issued

Your agent process fetches its X.509-SVID from the SPIRE Workload API, receiving a certificate with its per-process SPIFFE ID — valid for 1 hour and automatically renewed.

Init container

Before any main container starts, the init container installs the Hexr SDK into a shared volume:
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 always matches what was used during hexr build, regardless of what’s baked into your agent image.

How a tool call flows through the pod

When your code calls hexr_tool("aws_s3"), here’s the complete path through the pod:

Agent calls hexr_tool('aws_s3')

The SDK checks the L1 in-memory cache, then the L2 Valkey cache. Both miss on first call.

Agent → Envoy (localhost)

The agent sends POST /exchange to the Envoy sidecar over localhost — plain HTTP within the pod.

Envoy → Credential Injector (mTLS)

Envoy initiates mutual TLS to the Credential Injector service, attaching your agent’s X.509-SVID as the client certificate.

Credential Injector verifies + checks OPA

The Credential Injector verifies your JWT-SVID via the SPIRE Workload API, then asks OPA: “Can this SPIFFE ID access aws_s3?”

STS exchange

The Credential Injector calls AssumeRoleWithWebIdentity on AWS STS, presenting your JWT-SVID as the web identity token. AWS trusts Hexr’s OIDC endpoint.

Credentials returned + cached

Temporary AWS credentials (15-minute TTL) flow back through Envoy to your agent and are stored in L1 and L2 cache. The SDK creates and returns an authenticated boto3 S3 client.
Subsequent calls to the same service hit the L1 in-memory cache (~0.001ms) or L2 Valkey cache (~1-3ms), skipping the full exchange entirely.