Key rotation itv
This article explains how to manage key rotation for Origin Authentication and URL Signing for the iTV use case.
How does it work?
Qwilt has created empty keysets to support key rotation for origin authentication and URL signing. These keysets are linked to your Media Delivery site. Adding a key to a keyset and republishing the site triggers key rotation. Each time the site is republished, the newest key in the keyset becomes the active key.
| Site | Site ID | Keyset ID for origin authentication |
Keyset ID 1 for URL authentication |
Keyset ID 2 for URL authentication |
|---|---|---|---|---|
| ITVX live - STAGE | 670695203151226bfe1ca391 | 93 | 94 | 184 |
| ITVX live - PROD | 685bc85c1333d155828e7656 | 182 | 181 | 183 |
Note the different Site ID and Keyset ID values for staging and production.
Authentication
An API key is used to authenticate API requests.
- Create an API key with Editor permission, using the QC Services UI or the API Keys API.
- Learn how to use the QC Services user interface to create an API key.
- Learn how to use the API Keys API to create an API key.
- To authenticate a Qwilt API request, include the API key in the X-API-Key header.
For example:
```
curl --request GET
--url https://keys-manager.cqloud.com/api/1/keys
--header 'Content-Type: application/json'
--header 'X-Api-Key: <your API key>'
```
Key Rotation
To rotate a key, use the Qwilt APIs to add a key to the keyset and then republish the active site configuration.
Add an Origin Key
Use the keys-manager API to upload a new key to the keyset.{target=_blank}
Request example:
curl --request POST \
--url https://keys-manager.cqloud.com/api/1/keys
--header 'Content-Type: application/json'
--header 'X-Api-Key: <your API key>'
--data '{
"type": "generic",
"name": "Example key name",
"description": "Example key description.",
"key": "<origin key>",
"base64Encoded": false,
"keySetId": 182
}'
| Parameter | Description |
|---|---|
| type | The type value must be generic. |
| name | A user-defined key name. |
| description | A user-defined description. |
| key | The key string. When you submit the request, the key string is SHA-512 hashed. Subsequently, only the hashed key value is exposed by Qwilt APIs and UIs. |
| base64Encoded | Indicates if the key string is base64 encoded. Keys containing binary data must be base64 encoded. For standard strings, base64 encoding is optional. |
| keySetId | The id of the keyset to which you want to assign the key. |
Response example:
{
"id": 1,
"type": "generic",
"name": "Example key name",
"description": "Example key description.",
"sha512": "b2b799f6f383f378ecff3f5bcda6...",
},
"keySetId": 182,
"ownerOrgId": "iTV"
}
Add a URL Signing Key
Use the keys-manager API to upload a new key to the keyset.{target=_blank}
:::(Info) (Important note about the key type:)
Unlike the standard URL signing workflow, which uses the QSEC key type (as described in the Keys Manager API documentation), the iTV use case requires using the generic key type to upload the shared secret key to the relevant keyset.
:::
Request example:
curl --request POST
--url https://keys-manager.cqloud.com/api/1/keys
--header 'Content-Type: application/json'
--header 'X-Api-Key: <your API key>'
--data '{
"type": "generic",
"name": "Example key name",
"description": "Example key description.",
"key": "<Shared secret key for URL signing, e.g., 123456abcd>",
"base64Encoded": false,
"tags": {
"kid": "<alphanumeric value>"
},
"keySetId": 181
}'
| Parameter | Description |
|---|---|
| type | For the iTV use case, the type value must be generic. |
| name | A user-defined key name. |
| description | A user-defined description. |
| key | The shared secret key for URL signing. When you submit the request, the key string is SHA-512 hashed. Subsequently, only the hashed key value is exposed by Qwilt APIs and UIs. |
| base64Encoded | Indicates if the key string is base64 encoded. Keys containing binary data must be base64 encoded. For standard strings, base64 encoding is optional. |
| tags | The tags object is relevant to the URL signing use case. Use the tags object to specify the kid which will be included in the JWT token of the signed request to identify the key for validation. |
| keySetId | The id of the keyset to which you want to assign the key. |
Response example:
{
"id": 1,
"type": "generic",
"name": "Example key name",
"description": "Example key description.",
"sha512": "a4b337ec1a444509d0ae054...",
},
"keySetId": 181,
"ownerOrgId": "iTV"
}
Verify the Key Addition
To verify that a key has been added to a particular keyset, use the List Keys function{target=_blank}, specifying the relevant keyset with the keySetId query parameter.
Request example:
curl --request GET
--url https://keys-manager.cqloud.com/api/1/keys?keySetId=93
--header 'Content-Type: application/json'
--header 'X-Api-Key: <your API key>'
Note that the keySetId is passed as a path parameter.
Response example:
{
"keys": [
{
"id": 1,
"type": "generic",
"name": "key_1",
"description": "09_2024",
"sha512": "3f5c1d5b8810a9c9c90734d7f5aee8...",
"keySetId": 93,
"ownerOrgId": "iTV"
},
{
"id": 2,
"type": "generic",
"name": "key_2",
"description": "10_2024",
"sha512": " a53be35de1f6784a83c074bed3e5…",
"keySetId": 93,
"ownerOrgId": "iTV"
},
{
"id": 3,
"type": "generic",
"name": "key_3",
"description": "11_2024",
"sha512": "57e0a5c7d7e94f4f42f7d5f6a4b…",
"keySetId": 93,
"ownerOrgId": "iTV"
}
]
}
Republish the Site
After adding a key to the keyset, republish the active site configuration to activate the new key.
Use the sites API to republish the site{target=_blank}.
Important:
- For the new key to be activated, the keys attribute within the republishedResources object must be set to true.
- The siteId is passed as a path parameter.
Request example:
curl --request POST \
--url https://media-sites.cqloud.com/api/v2/sites/<siteId>/publishing-operations/actions/republish
--header 'Content-Type: application/json'
--header 'X-Api-Key: <your API key>'
--data '{
"republishedResources": {
"keys": true
},
"target": "ga"
}'
| Parameter | Description |
|---|---|
| siteID | The site ID is passed as a path parameter. - To publish to staging, use the ITVX live - STAGE siteId: 670695203151226bfe1ca391 - To publish to production, use the ITVX live - PROD siteId: 685bc85c1333d155828e7656 |
| keys | The value must be true. |
| target | This attributed specifies the network in which the key will be activated. Valid values are - ga : Publishes to production- staging: Publishes to staging Note that Republish works only on an active (published) site. |
Response example:
{
"publishId":"8a5d8836-0930-4f32-ac2e-f56e2dd08d00",
"ownerOrgId":"iTV",
"creationTimeMilli":1731876472,
"lastUpdateTimeMilli":1729198069,
"revisionId":"65bfe8040e8c871d66c00000",
"target":"ga",
"username":"me@iTV.com",
"publishState":"Validation",
"publishStatus":"InProgress",
"publishAcceptanceStatus":"Pending",
"publishHidden":null,
"publishMode":"PUBLISH",
"operationType":"Publish",
"statusLine":[],
"configLastModifiedTimeMilli":null,
"isActive":false,
"validatorsErrDetails":null
}
Note the publishStatus and publishId attribute values in the API response.
Initially, the publishStatus is InProgress. The new key becomes active when the publishing operation is complete, as indicated by the publishStatus Success.
To track the publishStatus in order to confirm that the site was republished, you'll need the publishId.
Confirm the Site was Republished
The new key becomes active once the publishStatus of the Republish operation is Success. Publishing operations typically take 5 to 30 minutes to complete.
To track the status of the publishing operation, use the Get Publishing Operation function.
Request example:
curl --request GET \
--url https://media-sites.cqloud.com/api/v2/sites/<siteId>/publishing-operations/<publishId> \
--header 'X-Api-Key: <your API key>'
Note that the siteId and publishId are passed as path parameters.
Response example:
{
"publishId":"8a5d8836-0930-4f32-ac2e-f56e2dd08d00",
"ownerOrgId":"iTV",
"creationTimeMilli":1731876472,
"lastUpdateTimeMilli":1729198069,
"revisionId":"65bfe8040e8c871d66c00000",
"target":"ga",
"username":"me@iTV.com",
"publishState":"APPLIED",
"publishStatus":"Success",
"publishAcceptanceStatus":"Accepted",
"publishHidden":null,
"publishMode":"PUBLISH",
"operationType":"Publish",
"statusLine":[],
"configLastModifiedTimeMilli":null,
"isActive":true,
"validatorsErrDetails":null,
}
When the publishStatus attribute value in the API response is Success, the site is republished.