Token Authorization

Understand how DRMtoday Token Authorization works, why it protects users and content, and how to configure it for your organization.


How Token Authorization works

Core concept

The core principle of the DRMtoday licensing system is that when a user triggers a license request, your backend must provide a Customer Rights Token (CRT) to DRMtoday. This token dictates whether the user is allowed to receive a license and specifies the parameters the license should contain. Without this authorization, DRMtoday will not issue a license.

With Token Authorization (also called Upfront authentication, mode value UPFRONT), your backend embeds the CRT inside a signed JWT and delivers it to the player before the license request reaches DRMtoday. The player then sends that JWT in the x-dt-auth-token header — DRMtoday verifies the signature and issues the license without calling your server again.

Operational workflow

Token Authorization sequence diagram: User/Player, Your Backend, and DRMtoday Server
Token Authorization flow — from license request to DRM license delivery.
  1. Request video license — The player asks your backend whether the user may watch the content.
  2. Generate & sign JWT — Your backend builds the payload and signs it with the shared secret (see Signing and delivering the JWT).
  3. Deliver signed JWT — Your backend returns the JWT to the player over your own authenticated channel (API, session, etc.).
  4. License request — The player sends a license request to DRMtoday with the JWT in x-dt-auth-token.
  5. Validate & issue — DRMtoday verifies the signature and expiry, then issues the DRM license (see Security guarantees).

Signing and delivering the JWT

Only your backend holds the shared secret. The player never sees the secret — it only receives the finished JWT string. This is the trust boundary that prevents clients from forging their own authorization.

1. Build the JWT header and payload

Your backend assembles a JSON Web Token (RFC 7519) with two parts:

Header — identifies the signing algorithm and which secret DRMtoday should use:

{
  "kid": "1252fc63-7e2f-4142-81bb-c18b3c98f0c4",
  "alg": "HS256",
  "typ": "JWT"
}
  • kid — Key ID registered in the DRMtoday portal (SHARED_SECRET_KID). DRMtoday uses this to look up the matching shared secret when verifying.
  • alg — Signing algorithm. HS256 is the default (HMAC-SHA256).

Payload — carries authorization data DRMtoday needs to issue the license:

{
  "jti": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "iat": 1718700000,
  "optData": "{\"merchant\":\"46c7d6fb-...\",\"userId\":\"rental1\"}",
  "crt": "{\"assetId\":\"CPIX-test\",\"profile\":{\"type\":\"rental\",...}}"
}
  • jti — Unique token ID (prevents trivial replay within the validity window).
  • iat — Issued-at Unix timestamp. DRMtoday rejects tokens older than ~10 minutes.
  • optData — JSON string with merchant (organization ID) and userId.
  • crt — JSON string of the Customer Rights Token: asset ID, rental/play duration, and other playback constraints.

2. Sign with the shared secret (HS256)

The signing process produces a tamper-evident token in three dot-separated segments:

base64url(header) . base64url(payload) . base64url(HMAC-SHA256(signingInput, sharedSecret))

Concretely:

  1. Base64url-encode the header JSON and payload JSON.
  2. Concatenate them with a dot: signingInput = headerSegment + "." + payloadSegment.
  3. Compute HMAC-SHA256(signingInput, sharedSecretBytes) where sharedSecretBytes is the 32-byte (or 64-byte) key decoded from your hex secret (SHARED_SECRET_HEX).
  4. Base64url-encode the HMAC output as the third segment.

Because HMAC requires the secret key, no party without the secret can produce a valid signature. The player receives only the final string — for example:

eyJhbGciOiJIUzI1NiIsImtpZCI6IjEyNTJmYzYzLi4uIn0.
eyJqdGkiOiJhMWIyLi4uIiwiaWF0IjoxNzE4Ny4uLn0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

3. Deliver the token to the player

Your backend returns the signed JWT to the player through your own API (e.g. after the user logs in or purchases content). The player stores it temporarily and attaches it to the DRM license request as:

x-dt-auth-token: <signed JWT>

The shared secret itself never leaves your server. Even if a user inspects network traffic, they only see the JWT — not the key used to create it.

Why DRMtoday trusts this token: The valid HMAC signature proves the payload was created by a party that holds the same shared secret registered in the portal. Since only your backend and DRMtoday possess that secret, a correctly signed token is cryptographic proof that your backend authorized this specific playback request.

Security guarantees

The signing and validation flow above creates a secure chain from your business logic to the delivered DRM license:

Threat How Token Authorization mitigates it
User bypasses payment / entitlement checks Player cannot self-issue a token. Only your backend signs JWTs after applying your own authorization logic.
User forges or modifies the JWT HMAC signature breaks if any byte of header or payload is changed. DRMtoday rejects unsigned or tampered tokens.
Stolen JWT reused indefinitely Short TTL (~10 min from iat) and unique jti limit the replay window.
Shared secret exposed to the client Secret stays on your server and in DRMtoday portal only. The player receives the signed output, not the key.
License issued with excessive rights CRT embedded in the signed payload defines exact playback constraints. Tampering invalidates the signature.
Wrong organization's secret used kid in the header ties each token to a specific registered secret. Mismatched kid fails lookup.

In summary: your backend is the authorization authority (who may watch), the shared secret is the trust anchor (proof the decision came from you), and DRMtoday is the enforcement point (cryptographically verifies the proof before decrypting content). The video resource remains protected because decryption keys are only released when all three parts align. See also Callback Authorization for the alternative real-time callback model.

Comparison with Callback Authorization

Feature Token Authorization Callback Authorization
Primary flow Player → Backend → Player → DRMtoday Player → DRMtoday → Backend → DRMtoday
Required header x-dt-auth-token x-dt-custom-data
CRT delivery Embedded in signed JWT (crt claim) Returned by your backend in callback JSON
Security model JWT signature with shared secret (HS256) Real-time session validation on your server

