OpenTV ENTera & OpenTV Platform Documentation

Enabling secure interaction between CWM and third-party encoders/packagers

This an INTERNAL page intended primarily for use by GOS. Not for publication.


Introduction

This feature enable secure interaction between CWM and third party encoders/packagers by adding a JWT token to the request header.

Note that:

  • The token will be the part of the Authorization header.

  • The algorithm used to generate the token is HS256.

Assumptions

  • recorderType should be mapped in the capture, validation, and purge profiles.

Configuration

The configuration can be changed from the CWM configmap.

Configuration key

Example value

Description

isSecurityEnabled

false

This key specifies whether the token is to be created or not.

If true, the token will be sent as part of the header.

secretKeyForRecorderType

VOS360=secret@12345,Broadpeak=secret

secret key for recorderType and key should be mapped with recorderType in the profile.

token.expiry.in.ms

300000

Token expiry period

include.body.in.token

false

This key specifies whether to include body in claims.

If true, the request body will hashed with the HS256 algorithm and sent as part of claims.

Sample job header

JavaScript
{
  Authorization=Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtZXRob2QiOiJQT1NUIiwiZXhwIjoxNjQ1NTEwODg4LCJib2R5Ijp7ImFsZyI6IkhTMjU2IiwiaGFzaCI6IjBhYWE4YTRhYjFmZmRjNmI5NDk5MjVmNDJlYzJmYjk2Nzg1Y2MzYzhhZGQ3MGE2MTM5OWRkNDhmNDY4ZGM0MGMifSwiaWF0IjoxNjQ1NTEwNTg4LCJ1cmkiOiJodHRwOi8vbG9jYWxob3N0Ojc5OTUvY3hmL3ByaS92MS9jYXB0dXJlZGFzc2V0cyJ9.x3uISyVblV90huIvEhqX168S3vij1y11_sMkhqzL_8Y,
  breadcrumbId=ID-WINUKO4gyDv8fo1-1645510304213-0-1,
  CamelHttpMethod=POST,
  DeviceId=deviceId1,
  eventWithInBuffer=true,
  JobCount=1,
  numberOfRetries=3,
  requestUri=http: //localhost: 7995/cxf/pri/v1/capturedassets,
  routeRetryDelay=15,
  workflowJobId=22022022061618494_17,
  WorkflowJobs=[
    PersistedWorkflowJob[
      id='22022022061618494_17',
      creationDate=TueFeb2211: 46: 18IST2022,
      lastModificationDate=TueFeb2211: 46: 26IST2022,
      start=TueFeb2211: 00: 00IST2022,
      end=ThuMar2411: 00: 00IST2022,
      actualStartDate=TueFeb2211: 46: 26IST2022,
      actualEndDate=null,
      name='LiveCaptureUsingPRIv1 job for Editorial Content NAGRA_10002_001',
      metadataSet={
        eventId=NAGRA_10002_001,
        purgeProfileId=purge,
        editorialContentName=eventname0121345,
        editorialContentId=NAGRA_10002_001,
        jobType=Capture,
        validationProfileId=validate,
        formatsByTechnical={
          "tech1_CNN": "iOS",
          "tech2_CNN": "Android"
        },
        cwmPodName=LocalPod
      },
      priority=1,
      profileId='capture',
      ownerId='NAGRA_10002_001',
      ownerType='EditorialContent',
      sourceServiceId='CPM',
      profileData=com.nagra.ml.sp.bcm.api.rest.admin.v1.model.GetProfile@65040acb,
      devicesData={
        processingDevice=com.nagra.ml.sp.bcm.api.rest.admin.v1.model.GetDevice@4da758dc
      },
      status=IN_PROGRESS,
      workflowInputProperties={
        sourceId=SOURCE123,
        numberOfRetries=3,
        processingUri=http: //localhost: 7995/cxf/pri/v1,
        securityInfo=[
          {
            packagingFormat=iOS,
            drmId=DRM101,
            drmSystemId=system123
          },
          {
            packagingFormat=Android,
            drmId=DRM102,
            drmSystemId=system123
          }
        ],
        captureEndDate=2022-02-22T05: 30: 00Z,
        ltcuAssetNamePrefix=ltcu_,
        type=,
        rescheduleDelay=3600,
        recordId=ltcu_NAGRA_10002_001,
        mode=,
        retryDelay=15,
        numberOfRetriesForRescheduling=3,
        recorderType=VOS360,
        captureStartDate=2022-02-22T05: 22: 00Z
      },
      workflowOutputProperties={
        
      },
      error='null',
      internalData=com.nagra.ml.sp.cwm.fwk.model.InternalData@6a097c4
    ]
  ],
  wrkFlwJb=PersistedWorkflowJob[
    id='22022022061618494_17',
    creationDate=TueFeb2211: 46: 18IST2022,
    lastModificationDate=TueFeb2211: 46: 26IST2022,
    start=TueFeb2211: 00: 00IST2022,
    end=ThuMar2411: 00: 00IST2022,
    actualStartDate=TueFeb2211: 46: 26IST2022,
    actualEndDate=null,
    name='LiveCaptureUsingPRIv1 job for Editorial Content NAGRA_10002_001',
    metadataSet={
      eventId=NAGRA_10002_001,
      purgeProfileId=purge,
      editorialContentName=eventname0121345,
      editorialContentId=NAGRA_10002_001,
      jobType=Capture,
      validationProfileId=validate,
      formatsByTechnical={
        "tech1_CNN": "iOS",
        "tech2_CNN": "Android"
      },
      cwmPodName=LocalPod
    },
    priority=1,
    profileId='capture',
    ownerId='NAGRA_10002_001',
    ownerType='EditorialContent',
    sourceServiceId='CPM',
    profileData=com.nagra.ml.sp.bcm.api.rest.admin.v1.model.GetProfile@65040acb,
    devicesData={
      processingDevice=com.nagra.ml.sp.bcm.api.rest.admin.v1.model.GetDevice@4da758dc
    },
    status=IN_PROGRESS,
    workflowInputProperties={
      sourceId=SOURCE123,
      numberOfRetries=3,
      processingUri=http: //localhost: 7995/cxf/pri/v1,
      securityInfo=[
        {
          packagingFormat=iOS,
          drmId=DRM101,
          drmSystemId=system123
        },
        {
          packagingFormat=Android,
          drmId=DRM102,
          drmSystemId=system123
        }
      ],
      captureEndDate=2022-02-22T05: 30: 00Z,
      ltcuAssetNamePrefix=ltcu_,
      type=,
      rescheduleDelay=3600,
      recordId=ltcu_NAGRA_10002_001,
      mode=,
      retryDelay=15,
      numberOfRetriesForRescheduling=3,
      recorderType=VOS360,
      captureStartDate=2022-02-22T05: 22: 00Z
    },
    workflowOutputProperties={
      
    },
    error='null',
    internalData=com.nagra.ml.sp.cwm.fwk.model.InternalData@6a097c4
  ],
  wrkFlwJbType=Capture
}

