Two Kinds of Agents github

agent_

The textbook · 1995

“Autonomous, reactive, pro-active, and socially able.”

— Wooldridge & Jennings, back when the word had a spec

The vendor · 2026

“Agentic AI leverages autonomous agents to agentically transform agency.”

— every keynote, verbatim, simultaneously

The engineer · honestly

“A while-loop with an LLM and some tools in it.”

— anyone who has read the source

A NASA-grade agent, 1999

The Remote Agent Experiment · Deep Space 1

Artist's rendering of the Deep Space 1 spacecraft with its ion engine firing
Deep Space 1 · NASA/JPL
  • Built1996–98 Planner + Executive + a diagnosis engine (Livingstone). Model-based, in Common Lisp — 32 MB, 25 MHz, radiation-hardened.
  • Tested×3,000 3,000 ground runs + formal model checking before it earned command.
  • FlewMay 1999 29 hours in sole command of the spacecraft, tens of millions of miles out. First AI to command a spacecraft.
  • Attacked4 for 4 Mission control injected four failures — stuck camera, dead electronics, lying sensor, stuck thruster. Diagnosed and re-planned around every one.
  • Surprised1 real bug A thread deadlock that 3,000 ground runs never hit — the ion engine wouldn’t shut off. Debugged across the solar system; 100% of objectives met.
NASA Software of the Year 1999 Lisp, in space “It would have taken the ground team days”
B.C.before ChatGPT

ran a spacecraft on 25 MHz · 32 MB · ~15 W · 0 L of water

A.D.after Dario

one 1M-token call ~0.4 kWh · ~1 L of water

napkin math: 15 W × 29 h ≈ 0.4 kWh — one 1M-token call ≈ RAX’s entire mission.

The RAX stack · four load-bearing facts

01 · plans from a model

The Planner reasons over a physics model of the craft — every plan is explainable before it runs.

02 · executes under watch

The Executive monitors every step against expectations — no step succeeds on vibes.

03 · diagnoses from first principles

Livingstone infers which component failed and reconfigures around it — it knows why, not just that.

04 · verified before trusted

3,000 ground runs + formal model checking, then command authority — trust was earned, in that order.

Retro browser mock: a 'Google Console' terminal where an agent offers deployment options and the button below the prompt reads I'm Feeling Lucky
plans from a prayer · executes unsupervised · diagnoses nothing · trusted before verified

What agents look like for me

this morning · 10:36

A Claude Code terminal with a tmux session switcher listing nine agent sessions — ansible, nvidia, vault, sbom, wazu and more — with bypass permissions on
9 tmux sessions of Claude Code bypass permissions: on

Nine vibe agents. Full permissions. 1× self-hosted server.
This is why the rest of the talk exists.

The Red Hat Agentic Story

AgentOps · from pilot to production

Everyone is doing it

80%of the Fortune 500 run active agents in production today
40%of enterprise apps will embed agents by end of 2026 — up from <5% in 2025
81%of technical teams are already past the planning phase

Almost nobody is governing it

21%have a mature agent-governance model
14.4%of agent fleets have full security approval
1.5Munmonitored corporate agents — 29% of employees run shadow agents outside IT
45.6%still authenticate agents with shared API keys

source: “The Red Hat Agentic Story” deck · CY2026 industry surveys

Pillar 01 · identity

Kill the API key.

Short-lived SPIFFE/SPIRE certificates give every agent its own verifiable identity — per-agent authorization and tool governance through an MCP gateway.

↳ live demo: The Keys · The Identity

Pillar 02 · agent core

Bring your own agent.

Framework-agnostic operationalization: kernel-isolated sandboxes for safe execution, and deep tracing of every LLM call, tool execution, and decision step.

↳ live demo: The Box

Pillar 03 · inference

Survive the spikes.

Multi-agent systems spike inference unpredictably — vLLM for throughput, llm-d for dynamic scaling across the hybrid cloud.

↳ live demo: The Fleet

Highly operational, highly vulnerable — the industry shipped the vibe agent first. AgentOps is the box around the surprise.

Where does OpenShell come in?

source: “Validated Sandbox Images for OpenShell and Agent Runtimes”

The upstream runtime, redrawn

after the community architecture diagram

K8s in Docker zero K8s setup OPENSHELL RUNTIME upstream · community GATEWAY Log streaming follow output Cred injection server-side keys gRPC + HTTP API the front door EXECUTION PLANE Agent sandbox 1 Agent sandbox 2 Agent sandbox N POLICY ENFORCEMENT Static policy Landlock + seccomp BPF Dynamic: OPA rules hot-reload SSRF protection PRIVACY ROUTER Hostname matching Credential stripping Route decision Local Nemotron on-prem · sensitive Cloud LLMs GPT, Claude — non-sensitive