Register or retrieve the shared secret

Before enabling Token Authorization, register a shared secret in the DRMtoday portal. Your backend uses this secret (identified by kid) to sign JWTs that DRMtoday will verify during license delivery.

Navigate to Token authorization

  1. Sign in to the DRMtoday dashboard and switch into your organization (see Using the CastLab GUI for sign-in steps).
  2. In the left sidebar, click Token authorization.
  3. Existing secrets are listed in the Shared secrets table — use Manage to view details. Copy the ID column as SHARED_SECRET_KID.
Token authorization shared secrets list in DRMtoday
Token authorization — list of shared secrets. Copy the ID as SHARED_SECRET_KID.

Create a new shared secret

Click Add shared secret + and complete the form:

  1. Enter a Description for your reference.
  2. Specify a key with 64, 96, or 128 hex characters in the Secret field (32, 48, or 64 bytes). Use the Random button to generate one.
  3. Ensure Enabled is checked.
  4. Click Add shared secret.
Add shared secret form in DRMtoday
Add shared secret — description (1), secret key (2), then Add shared secret (3).
Important: After submitting the form, the shared secret value is not shown again. Copy SHARED_SECRET_HEX before saving. Never commit shared secrets to source control — store them in environment variables or a secrets manager.

Copy values for your backend

Store these environment variables on your server:

  • ID (from the shared secrets table) → SHARED_SECRET_KID
  • Secret (hex) (saved at creation time) → SHARED_SECRET_HEX

Enable Token Authorization

After registering a shared secret, switch your organization's license delivery mode to Token authorization (UPFRONT). You can do this through the CastLab GUI or by calling the DRMtoday REST API directly.

After enabling Token Authorization:

  • Players must include a valid JWT in x-dt-auth-token on license requests.
  • Your backend signs tokens with the shared secret from Register or retrieve the shared secret.
  • DRMtoday will not call a callback URL during license delivery.

Using the CastLab GUI

The CastLab GUI is the DRMtoday web dashboard used to manage organizations and license delivery authorization.

Step 1 — Sign in and select your organization

  1. Open the DRMtoday dashboard:
    • Staging: https://fe.staging.drmtoday.com
    • Production: https://fe.drmtoday.com
  2. Log in with your CastLabs / DRMtoday account credentials.
  3. On My organizations, note the ID column (your Merchant ID / ORGANIZATION_ID) and click Switch to enter the organization.
DRMtoday My organizations screen
My organizations — copy the ID as ORGANIZATION_ID.

Step 2 — Open License Delivery Authorization

  1. In the left sidebar, click License delivery authorization.
  2. Open the Authorization tab.
License delivery authorization page in DRMtoday
Navigate to License delivery authorization (step 1).

Step 3 — Select Token authorization and save

  1. Under Default settings, select Token authorization (step 2 in the screenshot above).
  2. Click Save changes (step 3).

Via the DRMtoday REST API

Switch the organization to UPFRONT programmatically using the DRMtoday CAS (Central Authentication Service) protocol.

Prerequisites

  • DRMtoday API credentials — username and password for CAS login.
  • Organization ID — your merchant UUID.
  • Environment base URLs:
    • Auth: https://auth.staging.drmtoday.com (staging) or https://auth.drmtoday.com (production)
    • Frontend: https://fe.staging.drmtoday.com (staging) or https://fe.drmtoday.com (production)

Settings endpoint:

{FRONTEND_BASE_URL}/frontend/rest/config/v1/{ORGANIZATION_ID}/auth/settings

API Step 1 — CAS login (obtain TGT)

Endpoint: POST {AUTH_BASE_URL}/cas/v1/tickets

Body: username, password (form-urlencoded)

Response: HTTP 201 with Location header (TGT URL).

curl -i -X POST "https://auth.staging.drmtoday.com/cas/v1/tickets" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "username=YOUR_USERNAME" \
  --data-urlencode "password=YOUR_PASSWORD"

API Step 2 — Obtain service ticket

Endpoint: POST {TGT_URL}

Body: service={SETTINGS_URL} — must match the settings URL exactly.

Response: HTTP 200, body is the plain-text service ticket.

curl -s -X POST "https://auth.staging.drmtoday.com/cas/v1/tickets/TGT-..." \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "service=${SETTINGS_URL}"

API Step 3 — Set mode to UPFRONT

Endpoint: POST {SETTINGS_URL}?ticket={SERVICE_TICKET}

Body:

{ "mode": "UPFRONT" }

Response: HTTP 200 or 204.

curl -X POST "${SETTINGS_URL}?ticket=${SERVICE_TICKET}" \
  -H "Content-Type: application/json" \
  -d '{"mode":"UPFRONT"}'

API Step 4 — Verify settings (optional)

Endpoint: GET {SETTINGS_URL}?ticket={SERVICE_TICKET}

Confirm the response contains "mode": "UPFRONT".

API notes

  • Service tickets are single-use — obtain a new one for each operation.
  • TGT URLs expire — repeat CAS login if Step 2 fails.
  • Register the shared secret (Register or retrieve the shared secret) before switching players to token-based requests.

Verify the setup

After configuration, confirm that Token Authorization is active and the player receives a signed JWT at playback time.

Test on the VideoJS Demo

  1. Open the VideoJS Demo and enable Enable DRM.
  2. The License delivery authorization panel should show TOKEN as the current active method.
  3. Enter an Asset ID matching your packaged content (e.g. CPIX-test) and click Load Video.

Confirm drmConfig headers

In the Player Options panel, verify that drmConfig includes licenseHeaders with x-dt-auth-token — this confirms your backend successfully issued and attached the signed JWT.