Sample JWT token 

JavaScript
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtZXRob2QiOiJQT1NUIiwiZXhwIjoxNjQ1NTEwODg4LCJib2R5Ijp7ImFsZyI6IkhTMjU2IiwiaGFzaCI6IjBhYWE4YTRhYjFmZmRjNmI5NDk5MjVmNDJlYzJmYjk2Nzg1Y2MzYzhhZGQ3MGE2MTM5OWRkNDhmNDY4ZGM0MGMifSwiaWF0IjoxNjQ1NTEwNTg4LCJ1cmkiOiJodHRwOi8vbG9jYWxob3N0Ojc5OTUvY3hmL3ByaS92MS9jYXB0dXJlZGFzc2V0cyJ9.x3uISyVblV90huIvEhqX168S3vij1y11_sMkhqzL_8Y

Note that the token contains three different parts: <header>.<payloadClaims>.<signature>:

  • Header– describes the cryptographic operations to compute the signature

  • Claims set – a set of JSON objects used to compute the signature

  • Signature – integrity protection of the claims set

Header

Name

Type

Mandatory

Description

alg

String

Yes

The algorithm used to produce the token.

type

String

yes

The type of token to produce

JavaScript
{
  "alg": "HS256",
  "typ": "JWT"
}

Claims set

Name

Type

Mandatory

Description

method

String

Yes

HTTP method

exp

Integer

Yes

Epoch timestamp after which the token expires

body

Object

No

Request body (only for capture job)

body.alg

String

No

Algorithm used for hashing the request body

body.hash

String

No

Request body after hashing

iat

Intger

Yes

Epoch timestamp at which the token was created

uri

String

No

Request URI

JavaScript
{
  "method": "POST"/"GET"/"DELETE",
  "exp": 1645510888,
  "body": {
    "alg": "HS256",
    "hash": "0aaa8a4ab1ffdc6b949925f42ec2fb96785cc3c8add70a61399dd48f468dc40c"
  },
  "iat": 1645510588,
  "uri": "http://localhost:7995/cxf/pri/v1/capturedassets"
}

The body in claimSet will be available only for POST requests.

Sample encoder header

JavaScript
{
Authorization=[Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtZXRob2QiOiJQT1NUIiwiZXhwIjoxNjQ2MDM2NTQyLCJib2R5Ijp7ImFsZyI6IkhTMjU2IiwiaGFzaCI6ImY1N2VmOWZiZTk4NGM2ZWYwOGEyZjQzN2Y0ZDE2Zjk5YTk4YzA2MDg0YWM2NTQ0NjFlN2Q3ZDE0NzU1NTkxMTcifSwiaWF0IjoxNjQ2MDM2MjQyLCJ1cmkiOiJodHRwOi8vbG9jYWxob3N0Ojc5OTUvY3hmL3ByaS92MS9jYXB0dXJlZGFzc2V0cyJ9.o2mpO0qddFcd5StmXRJzgR9EDsZHxgGgUxMVsdFETPg],
Content-Type=[application/xml]
}