Null-DRM-Official/apps/modules
404errordeveloper 2fa8f2435f Initial commit: Null DRM Official
Capture, decrypt, and restream toolkit with compiled-in app modules
(RTE, TG4, BBC), on-device MITM proxy, streamd control plane, and www.
BBC module.yaml is published (clear streams); other module values stay local.
2026-10-06 00:25:35 +02:00
..
all Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00
bbc Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00
provider Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00
rte Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00
tg4 Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00
go.mod Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00
go.sum Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00
README.md Initial commit: Null DRM Official 2026-10-06 00:25:35 +02:00

App modules

One Go package per streaming app. Every module is compiled into the binary — there is no plugin loading and no modules directory to point a binary at.

apps/modules/                 Go module: drmdecryption/modules
  go.mod                      replace drmdecryption => ../pkg
  all/all.go                  blank-imports every module — the link point
  provider/                   shared base: values loading, channel aliases, durations
  <name>/*.go                 TRACKED: the app's logic
  <name>/module.yaml          usually GITIGNORED values (bbc is published)

Tracked code, untracked values

This split is the rule for modules with secrets; BBC is the exception (clear streams — package id + channel map only, so bbc/module.yaml is committed):

<name>/*.go (tracked) <name>/module.yaml (gitignored except bbc)
launch + auto-play sequence android package id
navigation idioms license URL, origin hostnames
manifest rewrite shape channel KIDs, account id, policy key
catalog request flow video ids, playback config URL
which capture fields are required UI selectors, labels, aliases

Module Go source contains no account id, policy key, video id, license URL, origin host or KID. Modules with secrets have a test asserting an empty config yields empty credentials:

go -C apps/modules test ./... -run NoHardcoded -v

Values arrive by flag → environment → module.yaml → Go default, and only mechanical defaults (timeouts, DASH timescales, card geometry) live in code:

./bin/drm catalog --app tg4 --channel ioi --tg4.policy-key BCpkAD...
export TG4_POLICY_KEY=BCpkAD...        # same thing

Adding a module

  1. Create apps/modules/myapp/ with config.go and myapp.go
  2. Register from init(): appreg.Register(Name, New) and appreg.RegisterFlags(bindFlags)
  3. Add one line to all/all.go: _ "drmdecryption/modules/myapp"
  4. Create apps/modules/myapp/module.yaml with your values
  5. go -C apps/cli build -o ../../bin/drm . then ./bin/drm modules

Authoring guide: docs/modules.md — the full contract, uiflow reference, optional capability interfaces, and a checklist.

Finding the values: docs/capture.md for a new app, docs/providers/ for the modules already here.

Run

./bin/drm modules                                        # what is compiled in
./bin/drm capture --app rte --channel rteone --auto-play
./bin/drm capture --app bbc --channel bbcone   # transparent MITM; play on phone; MPD only
./bin/drm catalog --app tg4 --channel ioi --keys --wvd data/device.wvd
./bin/drm agent run --config apps/agent/agent.yaml