Action / inference flow Hosting · sensitive route

The proposal · and how I run it

The proposal · quick facts

  • Todayupstream Community base image is a 2.81 GB monolith (1.4 GB compressed) — every agent CLI and toolchain baked in. Slow cold-starts, licensing risk, no validation.
  • Thin base150–200 MB UBI 10-minimal + OpenShell supervisor and entrypoint. Nothing else.
  • Flavors300–450 MB Base + just the runtime (Node.js / Python). Proprietary agents like Claude Code are installed at runtime, never redistributed.
  • Universalone contract podman run is first-class; identical with or without the OpenShell CLI — same users, same /etc/openshell/policy.yaml.
  • ValidatedKonflux Built in Red Hat’s pipeline, ships an SBOM; offered upstream as an additive alternative — fat base for convenience, thin flavors for production.

How I run it today · securer by policy

  • Runtimelive Native OpenShell sandboxes on OpenShift — the supervisor manages the agent’s lifecycle inside each sandbox.
  • No keysSPIFFE The sandbox holds only its SVID via the CSI socket — ANTHROPIC_API_KEY is a placeholder; the identity is the credential.
  • NetPoldefault-deny Kyverno drops a default-deny (ingress + egress) into every namespace; the agent’s only egress allow is the model gateway pod — going around it is refused at the wire.
  • Kyvernoadmission Mutation policies harden each sandbox as it’s created — capabilities granted per pod, by policy, not by hand.
  • IsolationKata Stage A landed: the same sandbox boots inside a qemu-kvm micro-VM — a kernel boundary around the agent. And the SVID is now proven inside it (nested SPIRE, 2026-07-23).
  • Writesgated Every dangerous tool call is 403 until a second human approves — JIT, single-use, WORM-audited.

Demo 1: Claude Code with no API key

MaaS · the SVID is the model credential

  • 01delete the key Claude Code launches with a placeholder ANTHROPIC_API_KEY and one mounted volume: the SPIFFE CSI socket. There is no model key to steal.
  • 02borrow identity A loopback proxy (127.0.0.1:8787) strips the fake key and swaps in a fresh, short-lived JWT-SVID on every call.
  • 03the gate The Istio maas-gateway asks Authorino to validate the SVID against SPIRE-OIDC; OPA authorizes the sandbox subject. It checks who you are, not what you carry.
  • 04server-side key Past the gate, llm-proxy injects the real OpenRouter key from Vault and calls Anthropic. The provider credential never crosses to the agent’s side.
no token → 401 SVID → 200 · real completion “P1_BRAIN_OK” · proven 7/7

This is how I got it to work — not necessarily the best way. Just an idea.

AGENT SANDBOX no API key anywhere Claude Code CLI the agent brain KEY=placeholder maas_brain_proxy 127.0.0.1:8787 custom SPIFFE CSI socket the only credential supported MAAS GATEWAY — THE DOOR Authorino + OPA verify SVID vs SPIRE-OIDC sub ~ /sandbox/.+ supported · custom rego maas-gateway (Istio) Gateway API · ext-authz /openrouter supported 401 — refused NS MAAS Vault provider key, server-side external llm-proxy strips identity headers injects the real key custom OpenRouter sonnet-4.5 external P1_BRAIN_OK

Model plane Identity plane Refused custom = built here · supported = product, configured · external = provider

Demo 2: the agent acts as you

split identity · consent is the switch

  • 01two identities The agent authenticates as itself — a workload SVID. The human authorizes through a consent grant in Vault. The two are never conflated.
  • 02read as you Read-only grant → the per-user READ token is injected downstream. pfSense sees the human, not a bot — and returns real rules. 200.
  • 03refused by consent The same agent tries a write: 403 grant_scope_denied. The deny is a first-class receipt with a reason — never a silent drop.
  • 04flip the grant A human edits the same grant to read-write — no redeploy, no restart. The next write lands a REAL firewall rule, read straight back out. Every action leaves a receipt that names a person.
