---
title: "Protect a Gateway-Routed HTTP API"
url: "https://docs.caracal.run/v1.0/guides/protect-gateway-http/"
markdown_url: "https://docs.caracal.run/markdown/v1.0/guides/protect-gateway-http.md"
description: "Configure a resource route so Caracal Gateway verifies mandates, brokers provider credentials, forwards the request, and records action-result audit."
page_type: "page"
concepts: []
requires: []
---

# Protect a Gateway-Routed HTTP API

Canonical URL: https://docs.caracal.run/v1.0/guides/protect-gateway-http/
Markdown URL: https://docs.caracal.run/markdown/v1.0/guides/protect-gateway-http.md
Description: Configure a resource route so Caracal Gateway verifies mandates, brokers provider credentials, forwards the request, and records action-result audit.
Page type: page
Concepts: none
Requires: none

---

Use Gateway-routed protection when the upstream is HTTP-routable and you want Caracal to enforce every request before it reaches the target. The agent receives a short-lived Caracal mandate; Gateway verifies it, resolves the resource route, attaches the configured upstream credential when needed, forwards the request, and writes action-result audit.

## Prerequisites

* Gateway, STS, Redis revocation state, audit ingestion, and the upstream ready.
* A resource with stable identifier, Gateway application, provider, scopes, and declared operations.
* An active policy granting only the calling role and an application SDK configured for the same resource.

## When to Use Gateway

| Use Gateway when                                                               | Use another guide when                                                      |
| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| The upstream is HTTP, REST, MCP-over-HTTP, or another Gateway-routable target. | The service must verify mandates inside its own process.                    |
| You want provider credentials to stay inside the trusted Gateway/STS boundary. | The application must call the provider directly and only needs attribution. |
| You want action-result audit from the central Gateway.                         | The resource server owns result audit after adapter verification.           |
| Responses are request/response or streamed HTTP, such as SSE.                  | The upstream requires WebSocket connections, which Gateway does not proxy.  |

For in-process enforcement, use [Protect an Express App](/v1.0/guides/protect-express/), [Protect a FastMCP App](/v1.0/guides/protect-fastmcp/), [Protect a Go net/http Service](/v1.0/guides/protect-nethttp/), or [Protect an MCP Server](/v1.0/guides/protect-mcp/).

## Create or Select the Resource

Open the web console for your deployment (`http://localhost:3001` on the packaged local stack).

Create or select a resource with:

| Field                        | Guidance                                                                                                            |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Resource identifier          | Stable audience URI, such as `resource://pipernet`.                                                                 |
| Scopes                       | Action-oriented scopes, such as `pipernet:read` and `pipernet:submit`.                                              |
| Upstream URL                 | Network URL the Gateway can reach.                                                                                  |
| Gateway application          | The Caracal application identity Gateway uses for upstream exchanges.                                               |
| Upstream credential provider | The provider record Gateway uses to attach no credential, a Caracal mandate, OAuth token, API key, or bearer token. |

Keep the resource identifier stable even when upstream hosts or provider bindings change.

## Choose Provider Auth Mode

| Provider type            | Use when                                                                |
| ------------------------ | ----------------------------------------------------------------------- |
| None                     | Gateway enforces Caracal access and the upstream expects no credential. |
| Caracal mandate          | The upstream verifies Caracal mandates directly.                        |
| OAuth client credentials | Gateway needs a machine OAuth token.                                    |
| OAuth authorization code | Gateway needs a connected upstream account (delegated OAuth consent).   |
| API key                  | Gateway attaches a sealed static API key in a configured header.        |
| Bearer token             | Gateway attaches a sealed pre-issued bearer token.                      |

Use [Define Resources and Providers](/v1.0/guides/resources-providers/) for field definitions and [Provider Recipes](/v1.0/guides/provider-recipes/) for concrete OpenAI, Google, GitHub, Slack, and internal API examples.

## Route Calls Through Gateway

Gateway-routed requests include:

| Request part         | Value                                                                               |
| -------------------- | ----------------------------------------------------------------------------------- |
| URL                  | Gateway URL from your runtime profile (`gateway_url`; `http://localhost:8081` on the local stack). |
| `Authorization`      | `Bearer <Caracal mandate>`.                                                         |
| `X-Caracal-Resource` | Resource identifier.                                                                |
| Path                 | The protected path you configured for the upstream.                                 |

SDKs can build the Gateway request and inject headers for you:

* TypeScript: `caracal.gatewayRequest()` plus `caracal.transport({ scopes })`
* Python: `caracal.gateway_request()` plus `caracal.transport(scopes=[...])`
* Go: `GatewayRequest()` plus `Transport(nil, CallOptions{Scopes: ...})`

The request helper supplies only the Gateway URL and `X-Caracal-Resource`; the scoped transport mints and attaches the required `use=gateway` mandate. Do not combine the helper with raw lifecycle headers.

## Verify Authorization and Audit

Run these checks before treating the route as ready:

| Check                 | Expected result                                               |
| --------------------- | ------------------------------------------------------------- |
| Allowed request       | Gateway forwards to upstream and records action-result audit. |
| Missing mandate       | Gateway rejects the request.                                  |
| Missing scope         | STS or Gateway rejects the request.                           |
| Wrong resource header | Gateway rejects or routes to a different configured resource. |
| Revoked session       | Gateway rejects the old mandate.                              |

Open the web console **Audit** and filter by the request ID. A complete Gateway-routed call has both authorization evidence from STS and action-result evidence from Gateway.

Gateway preserves the HTTP method, path, query, body, and streaming response. It replaces caller authorization with the selected provider credential, strips upgrade behavior, does not proxy WebSockets, and does not retry an upstream mutation. A stale revocation snapshot fails closed with `503` before forwarding.

## Troubleshooting

| Symptom                                                       | Check                                                                    |
| ------------------------------------------------------------- | ------------------------------------------------------------------------ |
| Gateway returns 403                                           | Token expiry, resource ID, scopes, revocation, and `X-Caracal-Resource`. |
| Upstream is unreachable                                       | Upstream URL must be reachable from the Gateway container or deployment. |
| Provider credential not attached                              | Resource must bind exactly one upstream credential provider.             |
| Authorization audit exists but action-result audit is missing | The request did not reach Gateway or failed before route execution.      |

:::caution[Failure point: raw headers]
`X-Caracal-Resource` routes the request; it does not authorize it. Send a scoped `use=gateway` bearer minted by the SDK transport. Do not send lifecycle headers or trust a client-supplied application ID.
:::

## Next Step

Run [Check Provider Readiness](/v1.0/examples/provider-preflight/), then use [Debug Authorization Decisions](/v1.0/guides/authorize-access/) for any deny.
