Back to Blog
Sessions 2026-02-10

API Session Recording

How iddio captures full HTTP request/response bodies for forensic replay. Agent-grouped sessions, idle timeout boundaries, configurable body size limits, and automatic secrets redaction.

Beyond Exec Sessions

Iddio’s exec session recording captures the raw byte stream of kubectl exec and kubectl attach sessions — the keystrokes and terminal output of interactive container access. That covers one important category of AI agent activity, but not the majority of it. Most of what an agent does — listing pods, reading ConfigMaps, creating Deployments, patching Services — happens through ordinary HTTP requests, not protocol upgrades.

API session recording fills this gap. It captures the structured request and response bodies of every non-upgrade Kubernetes API call, groups them into sessions by agent, and persists them to disk. You get a reviewable record of everything an agent read or wrote during a working session, not just the audit log’s one-line-per-request summary.

The two systems are designed to be complementary: exec sessions capture the “what did it type” dimension; API sessions capture the “what did it read and write” dimension. Both link to the same hash-chained audit log.

Session Grouping by Idle Timeout

API requests from an agent don’t have explicit session boundaries like exec does (connect/disconnect). Instead, iddio uses an idle timeout to define session boundaries:

  1. An agent’s first request starts a new session
  2. Each subsequent request from that agent extends the session
  3. If no request arrives within the idle timeout (default: 5 minutes), the session is closed and persisted
  4. The next request from that agent starts a new session

This naturally groups related activity. An agent debugging a production issue might make 50 requests over 10 minutes — that’s one session. If it goes quiet for 5 minutes and then comes back for a different task, that’s a new session.

Request/Response Body Capture

The proxy captures bodies using a tee reader pattern — the body is read once and both forwarded to the upstream cluster and saved to the session:

func (p *Proxy) captureRequestBody(r *http.Request, session *APISession) {
    if r.Body == nil {
        return
    }

    limited := io.LimitReader(r.Body, p.maxBodySize)
    body, _ := io.ReadAll(limited)
    r.Body = io.NopCloser(bytes.NewReader(body))

    session.RecordRequest(r, body)
}

Response bodies are captured similarly, using a TeeReader that streams to both the client and the session recorder simultaneously — no buffering the entire response in memory.

Secrets Redaction

Response bodies containing Kubernetes Secrets are automatically redacted. The recorder detects Secret resources by API path (/api/v1/namespaces/*/secrets/*) and replaces the data field values with [REDACTED]:

{
  "apiVersion": "v1",
  "kind": "Secret",
  "metadata": { "name": "db-creds", "namespace": "payments" },
  "data": {
    "password": "[REDACTED]",
    "username": "[REDACTED]"
  }
}

This ensures that session recordings don’t become a secondary secrets store. The audit log records that the secret was accessed (as a T3 sensitive event), but the actual secret values are never persisted in the session file.

Configurable Body Size Limits

Bodies are captured up to a configurable maximum:

sessions:
  api:
    enabled: true
    idle_timeout: 5m
    max_body_size: 1MB
    redact_secrets: true
    storage: ~/.iddio/sessions/

Bodies larger than max_body_size are truncated with a [TRUNCATED at 1MB] marker. This prevents a kubectl get pods -o json response on a large cluster from consuming excessive disk space.

Session File Format

API sessions are stored as JSONL files with one entry per request/response pair:

{
  "timestamp": "2026-02-10T14:30:22.001Z",
  "method": "GET",
  "path": "/api/v1/namespaces/payments/pods",
  "tier": 0,
  "status": 200,
  "request_body": null,
  "response_body_size": 4821,
  "response_body": "{\"apiVersion\":\"v1\",\"items\":[...]}",
  "latency_us": 1200
}

Each entry captures the full request-response cycle. The session file gives a complete narrative of the agent’s interaction with the cluster.

Contrast with Exec Sessions

Exec SessionsAPI Sessions
TriggerHTTP 101 Upgrade (exec/attach)Every non-upgrade HTTP request
Unit of captureRaw byte stream (stdin/stdout)Structured request + response JSON
GroupingOne session per exec/attach callMany requests grouped by idle timeout
Secrets handlingN/A (raw bytes)Automatic redaction
ReplayTerminal replay with timingRequest log viewer
Typical sizeKBs to MBs per sessionKBs to tens of MBs per session

Try It Yourself

Iddio is open source. Deploy a zero-trust command proxy for your AI agents in minutes.