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

# Outrider security

> Review Outrider repository permissions, execution boundaries, and credentials.

Outrider runs through GitHub Actions in a repository you configure.

Review the workflow permissions, model-provider credentials, and code changes before allowing automated runs.

## Repository access

The workflow uses the repository permissions and secrets documented below. Its access depends on the installation method and repository settings.

## Review before merge

Draft PRs and other run artifacts are inputs to maintainer review. Your team controls merges and repository protection rules.

## Exact permissions and controls

The reference below lists the supported security controls and their defaults.

***

Outrider drives an autonomous coding agent from **untrusted input**. The candidate brief is assembled from arbitrary GitHub Issue and PR text, which is the classic vector for indirect prompt injection. No single control is trusted to stop a determined injection. Six independent layers each fail safe, so an attack has to defeat all of them to cause harm. The durable controls sit outside the model's influence (deterministic code, a stripped environment, path enforcement); the model-facing layers (input wrapping, the canary) are treated as signals, never guarantees.

This page covers the agent runtime. For what the agent is allowed to change in your repo, see [Guardrails](https://docs.remyx.ai/platform/agents/outrider-configuration.md#guardrails).

## The layers

**1. L1: Trust boundary at ingestion (signal)**

Every piece of untrusted text (Issue bodies, PR text, Discussions, fetched lead content) is wrapped in `<untrusted_content source=…>` tags with a preamble instructing the agent to treat it as data, not instructions. This reduces naive injections; it is not relied on alone.

**2. L2: Capability reduction (durable)**

The spawned agent runs under a **PreToolUse Bash deny gate** delivered through `claude --settings`, fail-closed, that blocks package installs and any outbound network command. Its subprocess environment is allow-listed at launch: `GITHUB_TOKEN`, `REMYX_API_KEY` and every `INPUT_*` variable are stripped, so `printenv` or `cat` cannot surface them. The tool gate is a Claude Code feature; Codex and Backboard run with the stripped environment but without a per-tool deny gate, so on those agents the timeout and the post-session gates are the controls.

**3. L3: Credential-leak prevention (durable)**

The clone's origin is rewritten **token-less** so no credential persists in `.git/config`; the push re-authenticates with a one-shot URL. Every outbound payload (PR and Issue bodies, API calls) passes a fail-closed scrubber: a credential match **aborts** the run with `aborted_secret_in_payload`, which exits red, rather than being silently redacted.

**4. L4: Per-run canary (signal)**

The invocation template requires the agent to acknowledge the spec with a per-run canary token derived from the run id and the target repo. A missing or wrong canary is the fingerprint of an injection that hijacked the agent's output, and downgrades routing from PR to Issue (`issue_opened_canary_missing`) for a human to inspect.

**5. L5: Deterministic post-session verification (durable)**

After the session and before any push: the path block (`.github/workflows/**` is the one hard block; workflow edits are stripped from the commit and listed), the **risky-surface** flag that forces draft and labels diffs touching dependency manifests, CI, hooks, containers or shell scripts, the integration gate (new code must be invoked by a changed file), and the stub-density gate.

**6. L6: Human-in-the-loop (external)**

Nothing auto-merges. Output is a **draft PR** or a **human-review Issue**. A guard trip aborts rather than filing, and a maintainer can disable the workflow outright.

Before the agent starts, the action pre-installs the target repo's dependencies itself, so the agent never needs install permissions during the session.

### What we deliberately do not rely on

The two model-facing layers (L1 wrapping, L4 canary) are signals, not guarantees; a sufficiently clever injection can evade either. The security argument rests on the durable layers (L2, L3, L5, L6), which are deterministic code the model cannot reach.

## Where the model key lives

Outrider runs on your own provider key. Where that key sits depends on how you installed:

| Install path | Where the key goes | Who holds a copy |
| - | - | - |
| `remyxai outrider init` (default) | The provider key you connected in [Connectors](https://docs.remyx.ai/platform/configure/connectors.md#model-providers-and-coding-agents) is pushed to the repo as an Actions secret by the Remyx engine | Remyx (encrypted at rest) and the repo's secret store |
| `remyxai outrider init --github-secrets-only` | Sealed against the repo's own Actions public key **on your machine**, so it reaches GitHub as ciphertext | The repo's secret store only |
| BYOK from the app (client-sealed relay) | Studio fetches the repo's Actions public key, seals the key in your browser, and sends only the ciphertext to the engine, which forwards it to GitHub | The repo's secret store only |
| Manual install | You set the secret yourself | The repo's secret store only |

In every case the key is decrypted only inside the ephemeral runner, and the agent subprocess never sees it as an environment variable the model can print.

### BYOK: the client-sealed relay

For the app path, the engine exposes the repo's Actions public key so the browser can seal the secret before it leaves your machine:

* `GET /api/v1.0/interests/<id>/provision-action/actions-public-key` (scope `provisioning:read`) returns `repo`, `key_id`, `key`, and `sealable_secret_names`, the provider secrets the registry allows (`ANTHROPIC_API_KEY`, `ZAI_API_KEY`, `MOONSHOT_API_KEY`, `OPENAI_API_KEY`, `OPENROUTER_API_KEY`).
* `POST /api/v1.0/interests/<id>/provision-action` accepts `sealed_provider_secrets`, a map of allowed secret name to sealed ciphertext plus the `key_id` it was sealed against. A stale `key_id` (GitHub rotated the repo key) returns `409`; fetch the key again and re-seal.
* The agent's `model_key_source` records custody: `remyx` when the engine pushed a key it holds, `byok` when you sealed it. Custody is sticky across re-provisions; pass `reclaim_key_custody: true` to switch a BYOK repo back to the engine-pushed key.

BYOK serves Outrider only. [Validate](https://docs.remyx.ai/platform/agents/validate.md) runs the model server-side on the key you connected in Connectors and never pushes a secret to the repo, so a sealed key cannot serve it.

## Supply chain

* Consumers pin `remyxai/outrider@v1`. That tag moves automatically when a release is published, so a fix reaches every install at the next release. Change-controlled orgs can pin an exact release (`remyxai/outrider@v1.9.0`) and bump deliberately.
* The coding-agent CLIs (`@anthropic-ai/claude-code`, `@openai/codex`) are installed at the exact versions pinned in the action's `package.json`, with a check that the runner's Node meets the CLI's declared floor; a floating install would pull whatever shipped overnight into every scheduled run at once. Backboard R-CLI is installed from its vendor installer.
* Python dependencies come from a pinned requirements file. No system packages are installed (`apt` is never called); PDF handling uses a pure-Python library.
* Steps that only improve the agent's inputs (optional PDF support, code-search indexing) are best-effort and never fail the run.

## What the Remyx engine holds

For an `init` install the engine holds a hash of your Remyx API key, the repo's scoped automation key (which can read one interest, refresh recommendations, and mint `remyx-ai[bot]` tokens for that repo), and, unless you used `--github-secrets-only` or BYOK, the provider key you connected, encrypted at rest. Each run reports its telemetry back (status, cost and tokens, the selection reasoning, the artifact URLs) for the [agent report](https://docs.remyx.ai/platform/agents/overview.md#the-agent-report) and [Reports](https://docs.remyx.ai/platform/review/reports.md). The repo clone stays on the ephemeral runner.

## Next steps

[Run Outrider on a repository](https://docs.remyx.ai/tutorials/outrider-repository.md) · [Use the CLI](https://docs.remyx.ai/cli/outrider.md) · [Read the GitHub Action configuration](https://docs.remyx.ai/platform/agents/outrider-configuration.md)

## Related

> [card] [Guardrails](https://docs.remyx.ai/platform/agents/outrider-configuration.md#guardrails)
>
> What the agent may change in the repo

> [card] [Model backends](https://docs.remyx.ai/platform/agents/backends.md)
>
> Which key each agent and provider pair needs

> [card] [Connectors](https://docs.remyx.ai/platform/configure/connectors.md#choose-a-model-provider)
>
> Connect a provider once; the engine pushes it per repo

> [card] [Defense-in-depth in the action repo](https://github.com/remyxai/outrider/blob/main/docs/security.md)
>
> The action repo's security page, with code references


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.