Architecture¶
RunAgents processes every agent interaction through three stages: Ingress, Runtime, and Egress. Together, they ensure that user identity, access policy, and credentials are handled transparently — so you can focus on writing agent logic, not security plumbing.
The user-facing interface can live anywhere. The same governed agent runtime can sit behind:
- a web application
- WhatsApp or another messaging surface
- Slack or an internal chat surface
- an internal operations portal
- a custom mobile or desktop client
RunAgents handles execution, identity propagation, policy enforcement, approvals, and outbound tool security no matter which surface initiated the request.
flowchart LR
client["Client Application"]
idp["Identity Provider<br/>(OIDC/JWKS)"]
ingress["RunAgents Ingress"]
runtime["Agent Runtime"]
llm["LLM Gateway"]
egress["Policy & Egress Layer"]
model["Model Provider APIs<br/>(OpenAI, Anthropic, Bedrock, ...)"]
tools["External Tool APIs<br/>(Stripe, Slack, GitHub, ...)"]
client -->|"JWT"| ingress
ingress -.->|"Validate signature & claims"| idp
ingress -->|"X-End-User-ID"| runtime
runtime -->|"Model requests"| llm
runtime -->|"Tool requests"| egress
llm --> model
egress --> tools Stage 1: Ingress (Client to Agent)¶
Client applications authenticate users via JWT. The client surface can be anything from a traditional web app to WhatsApp, Slack, or a custom internal UI. When a request reaches RunAgents, the platform:
- Validates the JWT -- Signature is verified against the identity provider's JWKS endpoint. Audience and issuer claims are checked.
- Extracts user identity -- A configurable claim (e.g.,
email,sub) is pulled from the token payload. - Injects the identity header -- The extracted value is set as
X-End-User-IDon all requests forwarded to the agent. - Enforces domain-level access -- Only client applications from allowed domains can reach the agent.
No tokens in agent code
Your agent never sees the raw JWT. It receives the verified user identity as a simple HTTP header. This prevents token leakage and removes the need for JWT libraries in your agent code.
Stage 2: Runtime (Agent Executes)¶
Once the request reaches the agent, it runs with everything it needs already injected:
| Injected Resource | How It Works |
|---|---|
| System prompt | Loaded from agent configuration; available to the agent at startup |
| Tool URLs | Each required tool is exposed as an environment variable (e.g., TOOL_STRIPE_URL) |
| LLM Gateway URL | A single endpoint for all model inference, regardless of provider |
| Model settings | Model name and provider per role (e.g., LLM_MODEL_DEFAULT, LLM_PROVIDER_DEFAULT) |
The agent calls tools at their registered URLs and the LLM gateway for model inference. No API keys appear in agent code -- the platform manages all credentials.
Write code, not configuration
From your agent's perspective, calling a tool is a standard HTTP request to a URL. RunAgents intercepts the call on the way out and handles authentication, authorization, and identity forwarding.
Stage 3: Egress (Agent to Tool)¶
Every outbound call from an agent is intercepted by the platform's security mesh. The platform performs the following checks on each request:
1. Tool Identification¶
The platform matches the destination host against registered tools. If the host is not recognized, the request is blocked.
2. Agent Identity Verification¶
The agent's service identity (a unique identifier per agent, separate from the end-user identity) is extracted and verified. This ensures the platform knows which agent is making the request.
3. Policy Evaluation¶
The platform evaluates bound policy rules for the agent ServiceAccount with precedence: deny > approval_required > allow > default deny.
- Allowed -- Proceed to the next step
- Approval required -- Create an access request, pause the run, return
APPROVAL_REQUIRED - Denied -- Return
403 Forbidden
4. Capability Enforcement¶
If the tool declares specific capabilities (method + path pairs), the platform verifies the request matches at least one:
GET /v1/chargeswith a capability forGET /v1/charges-- allowedDELETE /v1/chargeswith no matching capability -- blocked
If no capabilities are declared on the tool, all operations are allowed (passthrough).
5. Token Injection¶
For allowed requests, the platform injects the correct authentication credentials:
- API Key --
Authorization: Bearer <key>header added - OAuth2 -- Access token retrieved (or refreshed) and injected
- AWS Signature -- SigV4 signing applied
- No auth -- Request passed through as-is
6. Identity Forwarding¶
The X-End-User-ID header from Stage 1 is forwarded to the external tool, so the downstream API knows which user the agent is acting on behalf of.
The Developer Experience¶
From your perspective as a developer, the workflow is simple:
- Write agent code that calls URLs (tool endpoints and the LLM gateway)
- Deploy the agent via the console, API, or CLI
- RunAgents handles the rest -- identity propagation, policy enforcement, credential management, and approval workflows
You never write authentication logic, manage API keys in code, or implement policy checks. The platform does it all, transparently, on every request.
Key Design Principles¶
| Principle | Description |
|---|---|
| Zero-trust by default | No outbound request from an agent reaches an external service without policy evaluation |
| Identity at every hop | User identity flows from client to agent to tool, never lost or forged |
| Credentials never in code | API keys, OAuth tokens, and signing credentials are managed by the platform and injected at the egress layer |
| Least privilege | Agents only access tools they are explicitly bound to, with operation-level granularity |
| Human-in-the-loop | High-risk operations require explicit admin approval before the agent can proceed |
Next Steps¶
- Identity Propagation -- Deep dive into how user identity flows end-to-end
- Policy Model -- Understand how access control rules are structured and evaluated
- OAuth & Consent -- How RunAgents handles OAuth2 for tools that require user authorization