Thank you for helping harden SPACE. This document highlights day-to-day expectations with an emphasis on dependency hygiene and security auditing.
SPACE is dual-licensed under MIT OR Apache 2.0. This means:
- All contributions will be licensed under the same terms (MIT OR Apache 2.0)
- By submitting a pull request, you agree to license your contributions under both licenses
- Users can choose which license they prefer when using SPACE
- This follows the same approach as the Rust programming language and many other Rust projects
See LICENSE-MIT and LICENSE-APACHE for the full license texts.
All commits must carry a Signed-off-by line certifying the
Developer Certificate of Origin. This is
enforced by CI.
Add the sign-off automatically with:
git commit -s -m "feat(storage): add zero-copy read path"If you forget, amend your most recent commit:
git commit --amend -s --no-edit- Install the latest stable Rust toolchain (
rustup default stable). - Run
cargo xtask auditbefore opening a pull request to execute formatting, checks, and security tooling in one pass. - Generate dependency artefacts with
cargo xtask graphwhen introducing new crates or features; attach resulting files if reviewers request them. - Install
cargo fuzz(cargo install cargo-fuzz) to exercise the fuzz harnesses when touching encryption or compression code. - Follow the coding standards in
docs/architecture.mdand module-specific guides such asdocs/implementation/ENCRYPTION_IMPLEMENTATION.md.
To maintain the high reliability standards of SPACE, the following automated checks must pass before merging:
| Check | Description | Command to Run Locally |
|---|---|---|
| Fuzzing | Checks for edge-case crashes | cargo fuzz run <target> |
| Typos | Validates spelling | typos (Install via cargo install typos-cli) |
| Links | Checks for broken URLs | lychee . (Install via cargo install lychee) |
| Docs | Ensures documentation compiles | RUSTDOCFLAGS="-D warnings" cargo doc --no-deps |
| Conventional Commits | Enforces semantic PR titles | Use feat:, fix:, etc. in PR titles |
| Benchmarks | Checks for performance regressions | cargo bench |
All Pull Requests must follow the Conventional Commits specification.
- Good:
feat(storage): implement zero-copy read path - Bad:
added read path
Any modification to Cargo.toml, Cargo.lock, or enabled features must satisfy the workflow in docs/dependency-security.md.
Checklist (include in PR description)
- Identify Tier (0/1/2) for each change and record reviewer initials with date in
Cargo.tomlcomment. - Attach
cargo tree --edges normal,build,devdiff (before/after). - Run
cargo audit --deny warnings. - Run
cargo deny check bans licenses sources. - Run
cargo bloat --crates --releaseand record notable regressions. - Run
cargo xtask audit(enforces feature allowlist, fmt, clippy, tests). - Run
cargo xtask graphif the dependency graph changed and archive the generated artefacts. - Update
docs/security/audit-status.jsonif this PR contains the latest successful audit run.
Pull requests lacking the artefacts above will be blocked until they comply.
- Validate dependency tiering and ensure comments follow the
YYYY-MM-DD <initials>format. - Confirm CI
security-auditworkflow succeeded and review the posted summaries. - Reject PRs that introduce prohibited licenses or push the transitive dependency count beyond 50 without an approved waiver.
- Triage Dependabot PRs weekly (configurable via
.github/dependabot.yml); do not merge without full audit artefacts.
When triaging Dependabot PRs, follow the policy in docs/dependency-security.md:
- Green CI, patch bump — merge directly after a quick review.
- Major version bumps — check for breaking API changes. Dependabot cannot fix code; create a manual migration branch if needed.
- Ecosystem-coupled crates (libp2p, axum+leptos+tower) — close individual PRs and coordinate a single migration.
- Verify crate legitimacy — check
lib.rsfor protest/squatter crates and inspect transitive dependency diffs for supply-chain substitutions. - Stale PRs (changes already on main) — close promptly.
- No hardcoded secrets. Never commit API keys, tokens, or signing keys. Use environment variables or file-based providers. Debug fallbacks must use random ephemeral values.
- Validate all external input. Object key paths must reject null bytes, backslashes, and
..traversal components. Deserialize untrusted data only after size-limit checks. - Prefer poison-safe locks. Use
.unwrap_or_else(|e| e.into_inner())forMutex/RwLockinstead of.unwrap()to avoid cascading panics from poisoned locks. Use.map_err()when the caller can surface the error. - Minimize lock scope. Acquire keys or shared state, clone, and drop the lock guard before performing expensive operations (encryption, MAC verification, I/O).
- Descriptive expect messages. Every
expect()call must describe what operation failed and suggest remediation (e.g.,"failed to open audit log; check path and permissions"). - Use
&'static strfor fixed strings. Functions returning a fixed set of strings (like MIME type detection) should return&'static strto avoid per-call heap allocations.
- After modifying cryptography or compression, run
cargo fuzz run encrypt_roundtripto smoke-test the fuzz harness. - Avoid data-dependent branching or early returns on sensitive comparisons; rely on helpers wired with
subtle::ConstantTimeEq.
- Critical advisories require a release freeze, mitigation plan, and post-mortem within 72 hours.
- File emergency findings under
docs/security/meetings/<YYYY-MM>.mdand link to the GitHub issue or advisory.
For questions, open a GitHub Discussion tagged Security & Dependencies or ping the #space-security channel on Slack.