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

# Ori Configuration

> How to configure Ori, from a single shell to a managed fleet, plus every setting it reads

Ori has one set of settings and several ways to supply them. A setting is
named the same everywhere, so the same name works in your shell, in a config
file, and in an MDM profile. Pick the mechanism that matches who owns the
decision, then use the [reference](#settings-reference) at the bottom of this
page for the settings themselves.

## Ways to configure Ori

* **Your shell.** Export a variable for the current session, or put it in your
  shell profile or process manager. Good for one person on one machine.
* **`~/.ori/config.json`.** Your own defaults, applied to every project you
  work on.
* **`.ori/config.json` in a project.** Settings that belong to a repository and
  should apply to everyone working in it.
* **Command-line flags.** Six update settings also have flags, listed
  [below](#command-line-flags).
* **A machine policy file.** `/etc/ori/config.json`, or
  `C:\ProgramData\ori\config.json` on Windows. Owned by whoever administers the
  machine, and it beats a flag.
* **macOS managed preferences.** An MDM payload for the
  `com.openrouter.ori` preference domain. Beats everything, including the
  machine file.

If you administer a fleet, read [Configuring managed
machines](#configuring-managed-machines).

## Which source wins

Every setting resolves through the same list, and the first source that
carries a valid value for it wins:

1. macOS managed preferences (`com.openrouter.ori`)
2. The machine policy file, `/etc/ori/config.json`
3. A command-line flag
4. The process environment, meaning whatever your shell exports
5. `.ori/config.json` in the working directory
6. `~/.ori/config.json` in your home directory
7. Ori's own default

A project file beats your home file, matching how most tools treat local
configuration. The two administrator sources sit above flags, so a policy set
on the machine cannot be turned off from a shell, a project, or a flag. The one
exception is `ORI_NO_UPDATE_CHECK`, which only suppresses the update check when
no `--auto-update` flag is passed; `ORI_DISABLE_AUTOUPDATER` and
`ORI_DISABLE_UPDATES` are the settings to use when a policy has to hold.

Two groups of settings don't follow this list everywhere:

* **Administrator-only settings.** `ORI_REQUIRED_ORGANIZATION_ID`, `ORI_REQUIRED_WORKSPACE_ID`, `ORI_REQUIRED_REGION`, and `ORI_CREDENTIAL_STORAGE` are read only from macOS managed preferences and the machine policy file. Ori ignores them in your shell, a flag, or either `config.json`, and `ori doctor` names each copy it ignored. See [Configuring managed machines](#configuring-managed-machines).
* **Settings that choose where a credential goes.** `ORI_OPENROUTER_BASE_URL`, `ORI_OPENROUTER_ENDPOINT`, `ORI_RELEASE_BASE_URL`, `ORI_OPENROUTER_OIDC_ISSUER`, and `ORI_OPENROUTER_OIDC_CLIENT_ID` are ignored in a project's `.ori/config.json`, so a cloned repository can't send your key or your sign-in somewhere else. Set them in your shell, `~/.ori/config.json`, or an administrator source.

A missing file is fine, and a malformed one contributes nothing. A value Ori
cannot make sense of is skipped per setting, so one bad entry does not discard
the rest of a file, and the next source down answers instead.

Where a setting below is described as a switch, Ori reads an empty value, `0`,
and `false` as off, and any other value as on. `1` is the conventional way to
turn one on.

### Config file shape

A config file can carry an `env` object of plain strings, named fields, or
both. The two spellings feed the same setting:

```json theme={null}
{
  "channel": "stable",
  "autoUpdate": { "level": "patch", "intervalMs": 21600000 },
  "env": {
    "ORI_DISABLE_UPDATES": "1"
  }
}
```

### Command-line flags

Only `--auto-update`, `--auto-update-restart`, `--update-interval`,
`--drain-timeout`, `--alpha`, and `--stable` name a setting that also has a
variable, so those are the only flags that take part in the list above. Every
other flag is an argument to its command.

## Configuring managed machines

Two mechanisms are meant for administrators, and both outrank anything a user
can set. Every setting in the [reference](#settings-reference) works in either
one.

### macOS: managed preferences

Deliver a custom-settings payload for the preference domain
`com.openrouter.ori` from Jamf, Kandji, Intune, or any MDM that writes
managed preferences. Use the setting name as the key. Booleans, numbers, and
strings all work; Ori converts them:

```xml theme={null}
<dict>
    <key>ORI_MODEL</key>
    <string>anthropic/claude-sonnet-4.5</string>
    <key>ORI_DISABLE_OAUTH_LOGIN</key>
    <true/>
    <key>ORI_UPDATE_INTERVAL</key>
    <integer>21600000</integer>
</dict>
```

Ori reads the per-user profile at
`/Library/Managed Preferences/<username>/com.openrouter.ori.plist` and the
device-wide one at `/Library/Managed Preferences/com.openrouter.ori.plist`.
Nothing else on the machine can override what lands there.

For ordinary settings, the per-user profile wins as a whole when it exists, and Ori doesn't merge it with the device-wide one. The administrator-only settings in the next sections are different: Ori reads them from the per-user profile, the device-wide profile, and the machine policy file separately and combines them, so a device-wide restriction still applies when a per-user profile leaves it out. Ori takes the username from the operating system, not from `USER` or `LOGNAME`. Deliver the payload as forced settings; Ori doesn't implement set-once preferences.

### Any platform: the machine policy file

Write JSON to `/etc/ori/config.json` (or `C:\ProgramData\ori\config.json` on
Windows) with your settings in the `env` object:

```json theme={null}
{
  "channel": "stable",
  "env": {
    "ORI_DISABLE_UPDATES": "1",
    "ORI_REQUIRE_LOGIN": "1",
    "ORI_MODEL": "anthropic/claude-sonnet-4.5"
  }
}
```

Ship the file with the rest of your machine configuration, the same way you
ship any other policy file. A user cannot remove it without administrator
rights, and no flag other than `--auto-update` against
`ORI_NO_UPDATE_CHECK` can argue with it.

On Windows, the path is fixed at `C:\ProgramData\ori\config.json`. Ori doesn't use the `ProgramData` or `SystemDrive` environment variables to find it, because any user can change them. If you staged the file under a redirected `ProgramData` or on a drive other than `C:`, move it to `C:\ProgramData\ori\config.json`; until you do, Ori treats the machine as having no policy file.

### Restrict which OpenRouter account Ori can use

Set `ORI_REQUIRED_ORGANIZATION_ID`, `ORI_REQUIRED_WORKSPACE_ID`, or both to require that every OpenRouter key Ori uses belongs to your organization or to one workspace in it. Before Ori uses or saves a key, it looks up the key's owner with OpenRouter and refuses a key that doesn't match. This covers API keys, browser sign-in, OIDC sessions, and the key Ori passes to the harnesses it launches.

* **`ORI_REQUIRED_ORGANIZATION_ID`.** Your OpenRouter organization ID. A personal key is refused even when the person who created it belongs to the organization.
* **`ORI_REQUIRED_WORKSPACE_ID`.** An OpenRouter workspace UUID. Browser sign-in asks OpenRouter for a key in that workspace. When you set both keys, a key must match both.

Ori looks the owner up live at least once per command, with a five-second timeout, and never saves the answer to disk. A failed lookup refuses the key; it doesn't fall back to an earlier answer. The restriction applies to Ori's own sign-in only. A credential that a harness gets through its own sign-in isn't checked, and Ori interns are unaffected.

### Lock Ori to one region

Set `ORI_REQUIRED_REGION` to `global`, `us`, or `eu` to send every Ori request through one OpenRouter data region. The value must be one of those three exactly, in lowercase with no spaces; a URL or an alias such as `europe` is invalid.

While the lock applies, Ori derives every OpenRouter URL from the region and ignores `ORI_OPENROUTER_REGION`, `ORI_OPENROUTER_BASE_URL`, `ORI_OPENROUTER_ENDPOINT`, and the `region` and `endpoint` fields from every other source. Ori warns when one of those settings points somewhere else, naming the setting and where it came from. `ori auth region` refuses to change the region, `ori login` skips saving one, and every harness Ori launches routes through the locked region. A lock without `ORI_REQUIRED_ORGANIZATION_ID` or `ORI_REQUIRED_WORKSPACE_ID` doesn't look up who owns the key.

### Choose where credentials are stored

Set `ORI_CREDENTIAL_STORAGE` to choose how Ori stores saved logins, OIDC sessions, and MCP credentials on a machine:

* **`protected`.** Keys held by the operating system: the macOS Keychain, the Secret Service, or systemd user credentials on Linux.
* **`file`.** Keys held in files under `~/.ori/auth/plaintext/`, readable only by the user. This doesn't protect credentials from anyone who can copy the home directory.

Without this setting, Ori uses its release default, which is `file` while Ori releases are unsigned. Changing the value doesn't move existing credentials, so users sign in again after a switch, and switching back finds the earlier credentials unchanged. With `protected` on macOS, users see a Keychain approval prompt after each update until releases are signed. On Windows, saved logins can't use `protected` storage; OIDC sessions and MCP credentials can.

### When administrator settings disagree or can't be read

Ori fails closed on the administrator-only settings, so a typo never looks like it worked:

* A malformed value, such as an empty organization ID, a workspace ID that isn't a UUID, a region other than `global`, `us`, or `eu`, or a misspelled `ORI_REQUIRED_*` name, makes the policy invalid.
* Two administrator sources with different values for the same setting make the policy conflicting. Equal values agree, and a workspace from one source can narrow an organization from another.
* An administrator file or profile that exists but can't be read or parsed makes the policy unreadable.

While the account or region policy is invalid, conflicting, or unreadable, every command that would use an OpenRouter key refuses until you fix the source. While `ORI_CREDENTIAL_STORAGE` is invalid, saved logins, OIDC sessions, and MCP credentials refuse, but `OPENROUTER_API_KEY` keeps working. Commands that need no key keep working in both cases. A source you remove stops applying on the next read.

Each refusal has a stable code that `--output json` reports as its `code`, so scripts can act on it without parsing text:

| Code | Meaning |
| - | - |
| `ORI_CLI_MANAGED_AUTH_POLICY_INVALID` | An administrator setting is malformed, or a source can't be read. |
| `ORI_CLI_MANAGED_AUTH_POLICY_CONFLICTING` | Two administrator sources disagree. |
| `ORI_CLI_MANAGED_AUTH_ORGANIZATION_MISMATCH` | The key belongs to a different organization, or to a personal account. |
| `ORI_CLI_MANAGED_AUTH_WORKSPACE_MISMATCH` | The key belongs to a different workspace. |
| `ORI_CLI_MANAGED_AUTH_IDENTITY_UNAVAILABLE` | Ori couldn't confirm who owns the key. |
| `ORI_CLI_MANAGED_AUTH_REGION_LOCKED` | `ori auth region` tried to change a locked region. |
| `ORI_CLI_MANAGED_AUTH_METHOD_DISABLED` | An administrator turned off the sign-in method a saved session uses. |
| `ORI_CLI_MANAGED_CREDENTIAL_STORAGE_INVALID` | `ORI_CREDENTIAL_STORAGE` is malformed, conflicting, or unreadable. |

### Check what applies on a machine

Run `ori auth` to see the account and region policy, which administrator sources set it, the required organization and workspace, whether the current key matches, the locked region and any settings that conflict with it, and the credential storage and who chose it. `ori auth` reports the policy without failing on it. Run `ori doctor` to see administrator-only settings that Ori ignored because a user, a project, or the shell set them, and any setting that conflicts with a region lock.

### Roll out a new administrator setting

Deploy an Ori release that understands a setting before you deploy the setting:

* `ORI_REQUIRED_ORGANIZATION_ID` and `ORI_REQUIRED_WORKSPACE_ID` need Ori 0.15.1 or later. Earlier releases ignore them.
* `ORI_REQUIRED_REGION`, `ORI_CREDENTIAL_STORAGE`, `ORI_DISABLE_OIDC_LOGIN`, and the fixed Windows path need a release later than 0.15.5. A release that doesn't know `ORI_REQUIRED_REGION` reads it as a misspelled restriction and refuses every key, and one that doesn't know `ORI_CREDENTIAL_STORAGE` ignores it.

Keep API keys and management credentials out of every profile and policy file.

### Two recipes

**Ship Ori through your own tooling.** Set `ORI_DISABLE_UPDATES` to `1`. Ori
stops checking for releases, never prints an update notice, and answers
`ori update` with a message saying the installation is managed by your
organization. Use `ORI_DISABLE_AUTOUPDATER` instead to keep the background
updater quiet while users can still update by hand, and add
`"channel": "stable"` to hold the fleet on one channel even against an
`--alpha` flag.

**Force browser sign-in.** Set `ORI_DISABLE_API_KEY_LOGIN` and
`ORI_DISABLE_ENV_KEY_LOGIN` to `1` so the only way in is browser sign-in, and
`ORI_REQUIRE_LOGIN` to `1` so an `OPENROUTER_API_KEY` a developer happens to
have exported is refused rather than spent. These settings decide how a
credential may be obtained, not which OpenRouter account or organization it
belongs to, and a key saved before you turned a method off still works. To control which account Ori can use, add `ORI_REQUIRED_ORGANIZATION_ID`, as the next recipe shows.

**Keep the fleet on your organization.** Combine the sign-in switches with an account restriction and, if you need it, a region lock. In a `com.openrouter.ori` payload:

```xml theme={null}
<dict>
    <key>ORI_REQUIRED_ORGANIZATION_ID</key>
    <string>YOUR_OPENROUTER_ORGANIZATION_ID</string>
    <key>ORI_REQUIRED_WORKSPACE_ID</key>
    <string>YOUR_OPENROUTER_WORKSPACE_UUID</string>
    <key>ORI_REQUIRED_REGION</key>
    <string>eu</string>
    <key>ORI_CREDENTIAL_STORAGE</key>
    <string>protected</string>
    <key>ORI_DISABLE_API_KEY_LOGIN</key>
    <true/>
    <key>ORI_DISABLE_ENV_KEY_LOGIN</key>
    <true/>
</dict>
```

Or in the machine policy file:

```json theme={null}
{
  "env": {
    "ORI_REQUIRED_ORGANIZATION_ID": "YOUR_OPENROUTER_ORGANIZATION_ID",
    "ORI_REQUIRED_WORKSPACE_ID": "YOUR_OPENROUTER_WORKSPACE_UUID",
    "ORI_REQUIRED_REGION": "eu",
    "ORI_CREDENTIAL_STORAGE": "protected",
    "ORI_DISABLE_API_KEY_LOGIN": "1",
    "ORI_DISABLE_ENV_KEY_LOGIN": "1"
  }
}
```

Leave out `ORI_REQUIRED_WORKSPACE_ID` to allow any workspace in the organization, and leave out `ORI_REQUIRED_REGION` to let users choose their region. Copying this block into a user or project `config.json` creates no policy.

## Settings reference

Every name below works as an environment variable, as an `env` entry in any
config file, as a managed-preferences key, and in the machine policy file. The exceptions are the [administrator-only settings](#configuring-managed-machines), which work only in managed preferences and the machine policy file, and the settings that choose where a credential goes, which Ori ignores in a project's `.ori/config.json`.

<Note>
  Ori 0.14 and earlier read less than that. Config files and the machine
  policy file carry the update and installation settings plus the sign-in
  method Ori remembers, every other name comes from the environment only, and
  macOS managed preferences are not read at all, so a profile you deploy to
  those versions has no effect. Export the setting in the environment until
  the fleet is on a newer build.
</Note>

### Updates and installation

| Setting | Accepts | What it does |
| - | - | - |
| `ORI_DISABLE_UPDATES` | switch | Turns off automatic updates, hides the update notice, and makes `ori update` refuse to replace the install. Set this when your builds arrive through your own tooling. |
| `ORI_DISABLE_AUTOUPDATER` | switch | Turns off automatic updates and hides the update notice. An explicit `ori update` still runs. |
| `ORI_AUTO_UPDATE` | `off`, `patch`, `minor`, `major` | Largest version jump `ori start` and the TUI may install on their own. Defaults to `off`. |
| `ORI_CHANNEL` | `stable`, `alpha` | Release channel `ori update` and the background updater follow. With no channel set anywhere, an alpha build stays on alpha and everything else takes stable. |
| `ORI_NO_UPDATE_CHECK` | switch | Skips the background update check for this run. An explicit `--auto-update` flag overrides it wherever it came from, machine policy included, so use `ORI_DISABLE_AUTOUPDATER` for a fleet you want quiet. |
| `ORI_UPDATE_INTERVAL` | milliseconds | How long Ori waits between background update checks. |
| `ORI_UPDATE_RESTART` | `reexec`, `exit` | Whether a long-running Ori re-executes itself after an update or exits for your supervisor to restart. |
| `ORI_DRAIN_TIMEOUT` | milliseconds | How long an update waits for in-flight work to finish before restarting. |
| `ORI_INSTALL_DIR` | directory path | Where the installer writes the `ori` binary. By default it reinstalls over the `ori` already on your `PATH`, and only falls back to `~/.local/bin` for a first install. |
| `ORI_RELEASE_BASE_URL` | URL | Host that serves Ori release binaries and the `SHA256SUMS` file that verifies them. Ignored in a project's `.ori/config.json`. |

### Sign-in

| Setting | Accepts | What it does |
| - | - | - |
| `ORI_DISABLE_OAUTH_LOGIN` | switch | Removes browser sign-in from `ori login`. |
| `ORI_DISABLE_API_KEY_LOGIN` | switch | Removes pasting an API key from `ori login`. |
| `ORI_DISABLE_OIDC_LOGIN` | switch | Removes OpenRouter OIDC sign-in, including `ori login --oidc`, and refuses a saved OIDC session instead of using it. An administrator source that sets it to `0` keeps OIDC on. `ORI_DISABLE_CONNECT_LOGIN`, the earlier name, still turns OIDC off. |
| `ORI_DISABLE_ENV_KEY_LOGIN` | switch | Stops Ori accepting an `OPENROUTER_API_KEY` it finds in the environment. |
| `ORI_REQUIRE_LOGIN` | switch | Refuses to run on any credential that `ori login` did not establish, including an inherited `OPENROUTER_API_KEY` or one in a project dotenv file. |
| `ORI_FORCE_OPENROUTER_API_KEY` | switch | Always uses the `OPENROUTER_API_KEY` from the environment instead of a stored credential. |
| `ORI_OPENROUTER_OIDC_ISSUER` | URL | OpenID Connect issuer that `ori login --oidc` uses for new sessions. Ignored in a project's `.ori/config.json`. |
| `ORI_OPENROUTER_OIDC_CLIENT_ID` | client ID | OpenID Connect public client that `ori login --oidc` uses for new sessions. Ignored in a project's `.ori/config.json`. |

### Administrator-only

These settings work only in macOS managed preferences and the machine policy file. See [Configuring managed machines](#configuring-managed-machines).

| Setting | Accepts | What it does |
| - | - | - |
| `ORI_REQUIRED_ORGANIZATION_ID` | organization ID | Refuses any OpenRouter key that this organization doesn't own, including personal keys. |
| `ORI_REQUIRED_WORKSPACE_ID` | workspace UUID | Refuses any OpenRouter key outside this workspace, and asks browser sign-in for a key in it. |
| `ORI_REQUIRED_REGION` | `global`, `us`, `eu` | Sends every Ori request through this OpenRouter data region and ignores other region and endpoint settings. |
| `ORI_CREDENTIAL_STORAGE` | `protected`, `file` | Chooses OS-protected or file-backed storage for saved logins, OIDC sessions, and MCP credentials. On Windows, `protected` doesn't cover saved logins: Ori reports that encrypted storage is unsupported for them, while OIDC sessions and MCP credentials keep working. Defaults to `file` while Ori releases are unsigned. |

### Models and output

| Setting | Accepts | What it does |
| - | - | - |
| `ORI_MODEL` | model slug | Default model for `ori harness` and `ori code`. |
| `ORI_OPENROUTER_REGION` | `global`, `us`, `eu` | OpenRouter data region to route requests through. Overrides the `region` that `ori login` and `ori auth region` save. Defaults to `global`. |
| `ORI_OPENROUTER_BASE_URL` | URL | OpenRouter API base URL to send inference to, for a gateway, a proxy, or a regional host such as `https://us.openrouter.ai/api/v1`. Takes precedence over the region. Ignored in a project's `.ori/config.json`. |
| `ORI_OPENROUTER_ENDPOINT` | URL | Same as `ORI_OPENROUTER_BASE_URL`, used when that setting is empty. Ignored in a project's `.ori/config.json`. |
| `ORI_FALLBACK_MODELS` | comma-separated model slugs | Models the native harness tries in order when the run's model keeps failing. Defaults to `~google/gemini-flash-latest,~anthropic/claude-sonnet-latest`. An empty value turns fallback off. |
| `ORI_MAX_TURNS` | count | Tool-turn limit for each native harness run. No limit by default. |
| `ORI_OUTPUT` | `human`, `json` | Output mode for commands that support both. Ori otherwise picks `human` for a terminal. |
| `ORI_TELEMETRY` | `0` or `false` to disable | Turns off Ori's usage telemetry. |

### Terminal appearance

| Setting | Accepts | What it does |
| - | - | - |
| `ORI_TUI_THEME` | palette name | Built-in palette for the chat TUI. |
| `ORI_TUI_THEME_FILE` | file path | Palette file to load instead of a built-in one. |
| `ORI_TUI_DENSITY` | `compact`, `cozy`, `verbose` | How much vertical space the transcript uses. Defaults to `cozy`. |
| `ORI_TUI_WORKING_INDICATOR` | `verb`, `tokens`, `minimal`, `wave`, `bar`, `shimmer`, `glider`, `quadrant`, `meter` | Animation shown while the agent works. Defaults to `glider`. |
| `ORI_TUI_WORKING_VERB_MODE` | `rotating`, `gliding-only` | Whether the working line rotates through verbs. |
| `ORI_TUI_WORKING_CADENCE` | `calm`, `steady`, `fast` | Animation speed of the working indicator. |
| `ORI_TUI_WORKSPACE_ROW` | `top`, `bottom`, `off` | Where the workspace row sits, or `off` to hide it. |

### Files

| Setting | Accepts | What it does |
| - | - | - |
| `ORI_STATE_DIR` | directory path | Where Ori keeps its local state database. See [where Ori writes files](/docs/guides/ori/files). |
| `ORI_LOG_MAX_RUNS` | count | How many run logs Ori keeps before pruning the oldest. |
