proposed ANSI/SCTE 130-9 · reference implementation in Rust

Security for the
ESAM control plane.

SESAME (Secure ESAM Authentication and Message Encryption) adds authentication, channel-scoped authorization, and payload encryption to the ESAM interface, carried entirely in HTTP headers with no change to the ESAM XML. Three additive tiers over a backward-compatible baseline, so adoption is incremental: turn on what you need, when you need it.

Get the SDK $cargo add sesame-esamcopy
HMAC-SHA256 + AES-256-GCM No XML schema change Sub-millisecond per-request overhead One SDK in Rust · C++ · Python · Go
The problem

ESAM was designed for a trusted network. The network changed.

ESAM (SCTE 130-3) carries the signaling that decides what airs: blackouts, avails, regional replacement, redirects. It was specified for closed, trusted facilities. In multi-tenant cloud and partner workflows there is no broadly adopted ESAM-native security profile, so identity, replay protection, and policy authorization get bolted on per deployment, inconsistently, if at all.

TAMPERING · INJECTION

Unauthenticated signaling

A POIS that trusts the network accepts any well-formed ESAM request. A forged or modified message can insert, suppress, or reshape an avail with nothing to prove who sent it or that it arrived intact.

CROSS-CHANNEL

No authorization boundary

Without scoped credentials, anyone who can reach the endpoint can act on any channel. One compromised or misconfigured integration affects feeds it was never meant to touch.

RESPONSE SPOOFING

Decisions you cannot trust

The POIS response is policy: it sets the blackout, the avail, the redirect. If responses are not signed and bound to the request that asked for them, a tampered or substituted decision is indistinguishable from a real one.

What SESAME does

One protocol that authenticates and integrity-protects every message, scopes credentials to channels, optionally encrypts the payload, and signs the response back, all without touching the ESAM XML or breaking Tier-0 peers.

The model

Three additive tiers, carried in HTTP headers.

Each tier is independently enableable and builds on the one below. The ESAM XML is never modified; Tier 3 replaces the transmitted body with ciphertext. A channel's minimum required tier is server-side policy, so you can raise the floor per channel as integrations are ready.

Tier 0

Unauthenticated baseline

no SESAME headers

The existing ESAM exchange, unchanged. Backward compatible by construction: when no SESAME keys are configured, the path behaves exactly as before. Adoption never forces a flag day.

Tier 1

Authentication + integrity

HMAC-SHA256 · timestamp · nonce

Every message is signed over a canonical string covering method, target, timestamp, nonce, and a hash of the body as transmitted. Stops injection and tampering; timestamp and nonce give replay protection and bound exposure to abuse.

Tier 2

Channel-scoped authorization

signed X-SESAME-Scope · policy lookup

Credentials are bound to the channels they may act on. The scope travels in a signed header and is checked against policy, so a key authorized for one feed cannot interfere with another. Cross-channel actions fail closed.

Tier 3

Payload encryption

AES-256-GCM · 96-bit IV · 128-bit tag

The body is encrypted with a fresh per-message IV; the canonical SESAME headers are bound in as additional authenticated data. Defeats signal reconnaissance on the wire. Encryption keys live in a separate namespace from signing keys and rotate independently.

Additive and independent. Tier 1 ⊂ Tier 2 ⊂ Tier 3. Enable per channel, raise the floor over time.

On the wire

A byte-exact spec, not a vibe.

SESAME is specified down to the canonical signing string and the AEAD construction, so a signer and a verifier in any language agree byte-for-byte. Below is a real Tier-2 request and the exact string its signature covers, taken from the published conformance vectors.

ESAM request · Tier 1 + 2
POST /esam?channel=SportsFeed-East HTTP/1.1
Host: pois.example
Content-Type: application/xml
X-SESAME-Version: 1.0
X-SESAME-KeyId: sas-east-01
X-SESAME-Timestamp: 2026-02-24T18:00:00Z
X-SESAME-Nonce: a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
X-SESAME-Scope: channel=SportsFeed-East
X-SESAME-Signature: 68762486d0301b07…a8c32641

<SignalProcessingNotification
   acquisitionPointIdentity="ap-1"/>
