base64-ng defaults to zero external crates in the published package. That is
a security and maintenance choice: Base64 is infrastructure code, and every
new dependency expands the audit, license, advisory, and supply-chain surface.
Cargo.tomlhas no normal, build, or dev dependencies.scripts/validate-dependencies.shfails if the root crate dependency graph contains anything beyondbase64-ngitself.scripts/check_reserved_features.shverifies thattokio,kani, andfuzzingremain inert and dependency-free until admitted, and that deferred integration features such asserde,bytes,zeroize,subtle, andcriterionare not exposed before dependency admission.allow-wasm32-best-effort-wipeis a dependency-free policy feature, not a dependency admission. It is required to build forwasm32, where cleanup is limited to a compiler-fence-only wipe barrier.allow-compiler-fence-only-wipeis a dependency-free policy feature, not a dependency admission. It is required to build unsupported native architectures that do not have abase64-nghardware wipe barrier and therefore fall back to compiler-fence-only cleanup.base64_ng_aarch64_csdb_attestedis a dependency-free custom cfg operator attestation, not a dependency admission and not a Cargo feature. It should only be enabled after the deployment has evidence that the target AArch64 core treats CSDB as an effective speculation barrier for the CT result gate. Builds that set it reporthardware-speculation-barrier-build-assertedso audit logs preserve the operator-attestation boundary.- Fuzz, performance, and dudect-style timing harness dependencies are isolated
under
fuzz/,perf/, anddudect/; the standard local gate checks them separately from the published crate dependency graph. - CI toolchain setup requires
rustupandcargofrom the runner image. The repository script intentionally refuses unauthenticatedcurl | shrustup bootstrap during CI; missing toolchain managers are treated as infrastructure failures, not as a reason to execute freshly downloaded shell installers.
The v1.0 release candidate keeps the published crate dependency-free.
No optional ecosystem integration has a strong enough security and maintenance
case to enter the stable v1.0 contract yet.
Current decisions:
tokioremains a reserved, inert feature until async cancellation, drop cleanup, chunk-boundary, dependency, and release-evidence requirements are satisfied.serderemains deferred because serialization should not hide alphabet, padding, profile, allocation, or secret-handling choices.bytesremains deferred because slice, stack-buffer, andstd::iosurfaces cover current networking and streaming use cases without a runtime dependency.zeroizeandsubtleremain deferred; applications can combine their own approved dependencies with caller-owned buffers whilebase64-ngkeeps its audited local best-effort helpers dependency-free.- Property-testing and benchmark frameworks remain isolated or deferred; fuzz, dudect-style timing, and performance harnesses stay outside the published crate package.
Before adding any dependency to the published crate, the change must document:
- Why
core,alloc, orstdis not sufficient. - Whether the dependency is runtime, build-time, dev-only, feature-gated, or tool-only.
- The full transitive dependency graph.
- License compatibility with
MIT OR Apache-2.0. - RustSec advisory status and yanked-release status.
- Whether the dependency works under the crate's supported
no_stdfeature combinations. - Whether the dependency changes MSRV, build reproducibility, or target support.
- How the dependency is disabled for users who do not need the feature.
The release gate must remain clean after the change:
scripts/checks.sh
scripts/stable_release_gate.sh releaseAt minimum, evidence must include:
cargo treefor the affected feature set.cargo deny check.cargo audit.cargo license --json.- Updated release notes and migration/security documentation when the public API or threat model changes.
The following are rejected unless a specific review proves they are necessary:
- Helper crates for small bit manipulation, table generation, feature selection, error formatting, or simple CLI behavior.
- Git dependencies.
- Default-feature runtime dependencies.
- Dependencies with unclear licensing, unmaintained status, active security advisories, yanked releases, or unnecessary transitive graphs.
The following integrations are intentionally not admitted in the published crate today:
tokio: reserved for async streaming only after the policy inASYNC.mdis satisfied.serde: deferred until a concrete serialization use case proves that nativeAsRef,TryFrom, engine/profile APIs, and caller-owned buffers are insufficient.bytes: deferred until a concrete networking use case proves that slice andstd::ioAPIs are insufficient.zeroizeorsubtle: deferred unless a review proves that the dependency materially improves the documented best-effort cleanup or constant-time-oriented posture beyond the current audited local helpers.- Criterion or other benchmark frameworks: keep benchmark evidence isolated unless the added dependency graph clearly improves release evidence quality.
These are product decisions as much as technical ones. The crate is allowed to remain smaller than the broader ecosystem when dependency-free APIs preserve explicit security semantics.
Downstream applications may still combine base64-ng with their own approved
dependencies. For example, a service with an existing zeroize policy can
decode into a caller-owned buffer with decode_slice_clear_tail and then call
Zeroize::zeroize() on that buffer after the protocol step is complete. That
keeps the published base64-ng crate dependency-free while allowing the
application to apply its local memory-cleanup policy at the ownership boundary.
This is the recommended pattern for deployments that require a dependency-backed
zeroization policy while still wanting base64-ng itself to remain a small,
auditable zero-runtime-dependency crate.
Fuzzing, benchmark, and timing-evidence dependencies may live in isolated workspaces only when they are not packaged with the published crate:
fuzz/dependencies are reviewed byscripts/check_fuzz.sh.perf/dependencies are reviewed byscripts/check_perf.sh.dudect/dependencies are reviewed byscripts/check_dudect.sh.
scripts/checks.sh runs those isolated harness checks so ordinary local
verification catches harness dependency drift before release-only evidence
steps.
Those isolated dependencies do not weaken the zero-dependency guarantee for the published crate.