---
title: Configuration File
description: caracal.toml — full schema, lookup order, environment variable overrides, and credential injection configuration.
pageType: config
---

`caracal.toml` is the configuration file for the `caracal run` and `caracal credential read` commands. It stores the application credentials (zone, application, and client secret) used for token exchange, and declares which resource mandates to inject into subprocess environments.

The control-plane admin commands (`zone`, `app`, `resource`, etc.) do not require `caracal.toml` — they use environment variables directly.

---

## File discovery

The CLI resolves the config path in this order, stopping at the first match:

| Priority | Source | Path |
| --- | --- | --- |
| 1 | `CARACAL_CONFIG` env var | Explicit path |
| 2 | Current working directory | `./caracal.toml` |
| 3 | `$PWD` | `$PWD/caracal.toml` |
| 4 | npm `$INIT_CWD` | `$INIT_CWD/caracal.toml` |
| 5 | XDG config directory | `$XDG_CONFIG_HOME/caracal/caracal.toml` |
| 6 | Home config directory | `~/.config/caracal/caracal.toml` |

Author `caracal.toml` at the first writable path at priorities 2–3 (typically the project root) unless `CARACAL_CONFIG` points elsewhere.

---

## Full schema

```toml
# Required: credentials for token exchange with the STS
zone_url          = "http://localhost:8080"     # STS base URL
zone_id           = "zone_abc123"               # Zone ID
application_id    = "app_def456"               # OAuth application ID
app_client_secret = "secret_xyz"               # Client secret

# Optional: behavior on required credential failures (default: false)
continue_on_failure = false

# Declare resource mandates to inject into subprocesses
[[credentials]]
env      = "RESOURCE_TOKEN"          # Environment variable name in the subprocess
resource = "resource://my-api"       # Resource identifier to exchange for a token

[[credentials]]
env      = "PAYMENTS_TOKEN"
resource = "resource://payments-api"

# Optional credentials: failures log a warning but do not block the subprocess
[[optional_credentials]]
env        = "ANALYTICS_TOKEN"
resource   = "resource://analytics-api"
on_failure = "warn"    # "warn" or "error" (default: "warn" for optional credentials)

# MCP governance: control whether MCP server binaries can be spawned via caracal run
[mcp_governance]
mode = "block"    # "block" = exit 1 if MCP server detected, "log" = warn and continue
```

---

## Fields

### Core fields

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `zone_url` | string | Yes | STS base URL. The token exchange endpoint is at `{zone_url}/oauth2/token`. |
| `zone_id` | string | Yes | Zone ID. Sent as `zone_id` in the token exchange request. |
| `application_id` | string | Yes | OAuth application ID. Sent as `application_id` in the token exchange. |
| `app_client_secret` | string | Yes | Client secret for the application. |
| `continue_on_failure` | boolean | No | When `true`, if a required credential exchange fails, `caracal run` logs the error and continues without injecting that token. Default: `false`. |

### `[[credentials]]`

Declares a required resource mandate. Every credential in this array is exchanged before the subprocess is spawned. If any exchange fails and `continue_on_failure` is `false`, the subprocess is not started.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `env` | string | Yes | Environment variable name injected into the subprocess. |
| `resource` | string | Yes | Resource identifier to exchange for a token. |

### `[[optional_credentials]]`

Declares an optional resource mandate. Exchange failures produce a warning but do not block the subprocess.

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `env` | string | required | Environment variable name. |
| `resource` | string | required | Resource identifier. |
| `on_failure` | `"warn"\|"error"` | `"warn"` | Log level on failure. |

### `[mcp_governance]`

Controls how `caracal run` behaves when the subprocess command references an MCP server binary (`mcp-server`, `fastmcp`, or `@modelcontextprotocol`).

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | `"block"\|"log"` | — | `"block"` exits with code 1 before spawning. `"log"` logs and continues. |

---

## Environment variable overrides

These environment variables are read by the CLI. Most of them override what is in `caracal.toml` or the defaults applied in development mode:

| Variable | Default | Affects |
| --- | --- | --- |
| `CARACAL_ADMIN_TOKEN` | From secret-file discovery | All admin commands |
| `CARACAL_ADMIN_TOKEN_FILE` | — | Explicit path to a file containing the admin token |
| `CARACAL_API_URL` | `http://localhost:3000` (dev) | Admin commands API base URL |
| `CARACAL_ZONE_ID` | From `caracal.toml` | Zone ID for admin commands |
| `CARACAL_COORDINATOR_URL` | `http://localhost:4000` (dev) | `agent` and `delegation` commands |
| `CARACAL_COORDINATOR_TOKEN` | — | `agent` and `delegation` commands |
| `CARACAL_CONFIG` | Auto-resolved | Config file path |
| `CARACAL_REPO_ROOT` | Auto-searched | Root for `infra/docker/` stack commands |
| `CARACAL_HOME` | Platform default | Installed runtime home (compose, overrides, secrets) |

`CARACAL_ADMIN_TOKEN` is discovered in order: the environment variable itself → `CARACAL_ADMIN_TOKEN_FILE` → `$CARACAL_HOME/secrets/caracalAdminToken` → `$CARACAL_REPO_ROOT/infra/secrets/files/caracalAdminToken` (dev only). In production (`NODE_ENV !== 'development'`), `CARACAL_API_URL` and `CARACAL_COORDINATOR_URL` must be set explicitly — no localhost defaults are applied.

---

## Example: multi-resource configuration

```toml
zone_url          = "https://sts.internal.mycompany.com"
zone_id           = "zone_prod_abc123"
application_id    = "app_payment_agent"
app_client_secret = "prod-secret-xyz"

continue_on_failure = false

[[credentials]]
env      = "PAYMENTS_TOKEN"
resource = "resource://payments-api"

[[credentials]]
env      = "LEDGER_TOKEN"
resource = "resource://ledger-api"

[[optional_credentials]]
env        = "METRICS_TOKEN"
resource   = "resource://metrics-api"
on_failure = "warn"

[mcp_governance]
mode = "block"
```

```bash
caracal run -- node payment-agent.js
# Injects PAYMENTS_TOKEN, LEDGER_TOKEN, and METRICS_TOKEN (if available) into the process
```
