> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ironbee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> Tune IronBee's verification behavior with layered global, project, and local config.

IronBee works out of the box, and most projects never need to touch config. When you do want to fine-tune *which* files get verified, change retry limits, or point at a self-hosted collector, this page is the reference.

You can edit settings two ways: the `ironbee config` command (recommended, since it validates and re-applies changes for you) or by editing the JSON files directly.

***

## Config layers

Settings are read from three files and **deep-merged**. Higher layers override lower ones:

| Layer   | File                                   | Use for                                                             |
| ------- | -------------------------------------- | ------------------------------------------------------------------- |
| Global  | `~/.ironbee/config.json`               | Defaults across all your projects (e.g. your collector credentials) |
| Project | `<project>/.ironbee/config.json`       | Team settings committed to the repo                                 |
| Local   | `<project>/.ironbee/config.local.json` | Personal overrides, gitignored, never shared                        |

Precedence is **local > project > global**. A key set in the local layer wins over the same key in the project layer, which wins over global.

Secrets can also come from the environment: setting `IRONBEE_SERVICE_API_KEY` (or the legacy `IRONBEE_API_KEY`) supplies the account API key without committing it to any file.

***

## Editing config from the CLI

```bash theme={null}
ironbee config get <key>            # read the effective (merged) value
ironbee config set <key> <value>    # write to the project config
ironbee config unset <key>          # remove a value (idempotent)
ironbee config list                 # print the merged effective config
ironbee config path                 # print the project config file path
```

**Targeting a layer:**  `set`, `unset`, and the read commands accept `-g`/`--global` or `--local` to act on a specific layer (default is the project config). `list` and `get` also take `--project` to read one layer in isolation:

```bash theme={null}
ironbee config set collector.apiKey sk-... --global
ironbee config set maxRetries 5
ironbee config set browser.verifyPatterns '["*.ts", "*.tsx", "*.css"]'
ironbee config list --global
```

**Type coercion:** `set` parses values as JSON when it can (`true`, `42`, `[...]`, `{...}`) and falls back to a plain string otherwise. Pass `--json` to force strict JSON parsing.

**Automatic re-render:** when you change a key that affects installed client artifacts (anything under `verification`, `service`, `collector`, `browser`, `node`, `python`, `backend`, `android`, `terminal`, `telemetry`, `privacy`, `statusLine`, `otel`, `codex`, `runtime`, `integrations`, or the `*DevTools` overrides), the CLI automatically re-renders your hooks, MCP entries, skill, rule, and permissions. Pass `--no-rerender` to skip. After a global write on an artifact-affecting key, the CLI offers to propagate it to every registered project. `--apply-all` accepts without prompting, `--no-apply-all` declines.

<Info>
  Restart your editor or agent session after changing an artifact-affecting key; it takes effect on the next session.
</Info>

***

## Core options

