Hosted egress reference

Routes, roles, limits, the provider catalog, API errors and gateway answers of the AI egress gateway hosted by OpenWAF Cloud.

On this page

The hosted gateway is the open-source OpenWAF Egress run by OpenWAF Cloud at https://egress.openwaf.dev, with agents, targets and keys managed per organization instead of a configuration file.

Gateway URL

https://egress.openwaf.dev/v1/agent/<agent name>/proxy/<target id>/<provider path>
Authorization: Bearer OWE_TOKEN_…

<provider path> and the query string are appended to the target's base URL: …/proxy/openrouter/chat/completions goes to https://openrouter.ai/api/v1/chat/completions. Each agent's base_urls gives the URL for every target it may call.

Compared with a self-hosted gateway:

  • The agent is identified by its token, and the URL must name that token's agent; /v1/proxy/<target>/… and the X-OpenWAF-Agent header are not used.
  • The agent's token is never forwarded upstream; the target's auth header carries the provider key instead.
  • A target without a provider key is refused instead of being called without one.
  • Besides the check before the call, the address actually connected to is checked again against private and reserved ranges.
  • Changes to agents, targets and keys reach the gateway within seconds; a provider key is cached for up to five minutes.

The checks, detectors, body limits and timeouts are those of the open-source gateway: see the security model and the fixed limits.

Gateway errors

The gateway's own errors are JSON with an error code and a message; the provider's answers pass through unchanged.

StatuserrorCause
401token_requiredNo Authorization header
401invalid_tokenUnknown token, a rotated one, or the agent is disabled or deleted
401unauthorized_agentThe URL does not name the token's agent
403egress_blockedThe target is not among the agent's allowed targets (another agent of the organization may call it)
403ssrf_blockedThe target resolves to a private or reserved address
403injection_detectedA prompt-injection detector matched the body (Block prompt injection on)
403data_leak_blockedA data-leak pattern matched the body (Block data leaks on)
404unknown_targetNo agent of the organization may call that target id, or it does not exist
413body_too_largeOver 8 MiB, or over 1 MiB of text to inspect
502credential_resolution_failedThe target has no provider key, or it could not be read
502upstream_errorThe provider could not be reached
503policy_unavailableThe gateway has no current policy for the request; retry later

The 403 and 413 answers appear in blocked requests. The troubleshooting page explains each code in detail.

Management API

All routes are under https://dash.openwaf.dev/v1/orgs/{org} with an API token (Authorization: Bearer owf_…) or the dashboard session. Reads need any role of the whole organization; writes need admin of the whole organization. Members and tokens limited to a client or a zone get 403. Writes take an optional X-Change-Reason; they are not versioned configuration and refuse dry_run. The TypeScript and Python SDKs include every route except the stream.

RouteWhat it does
GET /egress{enabled, gateway_url, credentials_available}: whether AI egress is on for the organization, readable even when it is not
GET /egress/targetsThe catalog, then the custom targets, each with its key's metadata (credential: fingerprint, updated_at, updated_by, or null)
POST /egress/targetsAdd a custom target: id, name, base_url, auth_header, auth_prefix
DELETE /egress/targets/{target}Delete a custom target and its key
PUT /egress/targets/{target}/credentialSet or replace the key: {"secret": "…"}; answers the target with the key's fingerprint
DELETE /egress/targets/{target}/credentialRemove the key
GET /egress/agents, GET /egress/agents/{id}Agents, with base_urls per allowed target and token_prefix
POST /egress/agentsCreate an agent: name, description, allowed_targets, enforce_injection, block_dlp, disabled; answers {agent, token}
PATCH /egress/agents/{id}Change description, allowed_targets (replaced whole), enforce_injection, block_dlp or disabled
POST /egress/agents/{id}/rotate-tokenNew token; answers {agent, token}
DELETE /egress/agents/{id}Delete an agent
GET /egress/eventsBlocked requests, newest first, with the filters of the security events
GET /egress/events/streamBlocked requests as Server-Sent Events

Reading and deleting agents, targets and keys works even when AI egress is off for the organization; every other write, and the events, answer 403 feature_disabled. The answers that carry a token or set a key have Cache-Control: no-store.

Limits and formats

ItemRule
Agent name^[a-z0-9][a-z0-9-]{0,62}$, unique in the organization, cannot change
DescriptionUp to 500 characters
Allowed targets1 to 32 target ids per agent
TokenOWE_TOKEN_ and 32 random bytes in base64url, shown once; only its SHA-256 and its prefix (OWE_TOKEN_ and 6 characters) are kept
Custom target id^[a-z][a-z0-9-]{1,31}$, not a catalog id
Custom target nameUp to 100 characters
Custom target URLhttps://, port 443, public DNS name, no IP, credentials, query or fragment
Auth header, prefixA header name of up to 64 characters; a prefix of up to 32 printable characters
Provider key1 to 8,192 characters, no spaces or control characters

API errors

StatuscodeWhen
403feature_disabledAI egress is not enabled for the organization
403forbiddenThe role is too low, or the member or token is limited to a client or a zone
404not_foundNo such agent or target in the organization
409conflictAn agent or a custom target with that name or id already exists
409target_in_useDeleting a custom target that an agent still allows
422invalidA field breaks the rules above (field names it), or deleting a catalog target
502credential_storeThe credential store did not accept the change; try again
503unavailableProvider keys cannot be stored right now (credentials_available is false)

Catalog

IdProviderBase URLKey header
openrouterOpenRouterhttps://openrouter.ai/api/v1Authorization: Bearer
openaiOpenAIhttps://api.openai.com/v1Authorization: Bearer
anthropicAnthropichttps://api.anthropic.com/v1x-api-key
huggingfaceHugging Facehttps://router.huggingface.co/v1Authorization: Bearer
groqGroqhttps://api.groq.com/openai/v1Authorization: Bearer
mistralMistral AIhttps://api.mistral.ai/v1Authorization: Bearer
geminiGoogle Gemini (OpenAI-compatible)https://generativelanguage.googleapis.com/v1beta/openaiAuthorization: Bearer
deepseekDeepSeekhttps://api.deepseek.com/v1Authorization: Bearer
togetherTogether AIhttps://api.together.xyz/v1Authorization: Bearer
fireworksFireworks AIhttps://api.fireworks.ai/inference/v1Authorization: Bearer
cohereCoherehttps://api.cohere.com/v2Authorization: Bearer
perplexityPerplexityhttps://api.perplexity.aiAuthorization: Bearer
xaixAIhttps://api.x.ai/v1Authorization: Bearer

MCP tools

egress_status and egress_events read; egress_create_agent, egress_update_agent, egress_rotate_token, egress_delete_agent, egress_add_target, egress_remove_target and egress_remove_credential write, with confirm=false to check first and no expected_version. There is no tool to set a provider key. See the MCP tools.

Last updated:

↑↓ to navigate↵ to openesc to close