Execution environment
To fix code or verify a change, Hyrax has to run code — your repository's tests, dependency-vulnerability scans, and the build and lint checks behind a fix. Anything that runs code is a potential risk, so Hyrax confines it in layers: the commands most exposed to hostile repository code run inside a purpose-built sandbox designed to treat that code as untrusted, and everything else runs on per-job, single-customer compute with credentials scrubbed. This page describes both layers for security reviewers evaluating Hyrax.
What executes, where
Each product surface executes a different amount of your repository's code, and each kind of execution has one designated home:
| Surface | The guarantee | What executes, and where |
|---|---|---|
| PR review | Nothing runs. A review is read-only analysis of your diff — no repository code executes anywhere. | — |
| Audit | Analysis is read-only; anything that executes is confined. | Structured probes (dependency-vulnerability scans, repository-history and coverage probes) and recognized test commands an analysis agent invokes run in the sandbox. Every other command an agent composes — inspection steps, builds, installs, anything built with shell composition — runs on the per-job, credential-scrubbed container described under What runs outside the sandbox. |
| Fix | Every verification is confined, and a check that couldn't run is reported, never silently substituted. | Tests and the read-only verification gates behind a fix (build, lint, and syntax checks) run in the sandbox. Dependency installs and the project's auto-formatter run on the per-job container — the formatter has to modify the working tree, and the sandbox returns results, not changed files. |
When the sandbox is unavailable, the behavior is deliberate and fails closed on the verification side: an audit's structured probes are skipped rather than run elsewhere, and a fix's verification gates never quietly rerun a check outside the sandbox — the change is reported as not verified instead. The one stated fallback is on the audit side: in an environment where the sandbox is not configured at all, the test commands an analysis agent invokes run on the per-job, credential-scrubbed container instead — the same confinement the agent's other commands already run under, not an unconfined escape.
Every sandbox run is isolated
Test execution and the read-only verification gates behind a fix (build, lint, and syntax checks) run in a locked-down sandbox with four independent barriers, each enforced by the surrounding infrastructure rather than by trusting the code:
- Fresh, single-use compute. Every run gets its own freshly launched micro-VM. It runs one job and is then destroyed. Nothing persists between runs, and nothing is shared between customers — there is no long-lived host that repository code could take up residence on.
- No credentials inside. The sandbox runs with no cloud credentials and no access to Hyrax's secrets. There is no role attached to the compute, and the path a workload would normally use to fetch credentials is switched off. Even if repository code went looking for a key in the environment or at a metadata endpoint, there is nothing there to take.
- No network. The sandbox has no route to the public internet — no outbound gateway, no address translation out. It cannot call home, exfiltrate data, or download anything while it runs. The dependencies your build needs are staged into the workspace before the sandbox starts, so the run resolves them entirely offline.
- Read-only system, unprivileged user. The root filesystem is mounted read-only, and code runs as an ordinary non-root user with no elevated capabilities. Writes are confined to a small, bounded scratch area that is thrown away when the run ends.
Results leave through one pre-authorized channel. The run writes a single results record — its captured output, exit status, and nothing else — to one location it has been granted a narrow, one-time write to. That record is cryptographically bound to the specific run, so results cannot be forged or swapped between runs, and the captured output is size-capped. There is no general-purpose way out of the sandbox.
Why this design. Because the confinement is enforced by the environment around the code — no credentials, no network, read-only root, one audited exit — and not by trusting the contents of any particular image, even a broken or hostile test suite or verification run cannot escape its own run. The worst a bad run can do is misbehave inside its own disposable box and report a wrong result about its own job, which is then subject to human review before anything is merged. And when the sandbox itself is unavailable, verification fails closed as described under What executes, where — the check is skipped or the change reported as not verified, never quietly rerun elsewhere.
What runs outside the sandbox
Not everything an audit or fix executes can run in the sandbox, and this page doesn't claim otherwise. Dependency installation (which can execute a package's install hooks and build scripts), build and shell commands an analysis or fix agent composes itself, and the project's auto-formatter (which has to modify the working tree — the sandbox returns results, not changed files) run on the job's own container instead. That container is its own layer of confinement: it is launched fresh for one job and one customer, then destroyed; cloud credentials and secrets are scrubbed from the environment those commands run in, so repository-controlled code that runs there cannot reach Hyrax's cloud role or secret store; and the only credential in reach is a short-lived GitHub token scoped to your own repository. A hostile install hook or build script is therefore confined to the job's own workspace and the repository access you already granted — layered defense rather than total sandbox confinement.
How the sandbox images are built
The environments code runs in are defined as Dockerfiles kept in source control — nothing is assembled by hand:
- Built from pinned sources. Each image is defined by a specific pinned base image and pinned tool versions — anchored to exact source versions, not a floating "latest" tag. Images are produced by a dedicated CI build pipeline from those pinned sources; nothing is built or pushed by hand.
- Digest-pinned in production. Production always runs an image identified by its content digest, not a movable label. A label can be re-pointed at different bytes; a digest cannot — the environment that runs is exactly the one that was built and signed.
- Rebuilt on a regular cadence. A monthly rebuild cadence — to absorb security updates, plus out-of-band rebuilds when a specific fix warrants it — is being rolled out.
- Signed with a public transparency trail. Each image the pipeline builds is cryptographically signed and its signature recorded in a public transparency log, anchoring the image's provenance to that pipeline — and the signature is verified before an image can be deployed; an unsigned image cannot ship. This is a supply-chain integrity control on Hyrax's side of the boundary; we don't yet present it as a guarantee you can independently verify.
Available environments
Hyrax runs a small, deliberately minimal set of shared environments. Each carries only the runtime and tooling a test runner needs — the isolation above is what keeps a run safe, so the images stay lean rather than trying to be trusted:
| Environment | Repositories it serves | Toolchain |
|---|---|---|
| Python | Python, plus JavaScript and TypeScript | Python 3.12, Node.js 22, TypeScript 5.7.3 |
| Go | Go | Go 1.23.12 |
Additional language environments are added as demand warrants, rather than shipped speculatively. Custom images — an environment tailored to a specific customer's toolchain — are not part of any plan today; if your repository needs a toolchain these environments don't cover, contact us. Any tailored environment is authored and built by Hyrax, not the customer, and runs under the same isolation.
Related
- Security overview — data isolation, credential handling, and encryption.
- Public & private repositories — how repos are connected and cloned.