Skip to content

Commit 07bcdf8

Browse files
authored
docs(security): add public docs folder with security overview (#644)
## What Adds a top-level `docs/` folder for public-facing documentation, starting with a security overview article. ## Why Bashkit has extensive internal security documentation (specs, threat model, rustdoc guides) but no user-facing summary. This gives users a single entry point to understand the security model. ## How - **`docs/security.md`**: High-level security article covering: - Core security boundaries (VFS, no process execution, network allowlist, resource limits) - Threat model overview with all TM-* categories - Link to the [published rustdoc threat model](https://docs.rs/bashkit/latest/bashkit/threat_model/index.html) - POSIX deviations made for security - Security testing layers (threat model tests, fail-point injection, network/error/logging tests, fuzzing, differential tests) - Panic safety - How to report vulnerabilities (security@everruns.com) - **`AGENTS.md`**: Updated Documentation section to distinguish `docs/` (public) from `crates/bashkit/docs/` (rustdoc) ## Tests Docs-only change. All 2000+ existing tests pass. fmt and clippy clean.
1 parent 4ba693a commit 07bcdf8

2 files changed

Lines changed: 107 additions & 3 deletions

File tree

AGENTS.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ Fix root cause. Unsure: read more code; if stuck, ask w/ short options. Unrecogn
4545

4646
### Documentation
4747

48-
- Guides live in `crates/bashkit/docs/` as markdown files
49-
- Embedded into rustdoc via `include_str!` (see `specs/008-documentation.md`)
48+
- **Public docs** live in `docs/` — user-facing articles (security, guides, etc.)
49+
- **Rustdoc guides** live in `crates/bashkit/docs/` as markdown files
50+
- Rustdoc guides embedded via `include_str!` (see `specs/008-documentation.md`)
5051
- Edit `crates/bashkit/docs/*.md`, not the doc modules in `lib.rs`
5152
- Add "See also" cross-links when creating new guides
52-
- Run `cargo doc --open` to preview changes
53+
- Run `cargo doc --open` to preview rustdoc changes
5354

5455
### Bashkit Principles
5556

docs/security.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Security in Bashkit
2+
3+
Bashkit is a virtual Bash interpreter designed for safe, sandboxed script
4+
execution. Security is a first-class concern — every design decision considers
5+
what an untrusted script could do and how to prevent it.
6+
7+
This article gives a high-level overview. For the full threat model with
8+
individual threat IDs and mitigation status, see the
9+
[rustdoc threat model guide](https://docs.rs/bashkit/latest/bashkit/threat_model/index.html).
10+
11+
## Core security boundaries
12+
13+
| Boundary | What it does |
14+
|----------|-------------|
15+
| **Virtual filesystem** | Scripts run against an in-memory VFS. No real filesystem access by default. Path traversal (`../../../etc/passwd`) is normalised away. Symlinks are stored but never followed. |
16+
| **No process execution** | `exec` is excluded entirely. `bash -c` re-invokes the virtual interpreter instead of spawning a real process. Background jobs (`&`) parse but run synchronously. |
17+
| **Network allowlist** | HTTP/HTTPS only, pre-validated against an explicit host allowlist. No DNS resolution, no auto-redirect, no auto-decompression. |
18+
| **Resource limits** | Configurable caps on commands, loop iterations, recursion depth, AST depth, timeouts, and parser operations prevent denial-of-service from malicious scripts. |
19+
| **Filesystem limits** | Total bytes, per-file size, file count, path depth, and filename length are all capped to prevent storage exhaustion (zip bombs, tar bombs, recursive copies). |
20+
21+
## Threat model
22+
23+
Bashkit maintains a living threat model in [`specs/006-threat-model.md`](../specs/006-threat-model.md)
24+
with stable threat IDs across these categories:
25+
26+
| Category | ID prefix | Examples |
27+
|----------|-----------|----------|
28+
| Denial of Service | `TM-DOS` | Resource exhaustion, infinite loops, parser bombs |
29+
| Sandbox Escape | `TM-ESC` | Path traversal, real FS access, privilege escalation |
30+
| Information Disclosure | `TM-INF` | Secret leakage, host info exposure, data exfiltration |
31+
| Injection | `TM-INJ` | Command injection, variable namespace pollution |
32+
| Network | `TM-NET` | DNS rebinding, allowlist bypass, response flooding |
33+
| Multi-Tenant Isolation | `TM-ISO` | Cross-tenant data leaks |
34+
| Internal Errors | `TM-INT` | Panics, error message information leaks |
35+
| Git | `TM-GIT` | Repo access control, remote URL injection |
36+
| Logging | `TM-LOG` | Sensitive data in logs, log injection |
37+
| Python Sandbox | `TM-PY` | Monty resource limits, VFS bridge escapes |
38+
| Unicode | `TM-UNI` | Byte-boundary panics, homoglyph attacks |
39+
40+
The full threat model — including mitigation status for each threat — is
41+
published in the rustdoc:
42+
[**bashkit::threat_model**](https://docs.rs/bashkit/latest/bashkit/threat_model/index.html).
43+
44+
## POSIX deviations for security
45+
46+
Bashkit intentionally deviates from POSIX where compliance would compromise
47+
the sandbox. Key exclusions:
48+
49+
- **`exec`** — would break sandbox containment (`TM-ESC-005`)
50+
- **`trap`** — conflicts with the stateless execution model
51+
- **Real process spawning** — all subprocess commands stay within the virtual interpreter (`TM-ESC-015`)
52+
53+
These decisions are documented in [`specs/008-posix-compliance.md`](../specs/008-posix-compliance.md).
54+
55+
## Security testing
56+
57+
Bashkit uses multiple layers of security testing:
58+
59+
**Threat model tests** — Over 50 tests in `threat_model_tests.rs` that directly
60+
validate mitigations against documented threat IDs. Each test maps to a specific
61+
`TM-*` threat.
62+
63+
**Fail-point injection** — A framework defined in [`specs/005-security-testing.md`](../specs/005-security-testing.md)
64+
that injects failures at specific points to verify the interpreter handles them
65+
safely. 14+ tests in `security_failpoint_tests.rs`.
66+
67+
**Network security tests** — 53 tests covering allowlist enforcement, URL
68+
validation, timeout behaviour, and response limits.
69+
70+
**Error handling tests** — 39 tests verifying that builtins wrapped with
71+
`catch_unwind` never leak panic messages, stack traces, or memory addresses.
72+
73+
**Logging security tests** — 26 tests confirming that sensitive data (passwords,
74+
tokens, API keys, JWTs) is redacted in logs and that log injection is prevented.
75+
76+
**Fuzz testing** — Parser and lexer fuzzing to catch panics and unexpected
77+
behaviour on malformed input.
78+
79+
**Differential tests** — Compare Bashkit output against real Bash to ensure
80+
behaviour parity where expected, and confirm intentional divergences where
81+
security requires it.
82+
83+
## Panic safety
84+
85+
All builtin commands are wrapped with `catch_unwind`. If a builtin panics, the
86+
error is caught and converted to a sanitised error message — no stack traces, no
87+
memory addresses, no real filesystem paths leak to the caller (`TM-INT-001`,
88+
`TM-INT-002`).
89+
90+
## Reporting security issues
91+
92+
**Do not open a public GitHub issue for security vulnerabilities.**
93+
94+
Email: **security@everruns.com**
95+
96+
Please include a description of the vulnerability, steps to reproduce, and
97+
potential impact. We acknowledge reports within 48 hours, provide an initial
98+
assessment within 7 days, and target 30-day resolution for critical issues.
99+
100+
See [`SECURITY.md`](../SECURITY.md) for the full policy.
101+
102+
We appreciate responsible disclosure and acknowledge researchers who report
103+
valid vulnerabilities (with permission).

0 commit comments

Comments
 (0)