Security posture
Crypto core
All CMS/S-MIME cryptography is performed by libcrypto (OpenSSL 3) —
the most widely deployed and audited crypto library in existence — through
Rust bindings. The protocol engine itself is memory-safe Rust with
unsafe code forbidden in the core protocol crate. Legacy ciphers (RC2)
load through OpenSSL’s legacy provider, and the server round-trips RC2
through it at startup, in-process, before accepting traffic.
The production container is distroless: no shell, no package manager, no coreutils — the only executable in the image is as2d itself, alongside the OpenSSL shared libraries and the CA bundle (~50 MB total). There is nothing for an attacker to “live off the land” with, and vulnerability scanners have almost nothing to flag.
Enforced invariants
Each of these is protected by regression tests:
- Inbound security floor. If a partnership declares signing and/or
encryption, an inbound message missing those layers is rejected with
insufficient-message-security— a partner downgrade (or an attacker stripping layers) cannot slip plaintext through. Per-layer opt-outs exist for migration scenarios and are explicit configuration. - Receipt authentication. Asynchronous MDNs are verified against the pinned partner certificate from your keystore — not whatever certificate happens to be embedded in the receipt. A rejected or mismatched receipt cannot consume delivery state.
- SSRF guard. A receipt-delivery URL supplied by an unknown or
unauthenticated party is never honored, and only
http(s)URLs are ever delivered to — the receipt channel cannot be turned into an arbitrary-POST primitive against your network. - Certificate validity windows are enforced when signing and when verifying against the trust anchor.
- Replay protection. Message-IDs are remembered (configurable TTL); replays are answered idempotently without reprocessing.
- Retries are transient-only. Permanent HTTP failures (4xx other than 408/429) never loop.
Key handling
- Private keys are held in memory in zeroize-on-drop buffers.
- Keys load from PEM files you mount, or from Azure Key Vault using a managed identity — in that profile no private key ever touches disk.
- Partner trust is pinned: you install each partner’s certificate; there is no ambient CA trust for partner identity. (Verification against in-band certificates is available per partner for counterparts that rotate certificates that way, and is documented as the weaker mode.)
Network surface
- One partner-facing HTTP listener (
/as2,/as2/mdn,/healthz) — TLS terminates at your ingress. - Metrics, when enabled, are served on a separate port that you never expose to partners.
- No outbound connections except deliveries to configured partner URLs (and your configured storage backends). No telemetry, no license callbacks.