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

# ironrun run — Execute a Sealed Command with Secrets

> ironrun run executes a command defined in ironrun.yml with secrets injected and all output redacted. Key flags: --set to override the active environment.

`ironrun run <command-id>` looks up the command in `ironrun.yml`, resolves its secrets from your configured provider, runs the command with those secrets injected into the child process environment, and streams output with every secret value replaced by `[REDACTED]`. The agent — and anything else reading stdout or stderr — never sees the raw credential values.

## Usage

```bash theme={null}
ironrun run <command-id>
ironrun run --set staging <command-id>
```

## Flags

<ParamField query="--set" type="string">
  Override the active environment for this single run. The switch applies only to this invocation; the project's configured active environment is unchanged afterward.
</ParamField>

<ParamField query="--policy / -p" type="string" default="ironrun.yml">
  Path to the policy file. Accepts a relative or absolute path.
</ParamField>

## What happens under the hood

<Steps>
  <Step title="Secret resolution">
    ironrun reads `ironrun.yml`, finds the command by ID, and resolves each secret reference through the configured provider (encrypted vault, 1Password, Doppler, Infisical, `envfile`, or `env`).
  </Step>

  <Step title="Child process exec">
    The command is executed directly — no shell in between. `argv` is a literal list, so injected values can never be re-expanded, piped, or glob-expanded unexpectedly.
  </Step>

  <Step title="Output redaction">
    All stdout and stderr from the child process passes through a redactor before being forwarded. The literal secret value, its base64 encoding, its hex encoding, its URL-encoded form, and any high-entropy tokens that match are all replaced with `[REDACTED]`.
  </Step>

  <Step title="Exit code passthrough">
    The child process exit code is returned directly. ironrun exits with the same code, so your CI pipeline or shell script sees exactly what the command returned.
  </Step>
</Steps>

## Output truncation

If `max_bytes` is set for a command in `ironrun.yml`, total output (stdout + stderr combined) is capped at that limit. When the cap is reached, ironrun prints the following message to stderr and the child process is terminated:

```
[ironrun] output truncated at max_bytes limit
```

Set `max_bytes` in your policy:

```yaml theme={null}
commands:
  - id: test
    argv: [npm, test]
    ttl: 120s
    max_bytes: 10485760   # 10 MB
    secrets: [DATABASE_URL, STRIPE_SECRET_KEY]
```

## Example

```bash theme={null}
$ ironrun run test
=== RUN   TestUserCreate
--- PASS: TestUserCreate (0.12s)
=== RUN   TestPaymentWebhook
--- PASS: TestPaymentWebhook (0.34s)
ok  github.com/myapp/internal  4.231s
```

If one of those tests logged `DATABASE_URL` during setup, you would see `[REDACTED]` in its place — the connection string never reaches your terminal, your shell history, or any agent transcript.

## Error messages

| Message                                             | Cause and fix                                                                                                                           |
| --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `command "<id>" not found in policy`                | The ID you supplied doesn't match any `id:` field in `ironrun.yml`. Run `ironrun validate` to list all registered command IDs.          |
| `execution failed: runner: command timed out`       | The command ran longer than its `ttl`. Increase `ttl` in `ironrun.yml` for that command.                                                |
| `execution failed: …shell commands are not allowed` | `argv[0]` is `sh`, `bash`, or another shell interpreter. Wrap your shell logic in a script file and point `argv` at the script instead. |

<Note>
  `ironrun run` is equivalent to `ironrun exec`. The `exec` alias exists for scripts that prefer it, but `run` is the canonical form.
</Note>
