AS2 & AS4 · ebMS3 · Rust
AS2 and AS4 messaging for Rust that fails closed by default.
asx-rs is an async-native Rust library for the AS2 (RFC 4130) and AS4 (OASIS ebMS3 / eDelivery) protocols. S/MIME and WS-Security, MDN and cryptographically verified receipts — as an embeddable crate, not a gateway you have to operate.
cargo add asx-rs --features as4,client,server
Why another AS2/AS4 stack?
The type system enforces trust
Payloads move through UntrustedBytes → StructurallyParsed →
CryptographicallyVerified → ContentDecrypted → DomainReady. Application code cannot receive bytes that skipped a gate, because the state that would let it does not exist.
Insecure configurations are unreachable
Signatures are required, pull is denied, SMP results are not trusted, and encrypted-spool profiles refuse to run without a key — until you say otherwise. There is no unsafe setting you reach by forgetting a field.
A library, not a platform
No container, no database requirement, no JVM. Dedup, reconciliation, audit sinks and key management are traits you implement against your own infrastructure.
What it implements
AS2 — RFC 4130
- CMS/S/MIME signing and encryption (RSA, ECDSA)
- Synchronous and asynchronous MDN
- RFC 4130 §7.3.1 MIC over the signed MIME entity
- RFC 5402 compression as CMS
CompressedData - Streaming receive with a bounded, encrypted spool
AS2 reference →AS4 — OASIS ebMS3
- WS-Security XMLDSig with XML Signature Wrapping defences
- XML Encryption: AES-GCM, RSA-OAEP, ECDH-ES
- Verified receipts with Non-Repudiation Information
- One-Way/Push and One-Way/Pull with MPC authorization
- Large-message splitting and joining
- Peppol/CEF dynamic discovery (BDXL, SMP)
AS4 reference →Send a signed AS4 message
use asx_rs::as4::{send_async, As4ReceiptPolicy, As4SendPolicyBuilder, As4SendRequest};
use asx_rs::transport::egress::{As4HttpTransport, TransportConfig};
let (policy, credentials) = As4SendPolicyBuilder::new()
.action("urn:example:action")
.service("urn:example:service", "")
.signing_cert_pem(cert)
.signing_key_pem(key)
.build()?;
let sent = send_async(&session, &bus, As4SendRequest {
message_id: message_id.clone(),
payload,
policy,
credentials: Some(credentials),
payload_filename: None,
}).await?;
// Send, then verify the counterparty's receipt — signature and
// non-repudiation digests — in one call.
let outcome = As4HttpTransport::new(TransportConfig::default())?
.send_and_verify(&url, &session, &bus, &sent, &As4ReceiptPolicy::regulated())
.await?;
A receipt is only evidence of delivery once its signature and digests are checked against the message you sent. send_and_verify does both, so that step cannot be skipped by accident.
Questions people arrive with
Is this a gateway I have to run?
No. It is a crate you link into a service you already run. There is no container, no database requirement and no JVM. Dedup, reconciliation, audit sinks and key management are traits you implement against your own infrastructure — and a conformance suite ships so your backend can demonstrate durability rather than declare it.
Which networks use AS4?
Peppol (e-invoicing across some 40 countries), CEF eDelivery (EU sector networks such as customs and e-Justice), the German energy market's BDEW MaKo profile — where AS4 has been mandatory for electricity since April 2024 and gas since April 2025 — and ENTSOG for gas transmission. Each is a different profile of the same protocol; see interoperability.
Does it do AS2 as well?
Yes — RFC 4130 in full: S/MIME signing and encryption, RFC 5402 CMS compression, synchronous and asynchronous MDN, and the MIC computed over exactly the octets RFC 4130 §7.3.1 specifies. AS2 remains the backbone of North American retail and logistics EDI and is not going anywhere.
Is it conformance-certified?
Not yet, and the conformance page says exactly what is missing: a runnable access point and a SUT Controller, neither of which is a library concern. What does exist is continuous third-party evidence — every signature is checked against xmlsec1, AS2 against the openssl CLI, and a full signed exchange against Holodeck B2B in a container.
What does it need to build?
Rust 1.88 or newer and a working OpenSSL. as2 and as4 are not default features — enable the protocols you need. The library contains no unsafe and cannot gain any.