---
title: "Define Resources and Providers"
url: "https://docs.caracal.run/guides/resources-providers/"
markdown_url: "https://docs.caracal.run/markdown/guides/resources-providers.md"
description: "Register protected upstream resources and explicit provider auth modes from the web console."
page_type: "page"
concepts: []
requires: []
---

# Define Resources and Providers

Canonical URL: https://docs.caracal.run/guides/resources-providers/
Markdown URL: https://docs.caracal.run/markdown/guides/resources-providers.md
Description: Register protected upstream resources and explicit provider auth modes from the web console.
Page type: page
Concepts: none
Requires: none

---

Resources tell Caracal what protected target is being accessed. Providers describe how Gateway authenticates to that target, including no-credential and Caracal mandate flows.

## When to create each object

| Object | Create it when |
| --- | --- |
| Resource | You need a stable protected target, Caracal resource scopes, an upstream URL, a Gateway application, and one upstream credential provider binding. |
| Provider | A resource needs an explicit upstream auth mode: none, Caracal mandate, OAuth 2.0 authorization code, OAuth 2.0 client credentials, API key, or bearer-token upstream auth. |
| Gateway application | You want Gateway-originated upstream calls to use a specific Caracal application identity. |

Resource fields should answer “what is being protected and where does Gateway send traffic?” Provider fields should answer “what credential or identity does Gateway attach upstream?” Keep credential details such as client secrets, token endpoints, API-key placement, bearer tokens, identity forwarding, and runtime injection on the provider. Keep target details such as resource identifier, Caracal resource scopes, upstream URL, Gateway application, and the selected upstream credential provider on the resource.

