Expand description
§ironflow-auth-proxy
HTTP service that keeps the Claude credential out of ironflow agent pods.
The worker (K8sEphemeralProvider::auth_proxy) asks the admin API for an
opaque token bound to one run and one step, and hands only that token to
the pod. Claude Code sends it as Authorization: Bearer to this proxy,
which swaps it for the real credential and relays the request to
api.anthropic.com, streaming the answer back.
One listener serves:
GET /healthz- liveness;/admin/v1/...- token issuance and revocation, behindAuthorization: Bearer <IRONFLOW_AUTH_PROXY_ADMIN_KEY>;- anything else - the relay: an unknown, expired or revoked token gets a
401, a path outside
/v1/or a request for another host a 403, a method other than GET/POST a 405.
Grants live in a registry with two backends:
- in memory (default): a single replica, tokens lost on restart;
- PostgreSQL, when
DATABASE_URL_ENVis set (registry_from_config): shared by several replicas and surviving restarts. Only the token SHA-256 is stored, never the token, and the credential is AES-256-GCM encrypted at rest with theIRONFLOW_SECRET_KEYSkey ring.
Logs never contain a token or a credential, only the short token id.
§Examples
use std::env::var;
use std::time::Duration;
use ironflow_auth_proxy::{
AuthProxyConfig, AuthProxyState, DATABASE_URL_ENV, registry_from_config, serve, spawn_purge,
};
use ironflow_store::crypto::KeyRing;
use tokio::net::TcpListener;
let database_url = var(DATABASE_URL_ENV).ok();
let registry = registry_from_config(database_url.as_deref(), KeyRing::from_env()?).await?;
let config = AuthProxyConfig::new("0123456789abcdef0123456789abcdef");
let state = AuthProxyState::with_registry(config, registry)?;
let purge = spawn_purge(state.registry().clone(), Duration::from_secs(60));
let listener = TcpListener::bind("0.0.0.0:8080").await?;
serve(listener, state).await?;
purge.abort();Structs§
- Auth
Proxy Config - Configuration of the proxy. Its
Debugoutput never shows the admin key. - Auth
Proxy State - Shared state of the proxy: the token registry, the configuration and the upstream HTTP client. Cheap to clone.
Enums§
- Registry
Config Error - Why the token registry could not be built. No variant carries the database URL, a key or a credential.
Constants§
- DATABASE_
URL_ ENV - Environment variable holding the PostgreSQL URL of the shared token registry. Unset (or empty), tokens live in memory.
- DEFAULT_
MAX_ BODY_ BYTES - Default largest request body relayed: 32 MiB.
- MIN_
ADMIN_ KEY_ LEN - Shortest admin key accepted.
Functions§
- registry_
from_ config - Build the token registry: in memory when
database_urlisNoneor blank, otherwise shared in PostgreSQL, the credentials encrypted withkey_ring. Opening the database runs the store migrations. - router
- The proxy router: health, admin API and relay.
- serve
- Serve the proxy on
listeneruntil ctrl-c or SIGTERM, letting in-flight requests finish. - spawn_
purge - Spawn a task dropping the expired grants of
registryeveryinterval.