Skip to main content

Agent Runtime

This page describes the contract between CodeNOW and a deployed agent: what CodeNOW gives the agent at deploy time, and what an agent — and therefore an agent template — must do with it. CodeNOW composes all addresses; an agent never builds gateway paths or identity-provider URLs itself.

Where the agent runs​

  • Every exposed agent is registered in the account's Agent Gateway at https://agent-gateway.<data plane host>/agents/<swarmId>/<environmentId>/<agentId>. The gateway strips this prefix — the agent serves at its root (/).
  • The gateway authenticates every inbound call (CodeNOW token, account membership, the agent's allowed callers) and forwards the caller's token unchanged. The agent does not need to validate the token's audience again; the caller's identity is in the token (preferred_username, cn_teams) if the agent needs it.

Environment variables​

VariableWhenMeaning
AI_GATEWAY_URLalwaysAgent Gateway origin for outbound calls — models, MCP servers, other agents
AI_GATEWAY_REFRESH_TOKENalwaysRefresh token of the agent's service account; stable across redeploys, revoked on undeploy
OIDC_ISSUER_URLalwayshttps://<IAM host>/auth/realms/codenow
OIDC_CLIENT_IDalways<accountId>-ai-agents — public client (no secret) used for the refresh-token grant and the admin console sign-in
OIDC_REDIRECT_HOSTagent has an external endpointOrigin of the agent's external URL; the console sign-in callback is https://<OIDC_REDIRECT_HOST>/auth/callback
CONSOLE_ALLOWED_USERSlist not emptyComma-separated users allowed into the admin console
CONSOLE_ALLOWED_TEAMSlist not emptyComma-separated team names allowed into the admin console
AGENT_PUBLIC_URLagent is exposedThe agent's own URL through the gateway (for its agent card)
<NAME>_A2A_URLper connected agentURL of another agent this agent may call
A2A_AGENTSalways ({} without peers)JSON object {"<NAME>": "<url>"} of all connected agents, sorted by name
service account secretsas configuredEach environment secret of the service account under its own name; it overrides a component environment variable of the same name
CN_*alwaysCodeNOW Context Variables — for agents without CN_PACKAGE_VERSION

NAME is the connected agent's runtime name in upper case, every character other than A-Z and 0-9 replaced by _, prefixed with AGENT_ if it does not start with a letter (order-planner → ORDER_PLANNER_A2A_URL).

Reserved names — set by CodeNOW, so a service-account secret cannot use them (saving it is refused; see Reserved names): names starting with AI_GATEWAY_, OIDC_, CONSOLE_, CN_ or CODENOW_, the names A2A_AGENTS and AGENT_PUBLIC_URL, and names ending with _A2A_URL. Names are case-sensitive and upper-case. OIDC_CLIENT_SECRET is never set.

Identity and outbound calls​

  • Obtain an access token with the refresh-token grant at OIDC_ISSUER_URL (client_id = OIDC_CLIENT_ID, refresh_token = AI_GATEWAY_REFRESH_TOKEN). Access tokens are valid for 10 minutes — refresh them before they expire.
  • Use one token source for all outbound calls through the gateway (models, MCP servers, other agents) as Authorization: Bearer <token>.
  • The agent can do only what its service account is allowed to do.

A2A​

Calling other agents​

  • Read A2A_AGENTS at startup. If it is missing or invalid, run without peers and log it — don't fail.
  • Fetch peers' agent cards (<url>/.well-known/agent.json) lazily, cache them and refresh on failure.
  • A peer may not be deployed yet: its URL is set, but the gateway answers 404/503 until it is. Treat it as temporarily unavailable (timeouts, retries with backoff); never fail startup.
  • 401/403 means a configuration or permission problem (for example the peer restricts its callers) — log it clearly, don't retry in a loop.
  • Use the URLs as given; never compose gateway paths.

Being called​

  • Serve A2A at the root and the agent card at GET /.well-known/agent.json without authentication.
  • The card's url is AGENT_PUBLIC_URL, or https://<OIDC_REDIRECT_HOST> when the agent is not exposed. Its security scheme is bearer / OIDC at OIDC_ISSUER_URL.
  • Callers are already authenticated and authorized by the gateway (account membership and the agent's allowed callers).

Admin console​

If the agent template has an admin console:

  • Sign users in with OpenID Connect: issuer OIDC_ISSUER_URL, client OIDC_CLIENT_ID, redirect URI https://<OIDC_REDIRECT_HOST>/auth/callback. CodeNOW registers the redirect URI on the client when the agent is deployed and removes it on undeploy.
  • The console must send a PKCE challenge (S256). The <accountId>-ai-agents client is public and requires PKCE; a sign-in without it is rejected.
  • Authorize against CONSOLE_ALLOWED_USERS / CONSOLE_ALLOWED_TEAMS using the signed-in user's token (preferred_username, cn_teams). When both variables are absent, CodeNOW enforces nothing — the template defines and documents what the console allows then.

Lifecycle​

EventWhat CodeNOW does
DeployComposes the environment, registers the agent in the gateway (if exposed), adds the console redirect URI, issues or reuses the service-account token
RedeployRecomposes everything; changes of peers, allowed callers and A2A connections take effect
UndeployRemoves the gateway registration and the redirect URI, revokes the token

Checklist for agent templates​

  • Refresh-token flow and one token source for all outbound gateway calls
  • Model and MCP calls through AI_GATEWAY_URL
  • A2A server at / and an unauthenticated agent card with url = AGENT_PUBLIC_URL (fallback: direct URL)
  • A2A client using A2A_AGENTS / <NAME>_A2A_URL, lazy agent cards, resilient to 404/503, logging 401/403
  • Admin console (optional): OIDC sign-in with PKCE (S256), CONSOLE_ALLOWED_*, documented behaviour for empty lists
  • Ships .codenow.config.yaml with the agentGateway defaults (see Default Configuration)
  • The generated agent's README documents all variables above