canonical string the HMAC covers
POST
/esam?channel=SportsFeed-East
2026-02-24T18:00:00Z
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
d64f3b54575e97f1…d356868f   ; sha-256(body)
channel=SportsFeed-East     ; scope, Tier 2+
401 sesame_missing_headers 401 sesame_unknown_key 401 sesame_expired_timestamp 401 sesame_replay_detected 401 sesame_signature_mismatch 403 sesame_scope_denied 400 sesame_decrypt_failed 401 sesame_key_revoked
Measured, not estimated

Security you can leave on in production.

Criterion benchmarks of the reference implementation on AWS c6i.xlarge (Intel Ice Lake, AES-NI and SHA extensions). The full combined path, with all tiers active, stays far inside a 1 ms budget.

3.31 µs
Inbound p50 at 1 KB
verify + authorize + decrypt
0.028 ms
Worst-case p99 across all sizes
outbound encrypt + sign at 16 KB
~35× margin
Inside the 1 ms per-request
overhead budget
Combined per-request path1 KB p501 KB p994 KB p5016 KB p99
Inbound: verify + authz + decrypt (Tier 1+2+3)3.31 µs3.43 µs8.02 µs0.027 ms
Outbound: encrypt + sign (Tier 1+3)4.23 µs4.25 µs8.94 µs0.028 ms

Pure-Rust RustCrypto stack (hmac, sha2, aes-gcm), so it builds and runs anywhere. Even on a virtual CPU with no AES-NI or SHA extensions, the worst-case combined p99 is 0.219 ms, still under the 1 ms budget. Reproduce with cargo bench --bench sesame_overhead.

One protocol, one implementation

Link the SDK, speak SESAME natively.

Any ESAM participant (POIS, ADS, encoder, packager, decoder) links one library and shares a byte-identical implementation of the wire rules. Native ports in four languages are each proven against the same golden vectors, so a signer in any of them interoperates with a verifier in any other.

Rust
crates.io · sesame-esam
✓ canonical
Python
PyPI · sesame-esam
✓ conformant
C++
CMake · vcpkg port
✓ conformant
Go
go module
✓ conformant

Golden vectors are the contract

A language-neutral set of conformance vectors pins the wire format. Every port must reproduce each expected value byte-for-byte, so implementations cannot silently diverge.

No I/O, no framework lock-in

verify_request and sign_response take the request parts, headers, body, and the current time. The host owns its resources through injected KeyProvider and ReplayCache traits.

Verify-only builds

Verification is RNG-free. Signing needs a fresh nonce and IV, so the CSPRNG helpers are feature-gated: build --no-default-features for a verify-only or embedded host.

Read the API docs SDK on GitHub $pip install sesame-esamcopy
See it working

rust-pois: the reference implementation.

SESAME was extracted byte-for-byte from rust-pois, a self-contained POIS / ESAM server that signs live ESAM traffic. It is the working demo: the golden conformance vectors are generated from it, and the SDK exists to be the one shared home of the protocol it proves.

Standards-track, openly licensed

A profile for ESAM, proposed for SCTE 130-9.

SESAME mirrors the ANSI/SCTE 130-9 draft and adds nothing to the existing SCTE 130 schemas. Where the draft is silent, the reference implementation adopts a documented working construction and feeds the fix back into the paper, so the spec and the code converge on one wire format.

SCTE 130-9 SESAME profilePROPOSED SCTE 130-3 ESAMUNCHANGED SCTE-35 splice signalingCARRIED HMAC-SHA256 (RFC 2104 · FIPS 180-4)TIER 1 AES-256-GCM (NIST SP 800-38D)TIER 3 Conformance vectorsPUBLISHED

One home for the protocol

The SDK is the canonical implementation; rust-pois is intended to depend on it. Byte-level parity is pinned by golden vectors generated from rust-pois and reproduced in the SDK's conformance tests, so the two cannot drift apart. sesame-sdk →

Open core, clear line

The protocol, the pure core, the trait seams, and the single-node reference replay cache are open, dual-licensed MIT or Apache-2.0. Operating SESAME at scale (a distributed replay store, multi-tenant key management, audit) sits above the traits. crates.io →

Adopt incrementally

Authenticate the control plane.
Without rewriting it.

Start at Tier 1 on one channel, leave every Tier-0 peer untouched, and raise the floor as integrations come online. The spec, the SDK, and a working POIS are all open.