read 200 → write 403 → flip → write 200 real rule p2rw-2406927 · read back · re-proven 2026-07-23 receipts in Loki · no secrets in the log
Human — arsalan the consent holder approves scope Vault consent grant sandbox-grants/<uuid> scope: read-only external Agent sandbox holds only its SVID …/sandbox/<uuid> agentgateway MCP front door supported ext-proc-delegation verify · grant · token pick GRANT_SCOPE_ELEVATES=true custom pfSense firewall sees the HUMAN, not a bot real rules external read token per-user write token fail-closed 403 grant_scope_denied rule p2rw-2406927 · read back Loki / Grafana — the receipt external read · write_identity=false · arsalan write · write_identity=true · jit=false deny · grant_scope_denied · reason set

Tool & consent plane Identity / grant / receipt Denied custom = built here · supported = product, configured · external = provider

Demo 3: The Box — Confidential Containers × zero trust

A credential-less agent, sealed in a micro-VM · no key · delegated · human-approved

  • 01the stakes An autonomous agent runs shell commands nobody previewed. Escape the container and it doesn’t own a pod — it owns the node. Confidential Containers put a hardware wall around it.
  • 02confidential box Live 2026-07-22: a worker became a real Kata node (readyNodeCount=1) and a runtimeClassName: kata pod boots in a genuine qemu-kvm micro-VM — its own kernel, KVM isolation. Escape the container and you’re still trapped in the VM.
  • 03the boundary Inside, the guest sees only ~2 GiB — its VM allocation — not the host’s ~64 GiB. A runc container reads the host’s full memory. That gap is the hardware boundary.
  • 04identity inside The SVID-delivery socket can’t cross the VM boundary — so a nested SPIRE agent inside the guest node-attests over TCP and mints the SVID on an in-guest socket. No host socket is forwarded: the credential is born inside the box.
  • 05the trick A one-time door: pause the SPIRE operator, enable the join_token attestor, let the in-guest agent introduce itself over plain TCP, close the door. The running agent then renews against its datastore record — attestation is only needed for first introductions — which is why the pod must never restart until the operator grows the knob.
  • 06no key · your hands The whole zero-trust loop runs inside the VM (re-proven live 2026-07-23): Claude Code runs with no API key — its brain reaches the model only through its SVID; a delegated read returns real pfSense rules as the human (caller_username=arsalan); a write is gated 403 until a human approves, then a single-use capability lets it land. No key, no user token, no downstream secret — only the SVID.
  • 07what’s in the box The agent’s behavior is provisioned, not prompted: on-disk skills teach it the tools (pfsense-firewall, github…), the mcp-call helper is its only hand, and a CLAUDE.md memory file tells it who it is — credential-less, firewall means pfSense, a silent wait means a human is approving. All of it versioned in git, baked into the image, and re-synced into the container at session start.
  • 08openshell in coco 2026-07-23: the native OpenShell supervisor — not just a stand-in agent — now boots inside the Kata micro-VM. Its confined-network veth and identity mount-namespace were the two guest-kernel walls; both fixed. The runtime itself lives in Confidential Containers.
  • 09honest caveat The SPIRE operator’s CR has no field for the extra node attestor (patched out-of-band; a restart would fail re-attestation), and wiring the in-guest SVID into the supervisor sandbox is the last mile. The blockers are operator APIs, not Kata. Memory confidentiality from the host is Stage C (TEE).
kata micro-VM · guest 2 GiB vs host 64 GiB no key · delegated read · human-approved write — all inside the VM OpenShell supervisor boots in the box · 2026-07-23
WORKER NODE — ocp-dev shared kernel · RHCOS e2e-harness pod the runc before-state runtimeClassName: none Kata micro-VM (QEMU/KVM) agent pod · rtc: kata guest kernel ≠ host nested SPIRE — SVID minted runc canary same panic script node + siblings Ready canary pod lost read 200 from in-guest blocked at the VM boundary no-key brain · SVID→MaaS 200 write · 403 → approve → 200 OpenShell supervisor: boots in the VM OSC OPERATOR — CONTROL sandboxed-containers v1.13.0 supported Red Hat operator supported KataConfig cluster-kataconfig ready kata nodes: 0 selector: master → worker pool supported SPIRE Workload API (CSI) SVID delivery supported STAGE B / C — PLANNED peer-pods · TEE attestation peer-pod VM · kata-remote sibling VM on the hypervisor Trustee / KBS attestation challenge → evidence → policy EAR token Vault secret held until attested external secret released

Control / enrollment Identity & attestation Failure / blocked dashed = planned / not yet live custom = built here · supported = product, configured · external = provider

questions?_

This is one opinion, built from the tools we already have — and real work is still required to make it all click together. So tell me: what else can we cook up?

companion to the “what even is an agent?” deck · aegis zero-trust agentic platform · the two-kinds field guide →