> ## 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.

# Using ironrun for Sealed Execution in GitHub Actions

> Run sealed commands in GitHub Actions. ironrun blocks fork pull requests from accessing secrets and redacts all credential values from CI job logs.

ironrun's CI mode injects secrets for trusted runs and blocks untrusted ones — fork pull requests cannot trick your workflow into handing out production credentials. No special configuration is needed: the trust check is automatic based on GitHub's event context, and secrets are redacted from all CI output before they can appear in job logs.

## Trust model

ironrun inspects the GitHub Actions event context and decides automatically whether to inject secrets:

| Event                             | Secrets injected?                          |
| --------------------------------- | ------------------------------------------ |
| `push` to a branch in your repo   | ✓ yes                                      |
| `pull_request` from the same repo | ✓ yes                                      |
| `pull_request` from a fork        | ✗ no — blocked (`ErrCIUntrusted`)          |
| `pull_request_target`             | ✗ no — unless `IRONRUN_ALLOW_PRT=1` is set |

Fork PRs are blocked because GitHub Actions exposes repository secrets to jobs triggered by `pull_request` from the same repo but **not** from forks. ironrun enforces the same boundary at the command level, ensuring a fork-authored workflow file cannot be modified to exfiltrate credentials.

## Using the GitHub Action step

The `generalized-labs/ironrun@v0` action installs ironrun and runs a policy command in one step. Add it to any job:

```yaml theme={null}
- name: Deploy (sealed)
  uses: generalized-labs/ironrun@v0
  with:
    command_id: deploy
    policy: ironrun.yml
  env:
    OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
```

### Inputs

| Input        | Required | Default       | Description                                                         |
| ------------ | -------- | ------------- | ------------------------------------------------------------------- |
| `command_id` | ✓ yes    | —             | The policy command ID to execute (must exist in your `ironrun.yml`) |
| `policy`     | no       | `ironrun.yml` | Path to the policy file                                             |
| `version`    | no       | `latest`      | ironrun version to install (a released tag, or `latest`)            |

### Outputs

| Output        | Description                                  |
| ------------- | -------------------------------------------- |
| `exit_code`   | Exit code of the executed command            |
| `duration_ms` | Execution time in milliseconds               |
| `truncated`   | `"true"` if output was capped at `max_bytes` |

### Using outputs in later steps

```yaml theme={null}
- name: Deploy (sealed)
  id: deploy
  uses: generalized-labs/ironrun@v0
  with:
    command_id: deploy

- name: Report result
  run: echo "Finished in ${{ steps.deploy.outputs.duration_ms }}ms"
```

## Using the binary directly

If you prefer to install ironrun yourself and run it in a plain `run` step, use `go install`:

```yaml theme={null}
- run: go install github.com/generalized-labs/ironrun/cmd/ironrun@latest
- run: ironrun run test
```

This works in any job regardless of the action. The `ironrun.yml` policy is read from the repository root by default.

## Full workflow example

```yaml theme={null}
name: CI

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Test (sealed)
        uses: generalized-labs/ironrun@v0
        with:
          command_id: test
        env:
          OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}

  deploy:
    runs-on: ubuntu-latest
    needs: test
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4

      - name: Deploy (sealed)
        uses: generalized-labs/ironrun@v0
        with:
          command_id: deploy
        env:
          OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
```

<Note>
  No special CI configuration is needed to enable the fork-PR protection. ironrun reads GitHub's event context automatically and blocks untrusted runs with `ErrCIUntrusted`. The protection is on by default.
</Note>

<Warning>
  Setting `IRONRUN_ALLOW_PRT=1` disables fork protection for `pull_request_target` events. Use this only if you fully understand the security implications — `pull_request_target` runs with write access to the base repository, and enabling secret injection for fork-authored code in that context is a known attack surface.
</Warning>
