Content Authorization Token (ContentAuthZ)
If you are using Contego/Conax products, please refer to the documentation available at https://doc.integra.nagra.com/.
1. About
This page defines the format of the Content Authorization Token that must be generated by the service providers in order to authorize SSP to create a DRM license for a specific OTT content.
2. Header
2.1. Schema
{"$schema":"http://json-schema.org/draft-04/schema#","title":"SSP Token Header Schema","required":["typ","alg","kid"],"properties":{"typ":{"description":"JSON Web Token type","type":"string","value":"JWT"},"alg":{"description":"Hashing algorithm used","type":"string","value":"HS256"},"kid":{"description":"Identifier of the credential used to sign the token","type":"string"}}}
2.2. Sample
{"typ":"JWT","alg":"HS256","kid":"263953"}
3. Payload
3.1. Schema
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Content Authorization Token Payload Schema",
"required": [
"typ",
"ver",
"contentRights"
],
"properties": {
"typ": {
"description": "CLM content authorization token type",
"type": "string",
"value": "ContentAuthZ"
},
"ver": {
"description": "CLM content authorization token version",
"type": "string",
"value": "1.0"
},
"exp": {
"description": "Expiration date of the token, as Epoch time in secs",
"type": "integer",
"minimum": 0,
"maximum": 4294967295
},
"jti": {
"description": "Unique token identifier, used for anti-replay. Anti-replay is enforced by the SSP service whenever both jti and exp fields are present and token can be decrypted and/or verified against its signature. When anti-replay is enforced, validity of the token must not exceed 24 hours, otherwise the token will be rejected.",
"type": "string"
},
"device": {
"description": "Device definition used to bind the authorization to a given device. If not given, anti-replay can be enabled by providing both jti and exp fields.",
"required": [],
"properties": {
"deviceUniqueId": {
"description": "Unique device identifier coming from the DRM. Examples: { Widevine: '4368726f6d6543444d2d57696e646f77732d783836', PRM: 'prm.TEE1.DeviceId-01', PlayReady: 'e7b772dc-9d74-982b-f0b4-261f30301efe', Fairplay: 'DI.SDovyiU4XDlM5uOLHCx0Foau+DA', SW-PRM (iOS): 'prm.iOS.e195f8ac631ec537f802b94cecd0762eab3a6cfb3a0d8f41232641b67459dd8e', SW-PRM (Android): 'prm.Android.2988ed859bfc6ffbf46b9d955653211b5cf4617674c18b56b459c25ad07c4b50' }",
"type": "string"
},
"deviceId": {
"description": "Public device identifier defined by the operator used to bind request with registered device",
"type": "string"
},
"watermarking": {
"description": "Flag representing device watermarking enabled/disabled",
"type": "boolean",
"default": "false"
},
"visibleMark": {
"description": "Flag specifying if the visible mark (stub mode) for test is enabled or disabled",
"type": "boolean",
"default": "false"
},
"watermarkSettingIndex": {
"description": "Index of the watermarking Settings Map to apply",
"type": "integer",
"minimum": 0,
"maximum": 4294967295
},
"ipAddress": {
"description": "CURRENTLY NOT USED - Device IP address. Format supported are either: IPV6 string compliant with RFC 5952, IPV4 string compliant with Dot-decimal notation",
"type": "string"
},
"model": {
"description": "CURRENTLY NOT USED - DRM device model",
"type": "string"
},
"drm": {
"description": "DRM type - CONNECT/PRM (PRM), PlayReady (PR), Widevine (WV), Fairplay (FP), SW-PRM (SWPRM), TVKey (TK)",
"enum": [
"PRM",
"PR",
"WV",
"FP",
"SWPRM",
"TK"
]
},
"accountId": {
"description": "Account identifier as provided by the business portal",
"type": "string"
},
"watermarkId": {
"description": "Identifier for the watermarking with Quickmark (QM)",
"type": "integer",
"minimum": 0,
"maximum": 4294967295,
"deprecated": true
}
}
},
"contentRights": {
"description": "Content for which the authorization is being granted (only one content right is authorized per request)",
"type": "array",
"minItems": 1,
"maxItems": 1,
"items": {
"required": [
"contentId"
],
"properties": {
"contentId": {
"type": "string",
"description": "Unique content identifier used to interface the key server and the license server. This content identifier needs to match the identifier embedded in the DRM signaling associated to the content. (Format: UTF-8)",
"maxLength": 256
},
"encryptionMethod": {
"description": "Encryption method of the content",
"default": "RAW_AES_128_CTR_CENC",
"enum": [
"RAW_AES_128_CBC_ALS",
"RAW_AES_128_CTR_CENC",
"RAW_AES_128_SAMPLE_ALS",
"RAW_AES_128_CBC_CBCS"
]
},
"start": {
"description": "Validity start of the right. If not provided, defaults to the moment where the license is delivered.",
"$ref": "#/definitions/iso8601Date"
},
"end": {
"description": "Validity end of the right. If not provided, unlimited validity.",
"$ref": "#/definitions/iso8601Date"
},
"duration": {
"description": "Duration of the rights, expressed in seconds, once playback session is started. Unlimited if not provided, bound by the right's end.",
"type": "integer",
"minimum": 0,
"maximum": 4294967295
},
"storable": {
"description": "Whether the client can persist the license (for off-line consumption, not linked to a given session). Attention: Most browsers don't support storable licenses (Internet Explorer, Edge, Chrome, Firefox, ...)",
"type": "boolean",
"default": "false"
},
"usageRulesProfileId": {
"description": "Reference to the profile of usage rules applicable, mutually exclusive with defaultUsageRules. ASCII char only.",
"type": "string",
"maxLength": 50
},
"defaultUsageRules": {
"description": "DEPRECATED. Set of usage rules applicable to the ContentRight and to all tracks by default. Tracks may override any rule by including specific usage rules. Mutually exclusive with usageRulesProfileId.",
"$ref": "#/definitions/usageRules"
},
"tracks": {
"description": "List of content tracks: SD, HD, Audio, full HD, UHD. Not needed if no specific rules or keys are needed for a given track",
"type": "array",
"minItems": 0,
"items": {
"$ref": "#/definitions/track"
}
},
"defaultKcIds": {
"description": "Optional list of content key identifiers. They are applicable as default key identifiers for all tracks, if any. Refer to page 'Rules for Content Keys' for details.",
"type": "array",
"minItems": 0,
"items": {
"$ref": "#/definitions/uuid"
}
},
"sessionControl": {
"description": "Session Control element containing the necessary elements to enforce it at the content right level",
"properties": {
"groupId": {
"description": "The Group identifier to which applies the session control. DEPRECATED! Use rather the groups below.",
"type": "string",
"maxLength": 256
},
"sessionControlEnabled": {
"description": "DEPRECATED! When used, tells if session control is required or not. If true, maxSessions limit will be enforced.",
"type": "boolean",
"default": "true"
},
"sessionId": {
"description": "External Identifier of the generated session token",
"type": "string",
"maxLength": 256
},
"maxSessions": {
"description": "The Max number of sessions allowed. This field applies to the groupId if it is present, Otherwise it applies to the accountId. DEPRECATED! Use rather the groups below when it applies to group",
"type": "integer",
"default": 0,
"minimum": 0,
"maximum": 4294967295
},
"groups":{
"type": "array",
"minItems": 0,
"maxItems": 100,
"items": {
"required": [
"groupId",
"maxSessions"
],
"properties": {
"groupId": {
"type": "string",
"description": "The Group identifier to which applies the session control.",
"maxLength": 256
},
"maxSessions": {
"description":"The Max number of sessions allowed for this group",
"type": "integer",
"default": 0,
"minimum": 0,
"maximum": 4294967295
}
}
}
}
}
}
}
}
}
},
"definitions": {
"cappingResolution": {
"description": "Maximum resolution authorized - any video signal with a higher resolution than the configured capping resolution will be capped",
"enum": [
"NO_OUTPUT",
"QCIF",
"CIF",
"SD",
"HD",
"FULL_HD",
"NO_RESTRICTIONS"
],
"default": "NO_RESTRICTIONS"
},
"iso8601Date": {
"description": "Standard representation of date and time according to ISO-8601 standard (see https://tools.ietf.org/html/rfc6350) - Example: '2018-09-27T09:45:12Z'",
"type": "string",
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}([.,][0-9]{1,3})?Z$"
},
"track": {
"description": "One content may contain multiple video resolution and audio tracks. Each track may have specific usage rules and may be encrypted with specific keys.",
"required": [
"type"
],
"properties": {
"type": {
"description": "Video resolution or audio track type",
"type": "string"
},
"usageRulesProfileId": {
"description": "Reference to the profile of usage rules applicable to the track, overriding profile ID defined for the ContentRight, mutually exclusive with usageRules. ASCII char only.",
"type": "string",
"maxLength": 50
},
"usageRules": {
"description": "DEPRECATED. Set of usage rules applicable to the track, only needed if content keys are differentiated for each track. See 'Rules for Content Keys' for details.",
"$ref": "#/definitions/usageRules"
},
"kcIds": {
"description": "List of content keys specific for this track. Only needed if default keys are not available or do not apply to this track.",
"type": "array",
"minItems": 0,
"items": {
"$ref": "#/definitions/uuid"
}
}
}
},
"usageRules": {
"description": "DRM agnostic content usage rules granted by the license. Default values apply when not provided. Each license server shall map them to the DRM specific rule name & value.",
"properties": {
"minLevel": {
"description": "Device robustness level required to play the track. One of: 0 - test/integration devices, 1 - SW secure crypto, 2 - HW secure crypto, 3 - HW secure crypto+decode, 4 - Certified HW secure crypto+decode",
"type": "integer",
"minimum": 0,
"maximum": 4,
"default": "1"
},
"analogCappingResolution": {
"description": "No bit rate capping by default",
"$ref": "#/definitions/cappingResolution"
},
"digitalOnly": {
"description": "No analog output by default",
"type": "boolean",
"default": "true"
},
"hdcp": {
"description": "HDCP protection applies by default",
"type": "boolean",
"default": "true"
},
"hdcpType": {
"description": "No HDCP downgrade by default",
"default": "TYPE_1",
"enum": [
"TYPE_0",
"TYPE_1"
]
},
"imageConstraint": {
"description": "Downscale not needed as analog output not authorized by default",
"type": "boolean",
"default": "false"
},
"uncompressedDigitalCappingResolution": {
"description": "No bit rate capping by default",
"$ref": "#/definitions/cappingResolution"
},
"deviceCappingResolution": {
"description": "No bit rate capping by default",
"$ref": "#/definitions/cappingResolution"
},
"unprotectedAnalogOutput": {
"description": "No analog output by default",
"type": "boolean",
"default": "false"
},
"unprotectedDigitalOutput": {
"description": "No digital output by default",
"type": "boolean",
"default": "false"
},
"watermarkingEnabled": {
"description": "Device watermarking authorized",
"type": "boolean",
"default": "true"
},
"airplayOutput": {
"description": "video is authorized to be played on an external device connected by AirPlay",
"type": "boolean",
"default": "false"
}
}
},
"uuid": {
"description": "128-bits universally unique identifier - UUIDs are documented as part of ISO/IEC 11578:1996. Example: '123e4567-e89b-12d3-a456-426655440000'",
"type": "string",
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
}
}
}
3.2. Diagram
3.3. Samples
{"typ":"ContentAuthZ","ver":"1.0","exp":1463326662,"jti":"e72782ef-8b1d-4f9f-8bdf-02fe55d1d5a0","contentRights":[{"contentId":"LYS001990","start":"2015-05-19T19:42:18Z","end":"2016-05-21T19:42:18Z","defaultKcIds":["ffffffff-aaaa-bbbb-cccc-000000000501"]}]}
{"typ":"ContentAuthZ","ver":"1.0","exp":1463326662,"device":{"deviceUniqueId":"prm.NOCS.14300", "watermarking": false},"contentRights":[{"contentId":"LYS001990","start":"2015-05-19T19:42:18Z","end":"2016-05-21T19:42:18Z","defaultUsageRules":{"imageConstraint":true},"tracks":[{"type":"SD"},{"type":"HD","kcIds":["ffffffff-aaaa-bbbb-cccc-000000000501"]}],"defaultKcIds":["ffffffff-aaaa-bbbb-cccc-000000000500"]}]}
4. Signature
In order to build the signature, the token's header and payload are signed like this:
- The signing key that is used corresponds to the SSP tenant's credential identified by "kid" claim from the token's header.
- The algorithm that is used is HMAC-SHA256, as described in https://tools.ietf.org/html/rfc7518 , section 5.2.