Approval envelope and revocation list formats
Two signed files decide what a player may show: the approval envelope that travels with every media file, and the revocation list that takes an approval back. This page describes both so that a player, a CMS or a checking tool can read them without our software.
Reference pages: Approval envelope and revocation list formats and Device protocol.
The approval bundle
An approved creative is delivered as two files with the published naming: the media file and its envelope, for example spot.mp4 and spot.mp4.p7s. Download the envelope of an approval with the integration API (GET /api/v1/approvals/{number}/envelope, scope read:approvals). The envelope is useless without the file it names, and the file is not allowed on a screen without its envelope.
The envelope
The envelope is one CMS SignedData in DER form (a .p7s file). Its signed content is the manifest of the approval, in canonical JSON (RFC 8785), which names the media file by its SHA-256.
A production approval carries two signatures (the test contour can also issue single-signature envelopes, and says so in the manifest note):
- The platform signature, ECDSA P-256 with SHA-256, made with the approval key of the platform. Every player can check it offline.
- The approver's own state signature (a GOST 2015 signature made in NCALayer). The platform signature commits to the SHA-256 of the state signature, so the state signature cannot be removed or swapped, and a later time stamp, added as an unsigned attribute, does not break the commitment.
The manifest holds the version v, the environment env (test or prod), the approval number, the approval and authority identifiers, the advertiser, the media (sha256, size, duration_ms, width, height), the validity (valid_from, valid_until), the structures the approval covers, the regulation (code, version) and issued_at. The public page /v1/approval/{number} shows the same manifest with the advertiser's number masked, and manifest_sha256, the hash of the original bytes.
Signed attributes and key usages
The platform signature carries these signed attributes and the certificates carry these extended key usages. All identifiers are in the arc 1.3.6.1.4.1.59999.1.
| Identifier | Used for |
|---|---|
1.3.6.1.4.1.59999.1.1 | Signed attribute: the registration number of the media |
1.3.6.1.4.1.59999.1.2 | Signed attribute: the identifier of the approving authority |
1.3.6.1.4.1.59999.1.3 | Signed attribute: the expiry of the approval |
1.3.6.1.4.1.59999.1.4 | Signed attribute: SHA-256 of the state signature value |
1.3.6.1.4.1.59999.1.5 | Signed attribute: the environment, test or prod |
1.3.6.1.4.1.59999.1.6 | Extended key usage of the approval certificate |
1.3.6.1.4.1.59999.1.7 | Extended key usage of the status certificate: revocation lists, audit anchors, statistics seals |
1.3.6.1.4.1.59999.1.8 | Extended key usage of the device command certificate |
This arc is provisional: it is a private test arc. A registered arc replaces it before firmware is told to trust an envelope in production, and the device protocol stays in beta until then. Do not hard-code the numbers in anything that has to outlive the test contour.
What a player decides
A player verifies the file before it shows it and reports a refusal as exactly one code:
| Code | Meaning |
|---|---|
NO_SIGNATURE | There is no envelope |
BAD_SIGNATURE | The signature, the certificate chain or the key usage is wrong |
HASH_MISMATCH | The file is not the one the manifest names |
EXPIRED_APPROVAL | Outside the validity of the approval, before or after it |
REVOKED | The approval is on the current revocation list |
The state signature is checked by the platform when the approval is made. A player that cannot read GOST keys passes on the platform signature and reports the state signature as present but not checked (OUTER_NOT_VERIFIED in tanba-verify). Stock tools such as OpenSSL cannot read the GOST key either, so use tanba-verify, from the Downloads page, or the checks of your own player.
The revocation list
The revocation list is a CMS SignedData with the list attached, signed with the status key of the platform. The key carries the status usage, so an approval certificate can never produce a list. Fetch the newest list from https://verify.tanba-ooh.kz/v1/revocations/latest (add ?format=json for the body and the signature as JSON), a given version from https://devices.tanba-ooh.kz/d/v1/revocations/{version}. The calls are open and cached for 60 seconds.
The body is canonical JSON:
{"v": 1, "env": "prod", "version": 42, "issued_at": "2026-10-14T08:00:00Z", "not_after": "2026-10-15T08:00:00Z",
"revoked": [{"approval_number": "TNB-2026-000123", "revoked_at": "2026-10-14T07:30:00Z", "ground_code": "court_order"}],
"revoked_devices": [{"device_id": "5c0e8f3a-71d2-4b6e-9a14-d8e2f7b30c59", "cert_serial": "1234567890123", "revoked_at": "2026-10-14T07:45:00Z"},
{"device_id": "a41d7b20-93c6-4e58-8f1b-0d6e2a9c5473", "pubkey_sha256": "ab12c4d7e9f0a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f607182930", "revoked_at": "2026-10-14T07:50:00Z"}]}
versiongrows by one with every new list. A new list is issued at once when an approval or a device is revoked, and also periodically.- A revocation is final: lists only grow. An entry never leaves a list, and the platform refuses to issue a list that drops one.
- On the certificate channel there is one entry for each certificate serial the device ever held, written in decimal. On the signed channel the entry carries
pubkey_sha256, the SHA-256 in hex of the DER public key. A list withoutrevoked_devicesmeans none. ground_codeis the code of the legal ground of the revocation.
What a player does with a list
- It keeps the newest list it has seen. A list whose
versionis not above the one in use is ignored, and so is a list past itsnot_after, so a stale list cannot bring a revoked approval back. - An approval on the list is refused as
REVOKED. - It ignores device entries that are not its own. If its own id is on the list, it enters the state
revoked: a black page, no playing, no heartbeats, no telemetry, and it stays there across restarts. A player that is answereddevice_unauthorizedreads the public list itself to find out why.
Check a list offline with tanba-verify revocations list.p7s --ca root.pem; it prints the approvals and then the devices.