:::note[FAQ]
[What is the difference between a resource and a provider?](/reference/faq/#faq-009) and [is an application secret the same as a provider credential?](/reference/faq/#faq-013)
:::

## Web Console Workflow

1. Start the local runtime with `caracal up`.
2. Open `caracal web`.
3. Select **Resources**.
4. Create a resource with a stable identifier, such as `resource://pipernet`.
5. Add action-oriented scopes, such as `payments:read` and `payments:refund`.
6. Set the upstream URL, Gateway application, and upstream credential provider for the protected service.
7. Select a `None` provider when Gateway should enforce Caracal access but the upstream expects no credential.
8. Select `Caracal mandate` for resources that verify Caracal tokens directly, or choose a provider-native type when the upstream needs external credentials.
9. Attach exactly one upstream credential provider to the resource.
10. For a path-addressed REST upstream, declare the operations the Gateway may invoke and keep operation authority `enforced`; choose `transport_uniform` for single-surface transports such as MCP.

## Provider auth modes

| Provider type | Required main fields | Runtime behavior |
| --- | --- | --- |
| None | No credential fields. | Gateway strips caller auth and forwards no upstream credential; use only when Gateway is the enforcement point and the upstream expects no credential. |
| Caracal mandate | No credential fields. | Gateway forwards the Caracal resource mandate in `Authorization: Bearer ...`; the resource verifies issuer, audience, scopes, target, expiry, and revocation. |
| OAuth 2.0 authorization code | Authorization endpoint, token endpoint, redirect URI, client ID, client secret, optional upstream OAuth scopes. | Creates user/resource provider grants through a browser consent callback, then refreshes delegated provider tokens inside STS. |
| OAuth 2.0 client credentials | Token endpoint, client ID, client secret unless OAuth client authentication is `none`, optional upstream OAuth scopes. | STS obtains and caches service-to-service provider tokens for Gateway upstream calls. |
| API key | Header name and API key. | Gateway forwards the sealed provider key in the configured header, with an optional auth scheme prefix. |
| Bearer token | Bearer token. | Gateway forwards the sealed provider token as `Authorization: Bearer ...` unless Advanced routing configures another header or scheme. |

OAuth 2.0 authorization-code providers are for delegated user consent. Register the exact Caracal callback URI as the provider redirect URI, such as `https://api.hooli.example/v1/zones/z1/provider-grants/oauth/callback`, then use the provider `connect` action to create an authorization URL for a user, resource, and Caracal resource scope set. Upstream OAuth scopes are main-form optional fields because they are a common part of consent. OAuth authorization parameters are Advanced key/value entries for provider-specific browser parameters, such as `access_type=offline` and `prompt=consent`; Caracal always owns reserved OAuth fields such as `client_id`, `redirect_uri`, `state`, and PKCE challenge values. OAuth token parameters are Advanced key/value entries for provider-specific token endpoint parameters; Caracal owns credentials, grants, refresh tokens, and scope parameters. OAuth token endpoint hosts constrain the code exchange and later refresh calls, and token endpoints must resolve to routable public addresses.

The callback endpoint is intentionally public so external providers can redirect browsers back to Caracal. Security comes from short-lived Redis-backed state, one-time state consumption, PKCE, resource/upstream credential provider binding checks, scope checks, sealed token storage, HTTPS-only token exchange, redirect blocking, host allow-listing, and private-address rejection. In cloud deployments, all API replicas must share Redis so a callback can validate state created by any replica. Reconnecting the same user, resource, and provider replaces the active provider grant instead of creating duplicate active credentials. Use the provider `disconnect` action to revoke the active delegated provider grant for a user and resource.

OAuth 2.0 client credentials keeps common machine-to-machine setup in the main form and moves provider-specific controls to Advanced. Use upstream OAuth scopes when the token endpoint expects OAuth scopes, OAuth token audience when the provider requires an `audience` parameter, OAuth resource indicator when the provider expects a resource indicator, and OAuth token parameters only for documented provider-specific token endpoint parameters. OAuth token endpoint hosts constrain outbound token acquisition; web console infers the host from the token endpoint when the Advanced field is blank.

API key providers use one required routing field: the exact header the upstream expects. Use `X-API-Key` or another vendor header when the API wants the raw key value, use `Authorization` plus the Advanced auth scheme `Bearer` for bearer-style API keys, and use a vendor scheme such as `Token` only when the provider documents that format. `auth_header` is not part of API-key provider config; OAuth and bearer-token providers use that field because their default upstream header is `Authorization`.

Bearer token providers are for static, pre-issued access tokens that Caracal does not mint or refresh. The main form only needs the token; Advanced options are for uncommon upstreams that expect a non-default header or a scheme other than `Bearer`. The token is sealed at creation time, list and detail APIs expose only `secret_config_keys`, and Gateway replaces caller-supplied auth before forwarding the provider credential upstream.

Provider secrets are sealed at creation time and are not returned by list or detail APIs. Every Gateway resource binds one upstream credential provider, and one provider can be reused by many resources. None providers have no secret and send no credential. Caracal mandate providers have no provider-native secret and no `forward_caracal_identity` setting because the mandate is already the upstream credential. Use Caracal mandate for internal services, partner services, external integrations, or network-level resources that choose to trust Caracal mandates through a verifier.

## Operation authority

A resource declares which upstream operations the Gateway may invoke and how strictly that surface is enforced. This authority is native to the platform: the Gateway and STS enforce it directly, so adopters configure data, not policy control flow.

| Field | Meaning |
| --- | --- |
| `operations` | The operations the Gateway may forward, each a `{method, path, scope}` triple. `method` and `path` match the upstream call; `scope` is the Caracal resource scope the mandate must carry for that operation, and must be one of the resource's declared scopes. |
| `operation_enforcement` | `enforced` denies any Gateway operation not listed in `operations` and requires its scope on the mandate. `transport_uniform` treats the upstream as a single surface and relies on the mint-time scope check, for protocols such as MCP that address every call through one transport path. |

When `operation_enforcement` is `enforced`, the Gateway authorizes only declared operations and denies everything else with `operation_not_permitted` before any upstream call. A resource that is `enforced` with an empty `operations` list is fully closed: every Gateway operation is denied until operations are declared. New resources created through the Control API default to `enforced`, so authority stays closed until you describe it; web console guided setup opens resources as `transport_uniform` because it does not collect per-operation detail, and you tighten them from the resource editor once the operation set is known.

Because the floor is enforced in the platform rather than in adopter policy, a policy can further restrict an operation but can never widen authority beyond the declared operations and their scopes.

## Identifier and scope guidance

| Field | Good pattern |
| --- | --- |
| Resource identifier | Stable audience URI, such as `resource://pipernet`; do not use the `provider://` namespace. |
| Caracal resource scope | `domain:action`, such as `pipernet:read`. |
| Upstream URL | The network URL Gateway can reach; it may change without changing policy audiences. |
| Gateway application | The managed Caracal application identity Gateway exchanges as to obtain this resource's upstream credential. It does not control which agents may call through the Gateway — callers are authorized by policy on their own mandate. DCR applications cannot be bound here — they are short-lived single-session credentials, not durable Gateway identities. |
| Upstream credential provider | The provider record Gateway uses to attach no credential, a Caracal mandate, OAuth tokens, API keys, or bearer tokens. |
| Authorized operation | `{method, path, scope}`, such as `{ "method": "POST", "path": "/api/create_payout", "scope": "pipernet:payout" }`; the scope must be one of the resource's Caracal resource scopes. |
| Operation enforcement | `enforced` for path-addressed REST upstreams; `transport_uniform` for single-surface transports such as MCP. |
| Provider identifier | `provider://lowercase-slug` stable name for the upstream credential system. |

Do not put provider-specific credential details on a resource. Do not use mutable deployment hostnames as policy identifiers unless they are the actual authority boundary. Keep the resource identifier stable even if the upstream URL or upstream credential provider binding changes.

:::note[FAQ]
[Why must the resource identifier stay stable if the upstream URL can change?](/reference/faq/#faq-010)
:::

## Validate the setup

- Open the resource in the web console and confirm scopes are present.
- Author and activate a policy that allows the application and subject to request the scopes.
- Send a Gateway request and inspect the audit event. For Caracal mandate upstreams, also confirm the resource uses a Caracal verifier or connector.

## Related guides

- [Provider Recipes](/guides/provider-recipes/)
- [Author Policy Data](/guides/author-policy/)
- [Debug Authorization Decisions](/guides/authorize-access/)
- [Protect a Gateway-Routed HTTP API](/guides/protect-gateway-http/)
- [Activate a Policy Set](/guides/activate-policy-set/)
