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.

A fair question

Why not just use TLS?

You should: run SESAME over HTTPS. But TLS secures the transport, while ESAM needs guarantees at the message layer that a tunnel cannot give, inside a latency and migration envelope mutual-TLS cannot meet. SESAME complements TLS, it does not replace it.

LATENCY · STATE

A handshake you cannot afford

mTLS adds round-trips and connection state. Across the signal chain (SAS → load balancer → POIS → ADS, and back) that compounds and overruns the ≤ 1 ms security budget. SESAME is stateless and per-request: low single-digit microseconds, with no session to establish.

MIGRATION

No flag day

Legacy encoders and Signal Acquisition Systems speak plain HTTP and have no practical path to client certificates. Per-channel tiers let Tier-0 peers keep working while others adopt on their own schedule. mTLS forces a coordinated client-certificate rollout across every device at once.

TERMINATION

It survives TLS termination

In cloud deployments TLS is usually terminated at the edge or load balancer, leaving the inner hop to the POIS in plaintext. SESAME's HMAC over a canonical string (including a hash of the body) protects integrity end to end, and catches tampering by an intermediary the tunnel implicitly trusts.

AUTHORIZATION · BINDING

It secures the message, not just the pipe

TLS authenticates the endpoint; it does not scope what that endpoint may do. SESAME binds a credential to its channels (a regional affiliate cannot touch a national feed), signs the POIS response back to the request that asked for it, and can encrypt the payload per channel. A secure pipe says nothing about any of these.

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. Full methodology and tables →

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.

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 →

Read the full write-up: the SESAME paper, SET IJBE submission (PDF) →

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.