Report security issues privately through GitHub private vulnerability reporting. Don't open a public issue, PR, or discussion for them.
Include the affected version or commit, your environment, steps to reproduce, and expected versus observed behavior. A proof of concept or a suggested fix is welcome but not required.
This is a small project, so response is best-effort:
| Stage | Target |
|---|---|
| Acknowledgement | within 7 days |
| Triage (accepted, declined, or needs more info) | within 30 days |
| Fix and disclosure | coordinated with you once a patch exists |
Reporters are credited in the advisory unless they prefer otherwise. Declined reports get a written explanation.
Fixes land on main and the latest tagged release. Older tags don't get backports.
In scope:
- The
orbitCLI, runtime, and crates published from this repository - Bypasses of filesystem-scoping policy (
fsProfile,denyRead,denyModify) - Sandbox or process-supervision escapes in
orbit-exec - Audit-log tampering or omission
- Auth, authorization, or origin-check bypasses on
orbit web serveandorbit mcp serve - Handling and redaction of provider credentials
Out of scope:
- Vulnerabilities in upstream dependencies. Report those upstream, and we'll bump once a fix ships.
- Attacks that already need local code execution as the Orbit user, or write access to the workspace, unless they cross a documented trust boundary below
- Social engineering of maintainers
- Forks and third-party redistributions
Agent filesystem access is scoped by an fsProfile (read and modify globs) plus global denyRead and denyModify rules. orbit-policy evaluates those rules. How strongly they're enforced depends on the platform and on what is running. The limits below are known and documented; reports that go beyond them are in scope.
| What runs | macOS | Linux |
|---|---|---|
| Agent CLIs (Claude Code, Codex, …) | sandbox-exec. Writes are confined. Reads are allowed everywhere except a credential denylist. Network is open. |
Bubblewrap (/usr/bin/bwrap). Writes are confined by the modify policy. Host reads and network stay open. Fails closed if bwrap is missing, unless the executor sets allow_fallback: true. |
proc.spawn in activities |
Refused, with a capability error | Landlock ruleset applied between fork and exec, covering the child and all its descendants. Refused on kernels without Landlock ABI 2. |
Credential denylist (macOS reads). The denylist covers ~/.ssh, ~/.aws, ~/.config/gh, the user and system Keychains, browser profile stores, and Cargo's publish token. It is known to be incomplete (for example, ~/.netrc, ~/.git-credentials, ~/.gnupg, ~/.docker/config.json, ~/.kube/config, ~/.npmrc, and cloud-CLI caches aren't on it). With network open, treat macOS read scoping as advisory, not a security boundary.
Provider-specific carve-outs (macOS):
- Every supported provider's state directory (
~/.claude,~/.codex,~/.gemini,~/.grok) is writable in every run, whichever provider is active. A file planted in another provider's directory could persist across sessions. - Claude runs may read
~/Library/Keychainsso they can refresh their OAuth session. Nothing gets keychain writes. The system keychains stay denied, and anfsProfilethat denies~/Libraryor~/Library/Keychainsstill wins. - Sandboxed Codex gets
CODEX_CA_CERTIFICATE=/etc/ssl/cert.pem, unless you set that orSSL_CERT_FILEyourself. The bundle holds public trust anchors only and doesn't weaken TLS verification.
Environment. Agent subprocess environments are built from an allowlist: a documented baseline, your [execution.env] pass list, and the variables each provider declares it needs. Nothing is inherited just because it has a harmless-looking name.
Symlinks. Policy matches the real path. Orbit canonicalizes the target, or the nearest existing ancestor for a new file, and follows dangling links to their target. A symlink from an allowed tree into a denied one is denied, and so is any path that resolves outside the workspace.
Race conditions. There is an inherent time-of-check-to-time-of-use gap between a policy decision and the filesystem operation that follows. On Linux, Landlock binds to inodes that exist at spawn, so a denied file created afterward is readable. Treat a workspace an attacker can modify concurrently as untrusted.
Details are in docs/design/policy-sandbox/ and the Linux sandbox runbook.