Metadata-Version: 2.5
Name: sesame-esam
Version: 0.1.4.post2
Summary: Native Python implementation of SESAME, the proposed SCTE 130-9 security layer for the ESAM interface (HMAC auth, channel-scoped authorization, AES-256-GCM payload encryption).
Project-URL: Homepage, https://github.com/bokelleher/sesame-sdk
Project-URL: Repository, https://github.com/bokelleher/sesame-sdk
Author: Bo Kelleher
License-Expression: MIT OR Apache-2.0
Keywords: ad-insertion,aes-gcm,cryptography,esam,hmac,scte,sesame
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.8
Requires-Dist: cryptography>=3.4
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == 'dev'
Description-Content-Type: text/markdown

# sesame-esam (Python)

A native **Python** implementation of SESAME (Secure ESAM Authentication and
Message Encryption), the proposed SCTE 130-9 security layer for the ESAM
interface. A sibling of the Rust crate and C++ SDK in this repo, proven against
the **same golden vectors** ([`test-vectors/`](https://github.com/bokelleher/sesame-sdk/tree/main/test-vectors)), so a Python signer and a Rust,
C++, or rust-pois verifier interoperate byte-for-byte.

- **Three tiers over a Tier-0 baseline:** HMAC-SHA256 auth (1), channel-scoped
  authorization (2), AES-256-GCM payload encryption (3), plus signed responses.
- **One dependency:** [`cryptography`](https://pypi.org/project/cryptography/)
  for AES-256-GCM (`hmac`/`hashlib` from the stdlib cover the rest).
- **Pythonic API:** `verify_request` / `sign_response`; failures raise
  `SesameError` (with `.code` and `.http_status`, Appendix A.7).

PyPI package: `sesame-esam`; import name: `sesame`. See
[`SESAME.md`](https://github.com/bokelleher/sesame-sdk/blob/main/SESAME.md) for the byte-exact wire format (draft v0.5).

The threat model, protocol design, and performance results are published in
B. Kelleher, ["SESAME: A Layered Security Framework for SCTE 130 ESAM with
Sub-Millisecond Overhead"](https://revistas.set.org.br/ijbe/article/view/342),
*SET International Journal of Broadcast Engineering*, vol. 12, 2026,
doi:[10.18580/setijbe.2026.6](https://doi.org/10.18580/setijbe.2026.6). BibTeX
is in the [main README](https://github.com/bokelleher/sesame-sdk#paper).

## Install

```sh
pip install sesame-esam
```

## Quick start

Verify an inbound request (the POIS side):

```python
from sesame import (verify_request, RequestContext, SesameConfig, SesameHeaders,
                    StaticKeyProvider, ChannelScope, InMemoryReplayCache, Tier, SesameError)
import time

keys = StaticKeyProvider().with_signing_key(
    "sas-east-01", b"shared-secret", ChannelScope.list(["SportsFeed-East"]))
replay = InMemoryReplayCache(300)

headers = SesameHeaders.from_lookup(lambda name: request_headers.get(name))
ctx = RequestContext("POST", "/esam", target_channel=None)
try:
    v = verify_request(SesameConfig(), keys, replay, ctx, headers, body,
                       int(time.time()), Tier.ONE)
    # v.plaintext is the ESAM XML; v.achieved_tier / v.key_id / v.scope_channel
except SesameError as e:
    # e.code (SesameErrorCode), e.http_status
    ...
```

Sign an outbound response (the POIS side):

```python
from sesame import sign_response, ResponseParams, SesameConfig, Tier
import time

params = ResponseParams(signing_key_id="pois-primary",
                        correlation="ap-1:sigid-20260224-001", tier=Tier.ONE)
resp = sign_response(SesameConfig(), keys, params, xml, int(time.time()))
# attach resp.headers (list of (name, value)), send resp.body with resp.content_type
```

## Development

```sh
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]"
pytest -q          # conformance (golden vectors) + unit (KATs + negative matrix)
python examples/sign_request.py 3
```

## License

Dual-licensed under [MIT](https://github.com/bokelleher/sesame-sdk/blob/main/LICENSE-MIT) or [Apache-2.0](https://github.com/bokelleher/sesame-sdk/blob/main/LICENSE-APACHE).
