SPACE enforces deterministic, auditable builds for every crate in the workspace. This document captures the lifecycle for selecting, pinning, reviewing, and updating third‑party code, with special focus on cryptography as we roll out Phase 3 encryption.
- Prevent supply-chain compromise through version pinning, reproducible builds, and continuous auditing.
- Ensure cryptographic dependencies uphold constant-time guarantees and align with
implementation/ENCRYPTION_IMPLEMENTATION.md. - Minimise dependency bloat while keeping license posture MIT / Apache-2.0 compatible (dual licensed).
- Plan – classify the dependency change (new crate, feature toggle, version bump) and map its tier.
- Pin – update
Cargo.tomlwith the approved version, add reviewer/timestamp comment, and syncCargo.lock. - Verify – run
cargo tree --edges normal,build,dev,cargo audit --deny warnings,cargo deny check, and feature allowlist validation. - Review – attach artefacts to the PR template (section below) and capture rationale in meeting notes if material.
- Monitor – Dependabot (configured via
.github/dependabot.yml) and nightly audits raise issues when advisories or drift are detected.
| Tier | Scope | Policy | Examples |
|---|---|---|---|
| Tier 0 | Cryptography, hashing, compression, serialization, memory scrubbing | Exact version pin (=) in Cargo.toml, CT compliance review, side-channel notes required |
blake3, aes, xts-mode, serde, zstd, zeroize, subtle |
| Tier 1 | Platform scaffolding, IO stacks, observability, CLI | Caret pin to specific minor (^x.y.z) with audit log reference; must be covered by cargo audit gating |
tokio, axum, clap, tower, tracing |
| Tier 2 | Dev-only, fuzzing, benchmarks | Wildcard or caret allowed, but include justification in PR and keep out of release artefacts | proptest, rand, criterion, fuzz targets |
Record tier assignments inside PR descriptions and keep the table up to date when new crates land.
- Comments in
Cargo.tomluse the format# YYYY-MM-DD <initials>: <rationale>and must reference this policy (example:see docs/dependency-security.md#tier-0). - Update
Cargo.lockviacargo update -p <crate>orcargo updateafter manifest edits; the change must be part of the same commit. - Maintain the feature allowlist in
[workspace.metadata.space.allowed-features]. Violations are caught bycargo xtask audit. - Feature flags that gate Phase 3 crypto (
experimental,pqc,tee) remain opt-in until a security review graduates them.
- CI Workflows
security-audit: runscargo xtask audit(format/check/audit/deny/bloat) on every push and pull request.dependency-drift: nightly; emits issues when advisories appear, transitive count exceeds 50, or manifests diverge from policy.
- Tooling
cargo audit --deny warningsblocks merges on high/critical advisories.cargo deny check bans licenses sourcesenforces Apache/MIT compatibility.cargo bloat --cratesruns in release mode and posts size regressions to PR logs.cargo xtask graphcaptures a workspace dependency snapshot (and, if available,cargo depsoutput) for review.- Results from the last green run are mirrored in
docs/security/audit-status.jsonand surfaced via Slack.
When a fixed upstream version is not available or the vulnerable crate is only reachable through an experimental/non-default path, keep CI blocking enabled by default and document the exception in three places:
.cargo/audit.tomlwith advisory id, affected stack, risk, and migration plan.deny.tomlwhen the exception affects duplicate/yanked policy.docs/security/audit-status.jsonwith the last reviewed date and owner.
The 2026-05-08 audit refresh follows this pattern for rustls-webpki advisories
remaining in older transitive rustls stacks, Wasmtime advisories in the
experimental transform path, and core2 yanked/unmaintained status through the
experimental libp2p path. These waivers are migration windows, not permanent
acceptance; remove them as the dependency stacks are upgraded or split out.
- Require constant-time primitives (
subtle::ConstantTimeEq, noPartialEqon secret data). - Verify upstream uses hardware acceleration safely (
cpufeaturesgating, no runtime feature toggles that alter timing). - For new algorithms, capture proofs or references in
implementation/ENCRYPTION_IMPLEMENTATION.mdand list reviewers. - Key derivation must use HKDF/PBKDF2 with TPM-backed master secrets; ensure
keymanager.rsaligns with policy.
- Fuzz targets live under
fuzz/(driven bycargo fuzz). Runcargo fuzz run encrypt_roundtripafter touching the encryption stack; archive interesting crashes alongside the PR. - Side-channel hardening relies on constant-time comparisons in compression, MAC verification, and key handling; new code paths must continue this pattern.
- [ ] Tier classification + reviewer initials recorded
- [ ] cargo tree --edges normal,build,dev attached (before/after)
- [ ] cargo audit --deny warnings
- [ ] cargo deny check bans licenses sources
- [ ] cargo bloat --crates (release) regression inspected
- [ ] Feature allowlist validated (cargo xtask audit)
- [ ] docs/security/audit-status.json updated (if audit run)
- A monthly “Dependency Review” triad (Security, Crypto, Core Eng) logs decisions in
docs/security/meetings/YYYY-MM.md. - Critical advisories trigger a release freeze, mitigation plan, and post-mortem within 72 hours.
- Mirror Tier 0 crates in a private registry and verify checksums when running
cargo vendor.
docs/security/audit-status.json– latest audit run metadata (tool versions, report hashes).docs/security/meetings/– minutes for monthly reviews and emergency sessions.CONTRIBUTING.md– contributor-facing checklist and policy summary.
Questions or proposals for new dependencies should be raised via GitHub Discussions under Security & Dependencies with a link to this policy.
Dependabot PRs (configured in .github/dependabot.yml) are triaged according to these rules:
- Green CI → merge immediately if the update is a patch bump within the same tier policy (exact pin → exact pin, caret → caret).
- Major version bumps require manual code review and migration. Dependabot cannot handle breaking API changes — close the PR and open a manual migration branch.
- Grouped crates with ecosystem coupling (e.g., the libp2p stack) must be bumped as a coordinated set. Individual bumps cause diamond dependency conflicts where traits from different crate versions are incompatible. Close individual PRs and coordinate a single migration PR.
- Verify crate legitimacy before merging. Supply-chain attacks via protest/squatter crates (e.g.,
bincode 3.0.0which contains onlycompile_error!) and suspicious dependency substitutions (e.g.,serde_jsonreplacingryuwith unknownzmij) must be rejected. Checklib.rs, transitive dependency diffs, and crate author history. - Stale PRs (changes already on main) should be closed promptly.
| Group | Constraint | Last Reviewed |
|---|---|---|
| libp2p | libp2p-core, libp2p-yamux, libp2p-tcp, libp2p-noise, libp2p-swarm, libp2p-gossipsub must all target the same libp2p-core major version |
2026-02 |
| axum | axum major bumps require simultaneous tower, leptos_axum, utoipa-swagger-ui, and axum-test migration |
2026-02 |
| serde-stack | bincode 3.x is a protest crate — pin bincode to =1.x via Dependabot ignore or version constraint |
2026-02 |
Status: Critical / Frozen
Risk: High (Unmaintained)
As of Phase 4, SPACE continues to rely on sled (v0.34) for the CapsuleRegistry. While the crate is effectively unmaintained, replacing it is a Phase 5 roadmap item (candidate replacements include redb or a custom log-structured engine aligned with our NVRAM pipeline).
Policy:
- No New Usage: Do not introduce
sledinto new crates (protocols, orchestrator, etc.). - Input Strictness: All keys written to existing
sledinstances MUST be derived from cryptographic primitives (UUIDs, BLAKE3 hashes). No user-provided strings. - Waivers: Security advisories related to
sledinternals (e.g.,fxhashcollision DoS) may be waived only if exploitation requires attacker-controlled keys. Document waivers indeny.tomlanddocs/security/audit-status.json.