# Trust Dashboard
This dashboard is a concise adoption checklist for security-sensitive users.
It describes the current release posture and should be refreshed before each
stable release.
The README's **Backend Verification Status** table is the release-facing
inventory of implementation, actual execution evidence, automatic-dispatch
admission, and independent verification. Repository tests and pentests count
as project evidence only; they do not become independent verification merely
because they pass.
Specialized protocol claims are also not trusted from crate names or prose
alone. `protocol-registry/v1` binds each claim to immutable standards/source
bytes, reviewed errata and requirements, finite limits, independent models,
retained corpus decisions, external implementations, and the package API
snapshot. This improves reproducibility without making the external tools part
of the published runtime trusted computing base.
| Area | Current Status | Evidence |
| --- | --- | --- |
| License | `MIT OR Apache-2.0` | `Cargo.toml`, `LICENSE-MIT`, `LICENSE-APACHE` |
| MSRV | Rust `1.90.0` | `Cargo.toml`, CI compatibility matrix |
| Active release toolchain | Rust `1.97.1`; MSRV remains Rust `1.90.0` | `rust-toolchain.toml`, `scripts/ci_install_rust.sh` |
| Runtime dependencies | Zero external crates in the core package; optional companion crates are separate opt-in packages | `scripts/validate-dependencies.sh`, `scripts/check_companion_crates.sh` |
| Default dev dependencies | Zero external crates | `Cargo.toml` |
| Optional runtime features | `alloc`, `std`, `stream`, and admitted ordinary `simd`; dependency-free `secrets` storage, scalar processing, and assurance tokens; secret-only `allow-wasm32-best-effort-wipe` and `allow-compiler-fence-only-wipe` cleanup-limit acknowledgements; reserved `tokio`, `kani`, `fuzzing`. AArch64 CSDB attestation uses custom cfg `base64_ng_aarch64_csdb_attested`. The `base64_ng_require_high_assurance` eligibility cfg requires `secrets` and fails on unsupported or unattested targets; additive ordinary SIMD does not authorize assured secret operations. | `Cargo.toml`, `scripts/check-2.0-secret-capabilities.sh`, `scripts/check-2.0-assurance.sh` |
| Unsafe policy | Scalar encode/decode remains safe Rust; audited unsafe is limited to volatile wiping, constant-time comparison, CT alphabet scan and result-gate barriers, reviewed SIMD, and the exact protected-provider/attestation declarations. | `src/cleanup.rs`, `src/ct/`, `src/simd/`, `src/v2/assurance/`, `docs/UNSAFE.md` |
| Per-operation backend | `encode_backend` and `strict_decode_backend` independently report admitted ordinary dispatch; `secret_decode_backend` is always `scalar-constant-time-oriented`. Wasm reports scalar or `simd128` artifact selection rather than native CPU probing. | `runtime::backend_report()`, `scripts/check-2.0-operation-reporting.sh` |
| SIMD status | AVX-512 VBMI, AVX2, SSSE3/SSE4.1, NEON, narrow wasm `simd128`, and exact-profile Linux/SpacemiT X60 RVV encode and strict decode are admitted for Standard and URL-safe alphabet families under documented contracts. Every ordinary backend is KAT-gated and process-quarantined independently. Wrapped and legacy decode may enter the admitted strict decode backend only after scalar line-profile validation and compaction. Strict in-place encode and decode may enter admitted backends only after stack staging. SVE remains a non-dispatchable QEMU/assembly candidate. Custom-alphabet, CT secret, big-endian acceleration, other RISC-V profiles, SVE production dispatch, and broader wasm/browser claims remain prototype-only or scalar. | `docs/SIMD.md`; `docs/RISCV_QEMU_REVIEW.md`; `docs/SVE_QEMU_REVIEW.md`; `docs/2.0_BACKEND_HEALTH.md` |
| Strict RFC 4648 decoding | Default behavior rejects whitespace, mixed alphabets, malformed padding, trailing data, impossible lengths, and non-canonical trailing bits; `_NO_PAD` engines explicitly reject padding | RFC 4648 Section 10 and malformed-input integration tests |
| Legacy compatibility | Explicit opt-in APIs only | `decode_slice_legacy`, `validate_legacy` |
| Constant-time API | Bounded constant-time-oriented scalar secret encode/decode and equal-length redacted-buffer comparison helpers exist with isolated generated-code and dudect-style evidence; no formal cryptographic constant-time guarantee | `docs/2.0_SECRET_ENCODING.md`, `docs/2.0_SECRET_DECODING.md`, `docs/CONSTANT_TIME.md`, `docs/DUDECT.md` |
| Generated-code review | Assembly evidence is generated by the release gate; manual ct review remains required before stronger wording | `scripts/generate_ct_asm_evidence.sh`, `docs/CT_ASM_REVIEW.md` |
| Cleanup posture | Ordinary public-data codecs require no cleanup opt-in. Compatibility clear-tail/buffer APIs retain best-effort cleanup behavior. The 2.0 `secrets` capability owns the explicit secret claim and fails closed on weak cleanup targets unless the corresponding acknowledgement is enabled; those acknowledgements are not high assurance. | `SECURITY.md`, `docs/2.0_SECRET_CAPABILITY_POLICY.md`, `docs/UNSAFE.md` |
| Protected assurance | Assured 2.0 operations require a generation-bound token plus one allocation-specific protected typestate. The default provider is finite, volatile, best-effort, and not a page-locking or persistent-recovery provider. | `docs/2.0_ASSURANCE_AND_PROTECTED_MEMORY.md`, `tests/v2_assurance.rs` |
| Fuzzing | Isolated `cargo-fuzz` harnesses outside the published dependency graph | `fuzz/`, `docs/RELEASE_EVIDENCE.md` |
| Miri | Release gate runs Miri when nightly Miri is installed and writes evidence artifacts | `scripts/check_miri.sh`, `target/release-evidence/miri/` |
| Dynamic memory sanitizers | AddressSanitizer covers in-place cursor, overlap, and staged-secret paths; LeakSanitizer covers heap secret ownership; ThreadSanitizer covers concurrent backend-health initialization on supported nightly x86-64 Linux | `scripts/check-2.0-in-place-sanitizers.sh`, `docs/2.0_MEMORY_SANITIZER_HARDWARE_EVIDENCE.md`, `target/release-evidence/2.0-memory-sanitizers/` |
| Formatting and append | Allocation-free formatting is counter-tested; append rollback is error- and unwind-injected; formatter partial mutation is explicitly prefix-committing | `scripts/check-2.0-format-append-chunks.sh`, `docs/2.0_FORMAT_APPEND_CHUNKS.md` |
| Bytes integration | Fragmented `Buf` input feeds the shared incremental core without coalescing; every mutable remainder report is limit-checked; owned `Bytes` results are transactional; arbitrary `BufMut` states report committed prefixes and latch downstream panics | `scripts/check-2.0-bytes.sh`, `docs/2.0_BYTES_INTEGRATION.md` |
| Tokio async readers | Read-all helpers and fixed-buffer `AsyncRead` adapters use the shared 2.0 core; exact readers preserve adjacent frames; unwinding inner panics latch and clear before resuming; ordinary delivered plaintext is irrevocable | `scripts/check-2.0-tokio-readers.sh`, `docs/2.0_TOKIO_ASYNC_READ.md` |
| Tokio async writers | Fixed-buffer `AsyncWrite` adapters use shared 2.0 state; accepted input and committed output are distinct; queued output survives backpressure and cancellation; unwinding inner panics prohibit ambiguous retry | `scripts/check-2.0-tokio-writers.sh`, `docs/2.0_TOKIO_ASYNC_WRITE.md` |
| Serde integration | Compatibility modules use validated 2.0 specifications; bounded ordinary fields avoid heap output; secret fields return wiping storage with opaque errors and wipe owned encoded allocations across return, error, and unwind | `scripts/check-2.0-serde.sh`, `docs/2.0_SERDE_INTEGRATION.md` |
| Sanitization protected fill | The 2.0 companion protects distinct staging and destination mappings before fixed-work decode. Core provider quarantine and fallible teardown apply only to the separate single-allocation `decode_assured` path. | `scripts/check-2.0-sanitization.sh`, `docs/2.0_SANITIZATION_PROTECTED_FILL.md` |
| WHATWG compatibility | `web::FORGIVING` is an ordinary, exact WHATWG decoder with opaque content errors; expert padding/trailing-bit policies remain separately named and ineligible for secret processing | `scripts/check-2.0-web-forgiving.sh`, `docs/2.0_WEB_FORGIVING_BASE64.md` |
| 2.0 protocol terminology | Body and alphabet values name only their exact byte-level scope; complete MIME, PEM, password-record, BinHex, and modified-UTF-7 semantics remain separate companion work | `docs/2.0_PROFILES_AND_TERMINOLOGY.md`, `scripts/check-2.0-profiles.sh` |
| RFC 2045 Base64 body | `base64-ng-mime` implements only Section 6.8 content-transfer body bytes with canonical and bounded-compatible policies, exact warning metadata, finite limits, and no complete MIME parser claim | `docs/2.0_MIME_BODY.md`, `scripts/check-2.0-mime-body.sh`, `rfc/rfc2045-requirements.json` |
| Base64-family multibase | `base64-ng-multibase` implements only the pinned `m`, `M`, `u`, and `U` registrations with strict prefix-selected canonicality, finite limits, and no complete-registry claim | `docs/2.0_MULTIBASE.md`, `scripts/check-2.0-multibase.sh`, `spec/multibase/` |
| RFC 7468 textual encoding | `base64-ng-pem` owns labels, exact boundaries, 64-column generation, multiple blocks, bounded adjacent text, compatible deviation reporting, and exact-label secret release without claiming ASN.1 validation | `docs/2.0_PEM.md`, `scripts/check-2.0-pem.sh`, `rfc/rfc7468-requirements.json` |
| Legacy IMAP modified Base64 | `base64-ng-imap` implements only the obsolete RFC 3501 Section 5.1.3 payload transform over already-converted UTF-16BE bytes, with strict canonicality and finite limits; Unicode conversion and complete mailbox grammar remain out of scope | `docs/2.0_IMAP.md`, `scripts/check-2.0-imap.sh`, `rfc/rfc3501-requirements.json` |
| Password-record Base64 | `base64-ng-password` implements exact Passlib PBKDF2 and SHA-crypt field/record transforms with finite limits and redacted formatting; it never accepts passwords, derives hashes, or verifies records | `docs/2.0_PASSWORD_RECORDS.md`, `scripts/check-2.0-password.sh` |
| RFC 9580 OpenPGP armor | `base64-ng-openpgp` validates complete ordinary armor framing, bounded headers and blocks, optional CRC-24 state, exact matching tails, and exact-type secret release without claiming packet parsing | `docs/2.0_OPENPGP.md`, `scripts/check-2.0-openpgp.sh`, `rfc/rfc9580-requirements.json` |
| 2.0 bounded secret transforms | `base64_ng::secret` retains decoded candidates until an opaque final gate and encodes through separate arithmetic/fixed-scan mapping into wiping protected owners | `docs/2.0_SECRET_STORAGE_AND_EXPOSURE.md`, `docs/2.0_SECRET_DECODING.md`, `docs/2.0_SECRET_ENCODING.md`, `scripts/check-2.0-secret-decoder.sh`, `scripts/check-2.0-secret-encoder.sh` |
| Kani | 43 normal and 19 release-host advanced bounded harnesses use Rust `1.90.0` with `cargo-kani 0.67.0`; 6 known high-cost integrated/wrapped harnesses are explicitly exploratory, and incompatible verifier/toolchain pairs must skip rather than pretending to prove. | `scripts/check_kani.sh`, `scripts/check_kani_advanced.sh`, `docs/2.0_FORMAL_VERIFICATION.md` |
| Bounds invariants | Remaining internal indexing is grouped by documented local invariants | `docs/INVARIANTS.md` |
| Audit | RustSec and cargo-deny advisory checks required on every change and daily while the repository is dormant | `cargo audit`, `scripts/checks.sh`, `scripts/check_scheduled_advisories.sh`, scheduled security-audit workflow |
| License policy | `cargo deny` and `cargo license --json` required | `deny.toml`, `scripts/checks.sh` |
| SBOM | SPDX and CycloneDX SBOM generation in release evidence | `scripts/generate-sbom.sh` |
| Reproducibility | Package/build reproducibility check uses tool-created temporary targets and atomically records compared `.rlib`, package-list, and `.crate` artifacts | `scripts/reproducible_build_check.sh`, `scripts/stable_release_gate.sh` |
| Release-evidence authenticity | After the build gate exits, the final evidence index is signed in a dedicated SSH namespace by a separate evidence-only principal/key. Readiness verifies the signature and exact artifact inventory; reuse additionally verifies every retained campaign hash, QEMU source/pass markers, and an immutable product tree. Symlinks fail closed, and executable release-policy files are never reuse-eligible. | `scripts/seal-release-evidence.sh`, `scripts/verify-release-evidence-signature.sh`, `scripts/verify-release-evidence-artifacts.py`, `scripts/evidence-equivalence.py`, `security/evidence-signers`, `security/evidence-reuse-allowlist.txt` |
| Release authorization | Rust and npm publishers require an immutable tag signed by the pinned project SSH principal/key; npm publication additionally requires registry provenance | `security/release-signers`, `scripts/verify-release-tag.sh`, `scripts/release_crates.py`, `scripts/release_wasm_loader.sh` |
| CI bootstrap | Runner-provided `rustup`/`cargo` required; CI refuses `curl \| sh` rustup bootstrap | `scripts/ci_install_rust.sh` |
## Deployment Checks
High-assurance deployments should record `runtime::backend_report()` at process
startup, including all three operation backends, `candidate_detection_mode`,
and Wasm artifact posture, and consider enforcing:
```rust
base64_ng::runtime::require_backend_policy(
base64_ng::runtime::BackendPolicy::HighAssuranceScalarOnly,
)?;
```
Use this policy when deterministic scalar execution matters more than future
acceleration. It requires scalar execution, no detected SIMD candidate, the
`simd` feature disabled, no active accelerated backend, and the conservative
unsafe-boundary flag marked as enforced. It also requires an attested hardware
speculation barrier for the CT result gate. AArch64 reports its CSDB sequence
as `hardware-speculation-barrier-unattested` by default. Deployments that rely
on CSDB must build with the explicit `base64_ng_aarch64_csdb_attested` cfg only
after platform attestation; that path reports
`hardware-speculation-barrier-build-asserted` so logs preserve the distinction
from native target guarantees. The
unsafe-boundary flag is intentionally false when the reserved `simd` feature is
enabled, even if execution remains scalar-only.
For secret-bearing Base64 payloads, combine this policy with the `ct` module
when avoiding future SIMD-induced timing variation is more important than
hardware acceleration.
Treat `candidate_detection_mode=compile-time-target-features` as a build-time
statement, not a runtime CPU attestation. It is used on `no_std` and targets
without `std`-equivalent runtime probing.
## Non-Claims
`base64-ng` currently does not claim:
- formally verified cryptographic constant-time behavior
- formal zeroization of all historical memory copies
- custom-alphabet, CT secret, or broader wasm/browser acceleration
- automatic `no_std` runtime probing or unattested `no_std` acceleration
- async/Tokio support in the core crate's inert `tokio` feature
- serde or bytes integration in the core crate
- Kani-complete whole-crate formal verification
Those features remain admission-gated until their evidence is strong enough for
security-sensitive users.
Optional companion crates may integrate with approved ecosystem dependencies,
but they do not change the core `base64-ng` package dependency contract. Use
`base64-ng-subtle` when an application wants `subtle::ConstantTimeEq` at the
protocol comparison boundary without adding `subtle` to the core crate. Its
sealed 2.0 integration covers only final secret owners and views, exposes
public-length behavior in the method name, and returns `Choice` for explicit
protocol-level declassification.
`base64-ng-derive` remains dependency-free and now generates only final 2.0
secret-owner operations. It requires explicit sealed-codec, exact-length, and
exposure policy, stages decode through `SecretArrayFrame`, and generates no
ordinary conversion, cloning, or equality trait. Its evidence is release-gated
by `scripts/check-2.0-derive.sh`.