| Key                     | Type       | Default                                    | Description                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------- | ---------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ignoredVerifyPatterns` | `string[]` | `[]` *(plus always-on test-file defaults)* | Glob patterns excluded from **all** cycles. Checked first a match here activates no cycle, whatever else matches. Your patterns are **unioned on top of** a built-in default set that always excludes test files (`**/*.spec.*`, `**/*.test.*`, `**/__tests__/**`, `**/__mocks__/**`), so a test-only edit never triggers a runtime-verification cycle even if you set nothing. |
| `maxRetries`            | `number`   | `3`                                        | Failed verification attempts allowed before the agent may complete anyway (reporting unresolved issues). One global counter across all active cycles.                                                                                                                                                                                                                           |
| `params`                | `object`   | *(unset)*                                  | User-defined string→string map consumed by [`${param:<name>}` placeholders](#placeholders-param-env-built-ins) elsewhere in the config. Merged per key across layers (local wins). Not artifact-affecting (read live).                                                                                                                                                          |

```json theme={null}
{
  "ignoredVerifyPatterns": ["**/generated/**", "**/*.gen.ts"],
  "maxRetries": 5
}
```

<Note>
  Test files are already excluded out of the box — `ignoredVerifyPatterns` is only for *additional* paths you want to skip on top of that built-in default.
</Note>

***

## Placeholders — `${param:}`, `${env:}`, built-ins

Config **string** values can interpolate placeholders that IronBee resolves at **read time**, so one committed config can carry per-developer or per-environment values without hand-editing. Three forms are supported:

| Form              | Reads from                                                                                     | Example                                                                                       |
| ----------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| `${param:<name>}` | The [`params`](#core-options) block, overridable per key by the `IRONBEE_PARAM_<NAME>` env var | `${param:api_url}`                                                                            |
| `${env:<name>}`   | The `IRONBEE_ENV_<NAME>` env var **only**                                                      | `${env:staging_url}`                                                                          |
| Built-ins         | Static values                                                                                  | `${projectDir}` `${projectName}` `${home}` `${configDir}` `${platform}` `${arch}` `${tmpdir}` |

Each `${param:}` / `${env:}` reference takes an optional bash-style default after `:-` (e.g. `${env:staging_url:-http://localhost:3000}`), and resolves in this order:

* **`${param:api_url}`** → `IRONBEE_PARAM_API_URL` env → the `params` block (local → project → global) → the `:-` default → the literal text (with a warning).
* **`${env:staging_url}`** → `IRONBEE_ENV_STAGING_URL` env → the `:-` default → the literal text.

```json theme={null}
{
  "params": { "api_url": "http://localhost:3000" },
  "verification": {
    "checks": [
      { "name": "api-test", "command": "npm",
        "args": ["run", "test:api", "--", "--base-url", "${param:api_url}"] }
    ],
    "context": { "message": "Verify against ${env:staging_url:-http://localhost:3000}." }
  }
}
```

<Note>
  The `env:` / `param:` prefix is **implied and never written** — `${env:staging_url}` can only read `IRONBEE_ENV_STAGING_URL`, so arbitrary environment variables (`AWS_SECRET_ACCESS_KEY`, tokens, …) are structurally unreachable from config text. Write a literal `${` as `$${`. Upper-case shell forms like `${HOME}` in check arguments are left untouched.
</Note>

Placeholders resolve for **runtime consumers** (checks, context injection, the collector). Values baked into **committed client artifacts** are read raw and kept as literal references, so a resolved value never lands in a shared artifact — the supported keys are the runtime-read ones (`verification.checks[]` command/args/env/cwd and `verification.context.message`). `ironbee config get <key>` (merged) prints the **resolved** value with a provenance note on stderr; a layer-scoped read (`--project` / `--global` / `--local`) shows the raw on-disk text.

***

## Runtime

| Key                | Type     | Default      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ------------------ | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `runtime.location` | `string` | `"external"` | Where per-session runtime data (the `sessions/` folder — `actions.jsonl`, verdicts, queue, analytics) is stored. `"external"` *(default)* keeps it **out of the project tree** at `~/.ironbee/projects/<token>/sessions/`, so a project never accumulates a growing `sessions/` folder even when it's gitignored. `"in-project"` stores it under `<project>/.ironbee/sessions/` (the legacy layout). Committed config, `scenarios/`, and `VERIFICATION.md` files always stay in-project regardless. The [`IRONBEE_RUNTIME_LOCATION`](/cli/configuration/environment-variables#advanced) env var overrides it per process. Takes effect on the next session. See [Runtime files](/cli/advanced/runtime-files#where-per-session-data-lives). |

<Note>
  Switching `runtime.location` doesn't move existing session data — it changes where *new* sessions are written. Old per-session folders under the previous location are left in place; you can delete them by hand if you don't need them.
</Note>

***

## Verification

| Key                   | Type                 | Default                               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| --------------------- | -------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `verification.enable` | `boolean`            | `true`                                | Master enforcement switch. `false` = monitoring-only (telemetry still flows, no verify gate). Equivalent to [`ironbee verification disable`](/cli/guides/verification#verification-modes).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `verification.auto`   | `boolean`            | `false`                               | Automatic-enforcement sub-toggle (only meaningful when `verification.enable` is `true`). Default `false` = [assist mode](/cli/guides/verification#assist-mode-default), the safer default: the `/ironbee-verify` command, the devtools MCP server, and permissions stay installed for manual verification, but nothing is enforced and no verify gate, non-blocking pre-edit hooks, and the skill/rule are omitted. Set `true` for full [enforce mode](/cli/guides/verification#enforce-mode) (blocking Stop gate + skill/rule installed). Equivalent to [`ironbee verification auto enable`/`disable`](/cli/guides/verification#enforce-mode).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `verification.model`  | `string` \| `object` | *(unset — inherit the session model)* | Model the [delegated verifier sub-agent](/cli/guides/verification#picking-the-verifier-model) runs on (Claude Code and Codex). Unset means the verifier inherits the main conversation's model. Set a **string** (e.g. `"sonnet"`, `"gpt-5.5"`) to apply to every client, or a **per-client object** `{ "claude": "sonnet", "codex": "gpt-5.5" }` when a project uses both. Cursor has no verifier sub-agent, so it's a no-op there. Equivalent to [`ironbee verification model <value>`](/cli/guides/verification#picking-the-verifier-model).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `verification.fix`    | `boolean`            | `true`                                | [Fix enforcement](/cli/guides/verification#fix-enforcement-block-on-a-fail-or-just-report-it). Default `true`: in enforce mode a **fail** verdict blocks completion until the agent fixes the issues and re-verifies (counts toward `maxRetries`). Set `false` for **report-only**: the agent still must verify and submit a verdict, but a fail is reported (and recorded) rather than looped on — the turn may end with the issues stated plainly. Only meaningful in enforce mode; read live by the gate. A manual `/ironbee-verify fix` run escalates that one run to fix-until-pass regardless. Equivalent to `ironbee verification fix <enable\|disable>`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `verification.strict` | `boolean`            | `false`                               | [Strict mode](/cli/guides/verification#strict-mode). When `true`, the verify gate **rejects all [N/A verdicts](/cli/guides/verification#when-a-change-has-nothing-to-verify-na-verdicts)** — the agent must produce real tool evidence for every active cycle. Default `false` accepts N/A (recorded and observable). Only meaningful in enforce mode (no gate runs in assist/monitoring). Read live by the gate. Equivalent to [`ironbee verification strict <enable\|disable>`](/cli/guides/verification#strict-mode).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `verification.checks` | `array`              | `[]`                                  | [Project checks](/cli/guides/verification#project-checks-run-first-lint-tests-types) — deterministic commands (lint, tests, typecheck, build, format) run as the **first step** of every verification cycle, before any devtools verification. Each entry is `{ "name", "command", "args"?, "env"?, "cwd"?, "timeoutMs"?, "required"?, "kind"?, "conclusive"? }` (`kind` is an advisory `typecheck`/`lint`/`test`/`build`/`format`/`other` label). The verifier runs them via `ironbee hook run-checks`; in enforce mode a `required` check that fails (or never ran) **blocks the gate** so the agent fixes and re-runs (it counts toward `maxRetries`). `conclusive: true` (implies `required`; hand-set only, never suggested) makes a check the **arbiter** of the cycle — all conclusive checks passing auto-submits the pass verdict and **skips** devtools verification; a conclusive check failing defers to a devtools **diagnosis** before a findings-rich fail. See [Conclusive checks](/cli/guides/verification#conclusive-checks-let-a-check-decide-the-cycle). Trust is the recorded exit code, never the agent's claim. Can be [LLM-suggested](/cli/guides/verification#let-ironbee-suggest-your-checks) at install or via `ironbee checks suggest`. Read live (not artifact-affecting); results stay local (not shipped to the Collector). |

***

## Verification cycles

The six cycles: `browser`, `node`, `python`, `backend`, `android`, and `terminal`, share the same set of keys (replace `<cycle>` with `browser`, `node`, `python`, `backend`, `android`, or `terminal`):

| Key                                | Type       | Description                                                                                                                                                                                            |
| ---------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `<cycle>.enable`                   | `boolean`  | Explicit on/off. Written `false` by `ironbee <cycle> disable`, stripped by `ironbee <cycle> enable`. Browser is the only cycle on by default; node, python, backend, android, and terminal are opt-in. |
| `<cycle>.verifyPatterns`           | `string[]` | Files that trigger the cycle. **Four states:** unset → built-in code defaults · `[]` → hard-disable · non-empty → custom patterns (replaces defaults).                                                 |
| `<cycle>.additionalVerifyPatterns` | `string[]` | Extra patterns appended to `verifyPatterns` (or to the defaults when it's unset). Ignored when `verifyPatterns` is `[]`.                                                                               |
| `<cycle>.alwaysRequired`           | `string[]` | Tools the agent must use before the cycle passes (all-of). Sensible per-cycle defaults apply. *Advanced.*                                                                                              |
| `<cycle>.evidencePaths`            | `json`     | Alternative tool-satisfaction paths (any-of). *Advanced.*                                                                                                                                              |

**Defaults differ per cycle:**

| Cycle      | Default state | Default verify patterns                                                                                                                                    |
| ---------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `browser`  | On            | 40+ code/markup extensions (`.ts`, `.tsx`, `.js`, `.css`, `.html`, `.vue`, …)                                                                              |
| `node`     | Opt-in        | When enabled: server/api/routes code paths                                                                                                                 |
| `python`   | Opt-in        | When enabled: server/api/app `.py` paths, Django (`views.py`/`urls.py`/`models.py`/`tasks.py`), Flask/FastAPI (`app.py`/`main.py`), WSGI/ASGI entry points |
| `backend`  | Opt-in        | When enabled: 13 multi-language code defaults (ts/js/py/go/java/rb/cs/rs/kt/scala/ex/php/clj)                                                              |
| `android`  | Opt-in        | When enabled: standard Android project layouts (Gradle, Kotlin/Java source trees, resources)                                                               |
| `terminal` | Opt-in        | When enabled: CLI / TUI / shell paths (`cli/**`, `cmd/**`, `bin/**`, `**/commands/**`, CLI entrypoints, shell scripts)                                     |

The exact default patterns each cycle uses when `verifyPatterns` is unset:

<AccordionGroup>
  <Accordion title="Browser default verify patterns">
    Matches code and markup files by extension (project-wide):

    ```
    *.ts  *.tsx  *.js  *.jsx  *.mjs  *.cjs
    *.vue  *.svelte
    *.html  *.htm
    *.css  *.scss  *.sass  *.less  *.styl
    *.py  *.rb  *.erb  *.go  *.rs
    *.java  *.kt  *.kts  *.swift
    *.c  *.cpp  *.h  *.hpp  *.cs  *.php  *.dart
    *.ex  *.exs  *.erl  *.lua  *.r  *.R
    *.scala  *.clj  *.cljs  *.zig  *.nim
    *.hbs  *.ejs  *.pug  *.jade  *.astro
    ```
  </Accordion>

  <Accordion title="Node default verify patterns">
    Targets typical Node.js server entry points and API routes (applies once the cycle is enabled):

    ```
    server/**/*.{ts,js,mjs,cjs}
    src/server/**/*.{ts,js,mjs,cjs}
    backend/**/*.{ts,js,mjs,cjs}
    api/**/*.{ts,js,mjs,cjs}
    src/api/**/*.{ts,js,mjs,cjs}
    pages/api/**/*.{ts,js,mjs,cjs}
    app/api/**/*.{ts,js,mjs,cjs}
    routes/**/*.{ts,js,mjs,cjs}
    **/server.{ts,js,mjs,cjs}
    ```
  </Accordion>

  <Accordion title="Python default verify patterns">
    Targets typical Python server entry points, web-framework modules, and WSGI/ASGI apps (applies once the cycle is enabled):

    ```
    server/**/*.py
    src/server/**/*.py
    backend/**/*.py
    api/**/*.py
    src/api/**/*.py
    app/**/*.py
    src/app/**/*.py
    routes/**/*.py
    services/**/*.py
    **/views.py  **/urls.py  **/models.py  **/tasks.py
    **/app.py  **/main.py  **/server.py
    **/wsgi.py  **/asgi.py
    ```
  </Accordion>

  <Accordion title="Backend default verify patterns">
    Multi-language coverage of common server-side directories (applies once the cycle is enabled). The `{...}` extension set is `ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj`:

    ```
    server/**/*.{…}
    src/server/**/*.{…}
    backend/**/*.{…}
    api/**/*.{…}
    src/api/**/*.{…}
    pages/api/**/*.{ts,js,mjs,cjs}
    app/api/**/*.{ts,js,mjs,cjs}
    routes/**/*.{…}
    controllers/**/*.{…}
    handlers/**/*.{…}
    services/**/*.{…}
    **/server.{…}
    **/main.{go,py,java,rb,kt,scala}
    ```
  </Accordion>

  <Accordion title="Android default verify patterns">
    Covers standard Android project layouts Gradle modules, Kotlin/Java source trees, and resources (applies once the cycle is enabled):

    ```
    android/**/*.{kt,java}
    app/src/**/*.{kt,java}
    mobile/**/*.{kt,java}
    src/main/kotlin/**/*.kt
    src/main/java/**/*.java
    **/*.{kt,java}
    **/res/**/*.xml
    **/AndroidManifest.xml
    ```
  </Accordion>

  <Accordion title="Terminal default verify patterns">
    Covers CLI entrypoints, command trees, and shell scripts (applies once the cycle is enabled):

    ```
    cli/**
    cmd/**
    bin/**
    **/commands/**
    **/cli.{ts,js,py,go,rs}
    **/*.{sh,bash,zsh,fish}
    ```
  </Accordion>
</AccordionGroup>

<Note>
  These defaults are defined in the CLI (not written into `config.json`) and may grow with new CLI versions. Setting `verifyPatterns` replaces the list for that cycle; `additionalVerifyPatterns` appends to it. The only built-in **skip** list is the always-on test-file exclusion baked into [`ignoredVerifyPatterns`](#core-options) (`**/*.spec.*`, `**/*.test.*`, `**/__tests__/**`, `**/__mocks__/**`); anything you add to `ignoredVerifyPatterns` is unioned on top. Non-code files simply don't match the patterns above.
</Note>

<Note>
  Prefer the [`ironbee browser` / `node` / `python` / `backend` / `android` / `terminal` commands](/cli/guides/verification#enable-or-disable-a-platform) for turning cycles on and off; they write `<cycle>.enable` and re-render artifacts for you. Reach for `verifyPatterns` only when you need to change *which files* a cycle covers.
</Note>

```json theme={null}
{
  "browser": {
    "additionalVerifyPatterns": ["*.mdx"]
  },
  "backend": {
    "verifyPatterns": ["api/**/*.go", "controllers/**/*.java"]
  }
}
```

***

## Verification context

Controls the [path-scoped verification guidance](/cli/guides/verification-context) IronBee injects from `.ironbee/VERIFICATION.md` files. On by default; these keys are **read live** at verification time, so changes take effect on the next session without re-rendering artifacts.

| Key                                | Type      | Default   | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ---------------------------------- | --------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `verification.context.enable`      | `boolean` | `true`    | Master switch. When the first verification tool call of a cycle fires, the relevant `.ironbee/VERIFICATION.md` files for the changed paths are injected into the agent's context. Advisory only, never gates. Opt out with `false`.                                                                                                                                                                                                                                                                                                  |
| `verification.context.source`      | `string`  | `"git"`   | Where the changed-path set comes from. `"git"` = working tree (staged + unstaged + untracked) ∪ the last `commitDepth` commits, with an `actions.jsonl` fallback when the project isn't a git repo. `"actions"` = IronBee's own `file_change` events only (no git subprocess).                                                                                                                                                                                                                                                       |
| `verification.context.commitDepth` | `number`  | `1`       | How many recent commits join the working tree for the `git` source. `0` = uncommitted work only. Ignored when `source` is `"actions"`.                                                                                                                                                                                                                                                                                                                                                                                               |
| `verification.context.maxBytes`    | `number`  | `65536`   | Aggregate cap (64 KB) on the injected text. Past the cap, the least-specific (root-side) guidance is dropped first, keeping area-specific docs.                                                                                                                                                                                                                                                                                                                                                                                      |
| `verification.context.message`     | `string`  | *(unset)* | A custom instruction injected into **every** verification cycle, independent of which files changed — so it reaches the verifier even on a manual no-change verify (where the path-scoped `VERIFICATION.md` injection is empty). Two forms: literal inline text, or a `file:<path>` reference whose contents are read (path relative to the project dir; a leading `~` expands to your home dir). Rendered first and **never truncated** (it reserves its bytes off the `maxBytes` budget). Layered across global / project / local. |

```json theme={null}
{
  "verification": {
    "context": {
      "commitDepth": 0,
      "message": "Always confirm the health endpoint returns 200 before passing."
    }
  }
}
```

<Note>
  Earlier CLI versions used a top-level `verificationContext.*` namespace. These keys now live under `verification.context.*`; update any scripts or committed config that still reference the old names.
</Note>

***

## Service identity

The `service` section is the CLI's **shared identity**: one credential and one stage selector that every IronBee service — the event-ingest collector, the read-side API (used by [`ironbee verify`](/cli/guides/verification-jobs) and the o11y trace tools), and the Console links — resolves from. [`ironbee login`](/cli/guides/authentication) writes it for you; you'd only set it by hand to self-host or to run in CI. See [Authentication](/cli/guides/authentication) for the difference between the two credentials.

| Key                  | Type     | Default                                 | Description                                                                                                                                                                                                                                                                                                                                                                                                          |
| -------------------- | -------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `service.domain`     | `string` | `ironbee.ai`                            | The single **stage selector**. Every service URL derives from it when not set explicitly: the collector at `collector.service.<domain>`, the API at `api.service.<domain>`, the Console at `console.<domain>`. `ironbee login` persists the domain you authenticated against when the hosts are standard-shaped (a non-standard, self-hosted deployment keeps explicit URLs instead). Env: `IRONBEE_SERVICE_DOMAIN`. |
| `service.oauthToken` | `string` | *(unset)*                               | Personal OAuth access token written by `ironbee login`. The CLI's default credential, shared by the collector and the API. Env: `IRONBEE_SERVICE_OAUTH_TOKEN`.                                                                                                                                                                                                                                                       |
| `service.apiKey`     | `string` | *(unset)*                               | Account API key, used for CI and machine-to-machine. When both credentials are set, the OAuth token is used. Env: `IRONBEE_SERVICE_API_KEY`.                                                                                                                                                                                                                                                                         |
| `api.url`            | `string` | derived: `https://api.service.<domain>` | Explicit override for the read-side API base URL ([`ironbee verify`](/cli/guides/verification-jobs), trace lookups). Rarely set — `service.domain` covers the normal cases.                                                                                                                                                                                                                                          |

<Note>
  Older configs kept the credential under `collector.oauthToken` / `collector.apiKey`. Those keys (and their `IRONBEE_OAUTH_TOKEN` / `IRONBEE_API_KEY` env vars) still work as **read fallbacks**, so nothing breaks — but new logins write `service.*`, and the `service.*` keys win when both are present.
</Note>

***

## Collector

The collector is what ships your session data to the IronBee Console. Its endpoint and credential come from the [`service` section](#service-identity) above; the keys here tune delivery (and carry the legacy credential fallbacks).

| Key                    | Type      | Default                                       | Description                                                                                                                                                                                                                  |
| ---------------------- | --------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `collector.url`        | `string`  | derived: `https://collector.service.<domain>` | Explicit endpoint override. Normally unset — it derives from `service.domain`.                                                                                                                                               |
| `collector.oauthToken` | `string`  | *(unset)*                                     | **Deprecated read fallback** for `service.oauthToken` (configs written before the `service` section). Can come from `IRONBEE_OAUTH_TOKEN` instead.                                                                           |
| `collector.apiKey`     | `string`  | *(unset)*                                     | **Deprecated read fallback** for `service.apiKey`. Can come from `IRONBEE_API_KEY` instead.                                                                                                                                  |
| `collector.enable`     | `boolean` | implicit `true` when a credential is set      | Set `false` to suspend sending while keeping credentials around. The collector activates on the **presence of a credential** (`service.*` preferred, `collector.*` fallback) — the URL always resolves via `service.domain`. |
| `collector.batchSize`  | `number`  | `100`                                         | Max events per POST.                                                                                                                                                                                                         |
| `collector.timeoutMs`  | `number`  | `10000`                                       | Per-request timeout (ms), clamped to `[1000, 60000]`.                                                                                                                                                                        |

***

## Telemetry

| Key                | Type      | Default | Description                                                                                                                                                                                                           |
| ------------------ | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `telemetry.enable` | `boolean` | `true`  | Anonymous PostHog product analytics for the CLI itself (separate from the collector pipeline). Opt out with `false`, also turns off telemetry in the devtools MCP servers. Equivalent to `ironbee telemetry disable`. |

***

## Privacy

| Key              | Type      | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| ---------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `privacy.enable` | `boolean` | `false` | [Privacy mode](/cli/advanced/privacy) is a single cross-cutting switch (all cycles) that redacts sensitive payloads from what the devtools MCP servers ship to the collector. **Opt-in, default off.** When `true`, injects `COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE=false` (tool input/output detail) and `COLLECTOR_ARTIFACTS_ENABLE=false` (screenshots, recordings) into the devtools MCP env. Devtools-side only and orthogonal to `telemetry` and `collector`. Equivalent to `ironbee privacy enable`. |

[DevTools env overrides](#devtools-mcp-overrides) are applied *after* the privacy flags, so set `ironbeeDevTools.env.COLLECTOR_ARTIFACTS_ENABLE` / `COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE` back to `"true"` to let one channel through while privacy mode is on.

***

## Issue-tracker integrations

Connect Jira, Linear, or GitHub Issues — see the [Issue Tracking guide](/cli/guides/issue-tracking) for the setup flows (`ironbee integrations <provider> setup`) and what the integration does. A provider activates by **configuration presence** (a configured credential turns it on; GitHub is on whenever the `gh` CLI is authenticated); its `enable` key is an opt-out kill-switch.

<Warning>
  **Secrets belong in the global config** (`~/.ironbee/config.json`) — `setup` writes them there for you. Installed artifacts carry only a `${file:…}` reference to the global config, so no token is ever baked into a committed file. In CI, supply them via the [credential env vars](/cli/configuration/environment-variables#issue-tracker-credentials) instead.
</Warning>

### Jira

| Key                                | Type       | Default                     | Description                                                                                                                                                                                                                     |
| ---------------------------------- | ---------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `integrations.jira.baseUrl`        | `string`   | *(unset — integration off)* | Jira base URL (e.g. `https://acme.atlassian.net`). Not a secret — can be team-shared (project config) or per-user (global, where `setup` writes it). Required for the integration to be configured.                             |
| `integrations.jira.email`          | `string`   | *(unset)*                   | Jira **Cloud** identity, paired with `apiToken`. Per-user — keep it in the global config (Server/DC deployments leave it unset).                                                                                                |
| `integrations.jira.apiToken`       | `string`   | *(unset)*                   | Jira **Cloud** API token — **secret**, global config only. CI: `IRONBEE_JIRA_API_TOKEN`.                                                                                                                                        |
| `integrations.jira.pat`            | `string`   | *(unset)*                   | Jira **Server/DC** personal access token — **secret**, global config only. CI: `IRONBEE_JIRA_PAT`.                                                                                                                              |
| `integrations.jira.deployment`     | `string`   | *(inferred)*                | `cloud` or `server`. Inferred from the credential shape; set explicitly to pin.                                                                                                                                                 |
| `integrations.jira.defaultProject` | `string`   | *(unset)*                   | Default Jira project key for creates and searches (e.g. `PROJ`). Committed.                                                                                                                                                     |
| `integrations.jira.projectKeys`    | `string[]` | `[]`                        | Allow-list of issue-key prefixes accepted when [attributing issues](/cli/guides/issue-tracking#vcs-linkage-sessions-to-prs-and-issues) from branch/commit/PR text — kills `UTF-8` / `SHA-256`-style false positives. Read live. |
| `integrations.jira.writeEnabled`   | `boolean`  | `false`                     | Whether the [write tiers](/cli/guides/issue-tracking#read-only-by-default-write-gating) (comment, attach, transition, create/link, report) are enabled. Read-only integrations still read, search, and attribute.               |
| `integrations.jira.enable`         | `boolean`  | `true` *(when configured)*  | Opt-out kill-switch — `false` suspends the integration without deleting its config. Equivalent to `ironbee integrations jira disable`.                                                                                          |

### Linear

| Key                                | Type       | Default                         | Description                                                                                                                                            |
| ---------------------------------- | ---------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `integrations.linear.apiKey`       | `string`   | *(unset — integration off)*     | Linear API key (`lin_api_…`) — **secret**, global config only. CI: `IRONBEE_LINEAR_API_KEY`.                                                           |
| `integrations.linear.oauth`        | `boolean`  | `false`                         | Set `true` when `apiKey` is an **OAuth access token** rather than a personal key (changes how it's sent).                                              |
| `integrations.linear.defaultTeam`  | `string`   | *(unset)*                       | Default Linear team key for creates and searches (e.g. `ENG`). Committed.                                                                              |
| `integrations.linear.teamKeys`     | `string[]` | `[]`                            | Allow-list of issue-key prefixes for attribution — same role as Jira's `projectKeys` (also disambiguates the two when both are configured). Read live. |
| `integrations.linear.workspace`    | `string`   | *(unset)*                       | Workspace URL slug (the `acme` in `linear.app/acme`), used to build issue browse links in the attribution data. Unset → no browse URL (graceful).      |
| `integrations.linear.baseUrl`      | `string`   | Linear's cloud GraphQL endpoint | Rare override for a proxy endpoint.                                                                                                                    |
| `integrations.linear.writeEnabled` | `boolean`  | `false`                         | Same write gating as Jira.                                                                                                                             |
| `integrations.linear.enable`       | `boolean`  | `true` *(when configured)*      | Opt-out kill-switch. Equivalent to `ironbee integrations linear disable`.                                                                              |

### GitHub Issues

| Key                                | Type      | Default                               | Description                                                                                                                                                                                                              |
| ---------------------------------- | --------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `integrations.github.enable`       | `boolean` | `true` *(when `gh` is authenticated)* | Opt-out kill-switch. GitHub is driven through the `gh` CLI and auto-activates when `gh` is installed and authenticated — no credential is stored. `false` suspends it regardless.                                        |
| `integrations.github.writeEnabled` | `boolean` | `false`                               | Whether the write operations (`gh issue comment` / `close` / `edit`, the verification report) are allowed. Self-enforced by the agent (`gh` is always shell-reachable), unlike Jira/Linear's mechanical gate. Read live. |

***

## VCS linkage

Links each session to the pull request it produced and the issues that PR closes — the join key behind the Console's per-issue cost and verification views. A **sub-feature of analytics**: the effective switch is `analytics.enable` *and* `vcs.enable`, and it runs in every mode (enforce / assist / monitoring-only). See [Issue Tracking → VCS linkage](/cli/guides/issue-tracking#vcs-linkage-sessions-to-prs-and-issues).

| Key                     | Type      | Default                                        | Description                                                                                                                                                                                                                                                                                |
| ----------------------- | --------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `vcs.enable`            | `boolean` | implicit `true` when a collector is configured | Master switch for the linkage — the git-ref stamp, PR resolution, issue attribution, and the `vcs_link` events. **Note:** it sends repository and *branch names* to the Collector; branch names can carry sensitive text. Independent of [privacy mode](/cli/advanced/privacy). Read live. |
| `vcs.issueTtlSeconds`   | `number`  | `600`                                          | Cache TTL for successful / not-found resolutions. Short — a PR can be opened or an issue transitioned at any moment.                                                                                                                                                                       |
| `vcs.resolveTtlSeconds` | `number`  | `3600`                                         | Cache TTL for resolutions that can't improve on retry (no token, no remote, rejected credentials).                                                                                                                                                                                         |
| `vcs.stampDirty`        | `boolean` | `false`                                        | Probe the working tree for uncommitted changes during the git-ref stamp. Off by default — it's the most expensive part of the stamp and scales with repo size.                                                                                                                             |
| `vcs.timeoutMs`         | `number`  | `5000`                                         | Per-request timeout for PR / issue resolution (always in a detached background worker, never a blocking hook). Clamped to `[1000, 60000]`.                                                                                                                                                 |

***

## Web console

| Key           | Type     | Default                             | Description                                                                                                                                                                                                                                                                                                                                    |
| ------------- | -------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `console.url` | `string` | derived: `https://console.<domain>` | Explicit Console base URL override, used to build the `🔗 View in IronBee` timeline deep-links in [issue-tracker reports](/cli/guides/issue-tracking#using-it-ironbee-issue-track). Normally unset — it derives from [`service.domain`](#service-identity), which `ironbee login` persists, so self-hosted consoles link correctly. Read live. |

***

## File change capture

| Key                            | Type      | Default | Description                                                                                                          |
| ------------------------------ | --------- | ------- | -------------------------------------------------------------------------------------------------------------------- |
| `fileChange.captureChangeset`  | `boolean` | `false` | When `true`, each `file_change` event carries a hunks-only unified diff. Off by default (events stay metadata-only). |
| `fileChange.maxChangesetBytes` | `number`  | `65536` | Hard cap (64 KB) on the diff string, larger diffs are truncated with a footer.                                       |

***

## Import

| Key                  | Type     | Default | Description                                                                                                                              |
| -------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `import.concurrency` | `number` | `4`     | Default parallelism for [`ironbee import`](/cli/guides/importing-sessions). The `--concurrency` flag overrides it. Clamped to `[1, 32]`. |

***

## Statusline (Claude Code only)

Integrates session status into Claude Code's statusline while preserving any statusline you already have. Manage it with `ironbee claude statusline enable` / `disable`.

| Key                                 | Type      | Default                                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ----------------------------------- | --------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `statusLine.enable`                 | `boolean` | implicit `true` when configured / collector set | Master switch for the statusline integration.                                                                                                                                                                                                                                                                                                                                                                                              |
| `statusLine.renderDefault`          | `boolean` | `false`                                         | When you have no existing statusline, `true` renders a minimal model + context-% line instead of staying silent.                                                                                                                                                                                                                                                                                                                           |
| `statusLine.emitMinIntervalSeconds` | `number`  | `10`                                            | Minimum seconds between emitted status events. `0` disables the throttle.                                                                                                                                                                                                                                                                                                                                                                  |
| `statusLine.refreshInterval`        | `number`  | *(unset)*                                       | Claude Code's own timer-based statusline refresh, in seconds.                                                                                                                                                                                                                                                                                                                                                                              |
| `statusLine.skipUnchanged`          | `boolean` | `false`                                         | Skip a `session_status` emit when its resource-metric signature (model, context window, cost, rate-limits) is identical to the last one. Default `false` — every throttle-passing tick emits even if unchanged (a heartbeat, so a long sub-agent delegation with flat main-thread metrics still produces points). Set `true` to emit only on a genuine change (lower volume, gaps while flat). The throttle applies either way. Read live. |

***

## Claude OAuth access (Claude Code only)

Controls whether IronBee may read your Claude Code OAuth token to fill statusline rate-limits for plans whose statusline JSON omits them (team / enterprise). Manage with `ironbee claude oauth-access enable` / `disable` / `status`. See [Claude Code → Claude OAuth access](/cli/clients/claude-code#claude-oauth-access).

| Key                                  | Type      | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------ | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `claude.oauthAccess.enable`          | `boolean` | `true`  | Whether IronBee may read the Claude OAuth token (macOS Keychain / `~/.claude/.credentials.json`) and call OAuth-scoped endpoints. Opt out with `false`. Claude-only.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `claude.oauthAccess.usageTtlSeconds` | `number`  | `60`    | Cache TTL for the rate-limit fetch, the token read + usage call fire at most once per this interval, however often the statusline ticks. `0` = every tick.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `claude.autoModeAllowlist.enable`    | `boolean` | `true`  | Whether IronBee writes the [auto-mode allowlist carve-out](/cli/clients/claude-code#auto-mode-and-the-verifier) for the verifier into `.claude/settings.local.json`. Claude Code's auto-mode "Content Integrity" classifier can false-positive on IronBee's legitimate verdict submissions; when enabled (default), install adds one narrow rule that exempts **only** that command from the block (every other auto-mode protection stays in force). Written only when verification is active (enforce/assist) and inert when the host isn't in auto mode. Opt out with `false` — takes effect on the next `ironbee install`. Claude-only.                                                       |
| `claude.trustWorkspace.enable`       | `boolean` | `true`  | Whether `ironbee install` marks the project [trusted](/cli/clients/claude-code#workspace-trust) in Claude Code's machine-global `~/.claude.json` when it isn't already. Claude Code 2.1.x ignores a project's committed `permissions.allow` (the devtools + `Bash(ironbee *)` entries IronBee writes) until the workspace is trusted, and the trust dialog doesn't re-appear once onboarding has been seen — so without this the entries stay silently disabled and the agent gets prompted on every devtools/`ironbee` call. Best-effort and idempotent: it only ever flips a missing/false flag to `true` and never clobbers other `~/.claude.json` content. Opt out with `false`. Claude-only. |

***

## Codex (Codex CLI only)

Controls how the Codex verification cycle is driven. Manage with `ironbee codex verifier mode <sub-agent|main-agent>`. See [Codex → How verification is delivered](/cli/clients/codex#how-verification-is-delivered).

| Key                   | Type     | Default     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| --------------------- | -------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `codex.verifier.mode` | `string` | `sub-agent` | How the Codex verification cycle runs. `"sub-agent"` (default) delegates to the [`ironbee-verifier`](/cli/clients/codex) custom agent (per-agent MCP, slim delegation skill/rule/command), keeping the heavy devtools output out of the main conversation. `"main-agent"` makes the **main** agent drive the devtools tools directly (session-level MCP server, no verifier sub-agent, inline skill/rule/command) — the Cursor-style fallback for when Codex's sub-agent machinery regresses. Re-renders the Codex client. Codex-only. |

***

## Cursor (Cursor only)

Controls whether IronBee may read your local Cursor session token and call Cursor's per-user usage API to enrich [Cursor analytics](/cli/clients/cursor#session-analytics) with exact per-request tokens and cost. Manage with [`ironbee cursor api-access enable` / `disable` / `status`](/cli/clients/cursor#session-analytics).

| Key                                | Type      | Default | Description                                                                                                                                                                                                                                                                                                                                                                                                             |
| ---------------------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cursor.apiAccess.enable`          | `boolean` | `true`  | Whether IronBee may read the local Cursor session token (`state.vscdb` / macOS Keychain) and call Cursor's usage API (`api2.cursor.sh`) for exact per-request tokens, cost, and rate-limit windows. When off or unavailable, Cursor analytics degrade to **structure + line data only** (cost/tokens omitted). Opt out with `false`. Parity with `claude.oauthAccess`. Cursor-only; read live (not artifact-affecting). |
| `cursor.apiAccess.usageTtlSeconds` | `number`  | `60`    | Cache TTL for the usage/rate-limit fetch — the token read + usage call fire at most once per this interval. `0` = every request.                                                                                                                                                                                                                                                                                        |

***

## OTEL collector

IronBee runs a local OTEL collector daemon that turns Claude Code's OTLP export into `session_context` (context-usage) events. One daemon per machine, started and reaped automatically. Manage it with [`ironbee claude otel`](/cli/clients/claude-code#otel-collector).

| Key                             | Type      | Default                                        | Description                                                                                                     |
| ------------------------------- | --------- | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `otel.enable`                   | `boolean` | implicit `true` when a collector is configured | Master switch for the local OTEL pipeline. Also gates whether the OTEL env block is written to `settings.json`. |
| `otel.port`                     | `number`  | `15986`                                        | Loopback port the daemon binds to (one daemon per machine).                                                     |
| `otel.idleTimeoutSeconds`       | `number`  | `600`                                          | Daemon self-reaps after this many seconds with no activity; restarted on the next session.                      |
| `otel.ensureMinIntervalSeconds` | `number`  | `30`                                           | Throttle for the liveness check fired from per-tool hooks.                                                      |
| `otel.emitMinIntervalSeconds`   | `number`  | `0`                                            | Per-session `session_context` emit throttle. `0` = emit on every API request (full context-growth series).      |

***

## Devtools MCP overrides

All cycles are served by a single **`ironbee-devtools`** compose MCP server, customized via the `ironbeeDevTools` keys:

| Key                   | Description                                                                                                                                   |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `ironbeeDevTools.env` | Extra env vars merged into the default MCP server entry.                                                                                      |
| `ironbeeDevTools.mcp` | Full replacement of the MCP server config, supply your own `command`+`args` (stdio) or `url` (HTTP), e.g. to point at a local devtools build. |

```json theme={null}
{
  "ironbeeDevTools": {
    "env": { "BROWSER_HEADLESS_ENABLE": "true" }
  }
}
```

<Note>
  IronBee always sets its own invariants (`PLATFORM=compose`, `COMPOSE_PLATFORMS`, metadata flags) last; these can't be overridden.
</Note>

<Info>
  The legacy per-cycle keys (`browserDevTools`, `nodeDevTools`, `pythonDevTools`, `backendDevTools`, `androidDevTools`, `terminalDevTools`) still exist for back-compat but **no longer feed the compose server** — use `ironbeeDevTools` to customize the one server that serves every cycle.
</Info>

***

## Automatic pipeline keys

These sections auto-enable when a collector is configured and rarely need manual tuning. Browse them with `ironbee config list` or the [TUI](/cli/guides/interactive-mode) Configuration area:

* **`recording:`** session recording for the browser and Android cycles (`recording.enable`); the node, python, backend, and terminal cycles never trigger it.
* **`jobQueue:`** the file-backed background queue that feeds the collector (`jobQueue.enable`, flush thresholds).
* **`analytics:`** per-session structural analytics and how often they emit (`analytics.enable`, `analytics.emitOnStop`, and per-event opt-in/opt-out flags).

***

## Common setups

### Ignore extra files

Test files (`**/*.spec.*`, `**/*.test.*`, `**/__tests__/**`, `**/__mocks__/**`) are **excluded by default** — you don't need to list them. Add `ignoredVerifyPatterns` only to skip *more* paths (e.g. generated code, fixtures); your entries are unioned with the built-in test-file defaults:

```json theme={null}
{
  "ignoredVerifyPatterns": ["**/generated/**", "**/*.gen.ts", "fixtures/**"]
}
```

### Backend-only project (no browser cycle)

```json theme={null}
{
  "browser": { "enable": false },
  "backend": { "enable": true }
}
```

Or use the CLI: `ironbee browser disable && ironbee backend enable`.

### Monitoring only (no enforcement)

```json theme={null}
{
  "verification": { "enable": false }
}
```

### Assist mode (verify on demand, never gated)

```json theme={null}
{
  "verification": { "auto": false }
}
```

Or use the CLI: `ironbee verification auto disable`.

### Capture code diffs in analytics

```json theme={null}
{
  "fileChange": { "captureChangeset": true }
}
```

***

## What's next?

<CardGroup cols={2}>
  <Card title="Environment variables" icon="variable" href="/cli/configuration/environment-variables">
    Overrides that take precedence over the config files.
  </Card>

  <Card title="Runtime files" icon="folder" href="/cli/advanced/runtime-files">
    Where these config files live and what else IronBee writes to disk.
  </Card>
</CardGroup>
