RFC 9246
URI Signing for Content Delivery Network Interconnection (CDNI)
Internet Engineering Task Force (IETF) π β¨ RFC 9246: URI Signing for Content Delivery Network Interconnection (CDNI) π
okay so bestie, this is RFC 9246 and it's giving URI signing for CDN interconnection π¦ It's a Standards Track document from June 2022, written by R. van Brandenburg (Tiledmedia), K. Leung, and P. Sorber (Apple, Inc.) π«Ά It's an Internet Standards Track document, which means the IETF community has reviewed it and the IESG has approved it for publication π It doesn't obsolete or update any earlier RFCs, so it's a fresh start, no drama πΈ It has ISSN 2070-1721, which is just the official serial number for the RFC series π§
The vibe: URI signing lets a Content Service Provider (CSP) authorize every single request, and the CDN checks that authorization π It's built on signed JSON Web Tokens (JWTs), and it works in both interconnected CDN setups and single CDN setups β¨
Status of This Memo π
This is an Internet Standards Track document π
It's a product of the Internet Engineering Task Force (IETF) and represents the consensus of the IETF community π«Ά It got public review and was approved for publication by the Internet Engineering Steering Group (IESG) π For more on Internet Standards, check Section 2 of RFC 7841 πΈ Info about the current status, errata, and feedback is at https://www.rfc-editor.org/info/rfc9246 π¦
Copyright Notice π
Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved π
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication π Please review those carefully, because they spell out your rights and restrictions for this document β¨ Code Components pulled from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Revised BSD License π
Table of Contents π§
1. Introduction
1.1. Terminology
1.2. Background and Overview on URI Signing
1.3. CDNI URI Signing Overview
1.4. URI Signing in a Non-CDNI Context
2. JWT Format and Processing Requirements
2.1. JWT Claims
2.1.1. Issuer (iss) Claim
2.1.2. Subject (sub) Claim
2.1.3. Audience (aud) Claim
2.1.4. Expiry Time (exp) Claim
2.1.5. Not Before (nbf) Claim
2.1.6. Issued At (iat) Claim
2.1.7. JWT ID (jti) Claim
2.1.8. CDNI Claim Set Version (cdniv) Claim
2.1.9. CDNI Critical Claims Set (cdnicrit) Claim
2.1.10. Client IP Address (cdniip) Claim
2.1.11. CDNI URI Container (cdniuc) Claim
2.1.12. CDNI Expiration Time Setting (cdniets) Claim
2.1.13. CDNI Signed Token Transport (cdnistt) Claim
2.1.14. CDNI Signed Token Depth (cdnistd) Claim
2.1.15. URI Container Forms
2.1.15.1. URI Hash Container (hash:)
2.1.15.2. URI Regular Expression Container (regex:)
2.2. JWT Header
3. URI Signing Token Renewal
3.1. Overview
3.2. Signed Token Renewal Mechanism
3.2.1. Required Claims
3.3. Communicating a Signed JWT in Signed Token Renewal
3.3.1. Support for Cross-Domain Redirection
4. Relationship with CDNI Interfaces
4.1. CDNI Control Interface
4.2. CDNI Footprint & Capabilities Advertisement Interface
4.3. CDNI Request Routing Redirection Interface
4.4. CDNI Metadata Interface
4.5. CDNI Logging Interface
5. URI Signing Message Flow
5.1. HTTP Redirection
5.2. DNS Redirection
6. IANA Considerations
6.1. CDNI Payload Type
6.1.1. CDNI UriSigning Payload Type
6.2. CDNI Logging Record Type
6.2.1. CDNI Logging Record Version 2 for HTTP
6.3. CDNI Logging Field Names
6.4. CDNI URI Signing Verification Code
6.5. CDNI URI Signing Signed Token Transport
6.6. JSON Web Token Claims Registration
6.6.1. Registry Contents
6.7. Expert Review Guidance
7. Security Considerations
8. Privacy
9. References
9.1. Normative References
9.2. Informative References
Appendix A. Signed URI Package Example
A.1. Simple Example
A.2. Complex Example
A.3. Signed Token Renewal Example
Acknowledgements
Contributors
Authors' Addresses
1. Introduction πΈ
okay so this doc explains URI signing and how it gives access authorization when things get redirected between cooperating CDNs, and between a Content Service Provider (CSP) and a CDN π¦ The main goal is making sure only authorized User Agents (UAs) can reach the content, with the CSP able to approve every individual request π Quick reality check: URI signing is not a content protection scheme π If a CSP wants to actually protect the content, stuff like Digital Rights Management (DRM) is the better tool β¨ Bonus perk: URI signing also helps cut down the impact of denial-of-service attacks π‘οΈ
The big-picture problem space for CDN Interconnection (CDNI) is described in the CDNI Problem Statement [RFC6707] π This doc, plus the Content Distribution Network Interconnection (CDNI) Requirements [RFC7337] and the Framework for Content Distribution Network Interconnection (CDNI) [RFC7336], explains why interconnected CDNs need an access control mechanism that enforces a CSP's distribution policies π«Ά
The CDNI Framework [RFC7336] literally says:
The CSP may also trust the CDN operator to perform actions such as delegating traffic to additional downstream CDNs, and to enforce per-request authorization performed by the CSP using techniques such as URI Signing.
And the CDNI Requirements [RFC7337] include this one, which is marked HIGH priority π₯:
| MI-16 {HIGH} The CDNI Metadata interface shall allow signaling
| of authorization checks and validation that are to be
| performed by the Surrogate before delivery. For example,
| this could potentially include the need to validate
| information (e.g., Expiry time, Client IP address) required
| for access authorization.
This doc defines a way of signing URIs so Surrogates in interconnected CDNs can enforce per-request authorization that the CSP started π Splitting the job (CSP starts the authorization, CDN verifies it) means any arbitrary distribution policy can be enforced across CDNs, without the CDNs needing to know anything about each CSP's specific policies π The whole thing is built on signed JSON Web Tokens (JWTs) [RFC7519] π
1.1. Terminology π§
Here's the key words situation, bestie: MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this document are interpreted as described in BCP 14 [RFC2119] [RFC8174], but only when they show up in all capitals, exactly like that π
This doc uses the terminology from the CDNI Problem Statement [RFC6707] π It also uses the JWT terminology from [RFC7519] π«Ά
On top of that, these terms show up all over the place:
- FCI: Footprint & Capabilities Advertisement interface π
- Signed URI: A URI that comes with a signed JWT π¦
- Target CDN URI: A URI the CSP creates to point a UA at the upstream CDN (uCDN) π The CSP can sign the Target CDN URI, and the uCDN and possibly further downstream CDNs (dCDNs) can verify it π
- Redirection URI: A URI the uCDN creates to redirect a UA towards the dCDN β¨ The uCDN can sign the Redirection URI, and the dCDN verifies it π In a cascaded CDNI setup, there can be more than one Redirection URI πΈ
- Signed Token Renewal: a series of signed JWTs used for later access to a set of related resources in a CDN, like a set of HTTP Adaptive Streaming files π§ Every time a signed JWT is used to access a resource, a new signed JWT gets sent along with it, so it can be used to request the next resource in the set π«Ά When a new signed JWT is generated in Signed Token Renewal, parameters get carried over from one signed JWT to the next π
1.2. Background and Overview on URI Signing π¦
A CSP and CDN are assumed to have a trust relationship, which lets the CSP authorize access to a content item π In practice, this happens by putting a set of claims in a signed JWT inside the URI, before the UA gets redirected to the CDN π With those attributes, the CDN can check whether an incoming content request was authorized by the CSP (for example, based on a time window or by pattern matching the URI) β¨ To stop the UA from messing with the claims, the JWT MUST be signed π
Figure 1 shows the overall URI signing mechanism for a CSP with a single CDN π When the UA browses the CSP's website (1), it gets HTML pages with embedded content URIs π When it requests those URIs, the CSP redirects to a CDN and creates a Target CDN URI (2) (or the Target CDN URI can be embedded straight into the HTML) πΈ The Target CDN URI is the Signed URI, and it may include the UA's IP address and/or a time window π The Signed URI always contains a signed JWT generated by the CSP, using a shared secret or private key π§ Once the UA gets the response with the Signed URI, it sends a new HTTP request using that Signed URI to the CDN (3) π When the CDN gets the request, it authenticates the Signed URI by verifying the signed JWT π«Ά If it applies, the CDN checks whether the time window is still valid in the Signed URI and whether the pattern matches the request URI β¨ After those claims are verified, the CDN delivers the content (4) π
Heads up, bestie: while a symmetric shared key is supported, it is NOT RECOMMENDED β οΈ Check the Security Considerations (Section 7) for the limits of shared keys π
--------
/ \
| CSP |< * * * * * * * * * * *
\ / Trust *
-------- relationship *
^ | *
| | *
1. Browse | | 2. Signed *
for | | URI *
content | | *
| v v
+------+ 3. Signed URI --------
| User |----------------->/ \
| Agent| | CDN |
| |<-----------------\ /
+------+ 4. Content --------
Delivery
Figure 1: URI Signing in a CDN Environment
π That's part 1 of 9, so more is coming, babe π Stay tuned β¨
1.3. CDNI URI Signing Overview π
okay so in a CDNI setup, URI Signing starts out exactly like the single CDN case, steps 1 and 2 π«Ά but then things get spicy because multiple CDNs are delivering the content π The big difference is a redirection step between the uCDN and the dCDN. In step 3, the UA might send an HTTP request or a DNS request, depending on whether the request routing is HTTP-based or DNS-based π¦ The uCDN then points the UA toward the dCDN with either a Redirection URI (basically a Signed URI the uCDN made itself) or a DNS reply, depending on which one (4). Once the UA has that response, it sends the Redirection URI/Target CDN URI over to the dCDN (5). Then the dCDN verifies the received URI before it delivers the content (6) β¨
Note: The CDNI call flows are covered in URI Signing Message Flow (Section 5).
+-------------------------+
|Request Redirection Modes|
+-------------------------+
| a) HTTP |
| b) DNS |
+-------------------------+
--------
/ \< * * * * * * * * * * * * * *
| CSP |< * * * * * * * * * * * *
\ / Trust * *
-------- relationship * *
^ | * *
| | 2. Signed * *
1. Browse | | URI in * *
for | | HTML * *
content | | * *
| v 3.a)Signed URI v *
+------+ b)DNS request -------- * Trust
| User |----------------->/ \ * relationship
| Agent| | uCDN | * (optional)
| |<-----------------\ / *
+------+ 4.a)Redirection URI------- *
^ | b)DNS Reply ^ *
| | * *
| | Trust relationship * *
| | * *
6. Content | | 5.a)Redirection URI * *
delivery | | b)Signed URI(after v v
| | DNS exchange) --------
| +---------------------->/ \ [May be
| | dCDN | cascaded
+--------------------------\ / CDNs]
--------
Figure 2: URI Signing in a CDNI Environment
The trust relationships between the CSP, uCDN, and dCDN have a direct effect on URI Signing π€ In the setup from Figure 2, the CSP has a trust relationship with the uCDN. The delivery of the content may be handed off to a dCDN, which has a relationship with the uCDN but may have no relationship with the CSP π
In CDNI, there are two request routing methods: DNS-based and HTTP-based. With DNS-based request routing, the Signed URI (aka the Target CDN URI) the CSP provided reaches the CDN directly. If the dCDN doesn't have a trust relationship with the CSP, then an asymmetric public/private key method has to be used to compute the signed JWT, because the CSP and dCDN can't swap symmetric shared secret keys π Shared keys MUST NOT be redistributed. π«
With HTTP-based request routing, the Signed URI (aka the Target CDN URI) the CSP provided reaches the uCDN. Once the uCDN has verified it, the uCDN creates and signs a brand new Redirection URI that sends the UA to the dCDN π¦ Since that new URI can carry a new signed JWT, the relationship between the dCDN and CSP doesn't matter here. Because a relationship always exists between the uCDN and dCDN, either asymmetric public/private keys or symmetric shared secret keys can be used for URI Signing with HTTP-based request routing. Note that the signed Redirection URI MUST maintain HTTPS as the scheme if it was present in the original, and it MAY be upgraded from "http:" to "https:". π
There are two kinds of keys you can use for URI Signing: asymmetric keys and symmetric shared keys ποΈ Asymmetric keys are based on a public/private key pair. The private key is only known to the entity signing the URI (either the CSP or the uCDN), and the public key is used to verify the Signed URI. With symmetric keys, the same key is used by the signing entity to sign the URI and by the verifying entity to verify the Signed URI. No matter which type of key you use, the verifying entity has to get the key in a way that lets it trust the assertions made with that key (either the public key or the symmetric key). Asymmetric keys and symmetric keys have very different distribution requirements, which are outside the scope of this document π Distributing symmetric keys requires confidentiality, so third parties can't get access to them. If they did, they could generate valid Signed URIs for unauthorized requests π± Distributing asymmetric keys doesn't require confidentiality, since public keys can typically be shared openly (they can't be used to sign URIs) and the matching private keys are kept secret by the URI signer π
Note: While using a symmetric shared key is supported, it is NOT RECOMMENDED. See the Security Considerations (Section 7) about the limitations of shared keys β οΈ
1.4. URI Signing in a Non-CDNI Context π§
So this URI Signing method was mainly built for CDNI scenarios, meaning between a uCDN and a dCDN. But nothing in the method stops it from being used in a non-CDNI context πΈ It could be used in a single-CDN scenario like the one shown in Figure 1 in Section 1.2, for example, so that a CSP that uses different CDNs only has to implement one URI Signing mechanism. Main character energy for CSPs π
2. JWT Format and Processing Requirements π
The whole idea behind URI Signing is embedding a signed JSON Web Token (JWT) [RFC7519] in an HTTP or HTTPS URI [RFC7230] (see Section 2.7 of [RFC7230]). The signed JWT holds a bunch of claims that can be checked to make sure the UA really has legit access to the content π
This document specifies the following attribute for embedding a signed JWT in a Target CDN URI or Redirection URI:
- URI Signing Package (URISigningPackage): The URI attribute that wraps up all the URI Signing claims in a signed JWT encoded format. This attribute shows up in the Signed URI as a path-style parameter or a form-style parameter.
The parameter name of the URI Signing Package Attribute is defined in the CDNI Metadata (Section 4.4). If the CDNI Metadata interface isn't used, or doesn't include a parameter name for the URI Signing Package Attribute, the parameter name can be set by configuration (which is out of scope for this document) π§©
The URI Signing Package gets found by parsing any path-style parameters and form-style parameters, looking for a key name that matches the URI Signing Package Attribute π Both parameter styles MUST be supported so things stay flexible. The first matching parameter SHOULD be taken to provide the signed JWT, though providing more than one matching key is undefined behavior π Path-style parameters generated in the form indicated by Section 3.2.7 of [RFC6570] and Form-style parameters generated in the form indicated by Sections 3.2.8 and 3.2.9 of [RFC6570] MUST be supported. π«Ά
Here's an example where the URI Signing Package Attribute name is "token" and the signed JWT is "SIGNEDJWT":
http://example.com/media/path?come=data&token=SIGNEDJWT&other=data
2.1. JWT Claims π
This section lists the set of claims that can be used to enforce the CSP distribution policy. New claims can be added in the future to extend what the distribution policy can do β¨
To give distribution policies some flexibility, the exact subset of claims used in a given signed JWT is a runtime decision π¦ Claim requirements are defined in the CDNI Metadata (Section 4.4). If the CDNI Metadata interface isn't used, or doesn't include claim requirements, the claim requirements can be set by configuration (out of scope for this document).
The following claims (where the "JSON Web Token Claims" registry claim name is in parentheses) are used to enforce the distribution policies. All of the listed claims are mandatory to implement in a URI Signing implementation, but they aren't necessarily mandatory to use in a given signed JWT. (The "optional" and "mandatory" labels in square brackets tell you whether or not a given claim MUST be present in a URI Signing JWT. π)
Note: The time on the entities that generate and verify the Signed URI MUST be in sync. In the CDNI case, that means the CSP, uCDN, and dCDN servers need to be time synchronized β° It is RECOMMENDED to use NTP [RFC5905] for time synchronization. π°οΈ
Note: See the Security Considerations (Section 7) on the limitations of using an expiration time and Client IP address for distribution policy enforcement. Seriously, go read it π
2.1.1. Issuer (iss) Claim πͺͺ
Issuer (iss) [optional] - The semantics in Section 4.1.1 of [RFC7519] MUST be followed. If this claim is used, it MUST be used to identify the Issuer (signer) of the JWT. In particular, the recipient will already have received, through trusted configuration, a mapping of Issuer name to one or more keys used to sign JWTs, and it must verify that the JWT was signed by one of those keys π If this claim is used and the CDN verifying the signed JWT does not support Issuer verification, or if the Issuer in the signed JWT does not match the list of known acceptable Issuers, or if the Issuer claim does not match the key used to sign the JWT, the CDN MUST reject the request. π« If the received signed JWT contains an Issuer claim, then any JWT subsequently generated for CDNI redirection MUST also contain an Issuer claim, and the Issuer value MUST be updated to identify the redirecting CDN. π If the received signed JWT does not contain an Issuer claim, an Issuer claim MAY be added to a signed JWT generated for CDNI redirection. β¨
2.1.2. Subject (sub) Claim π«
Subject (sub) [optional] - The semantics in Section 4.1.2 of [RFC7519] MUST be followed. If this claim is used, it MUST be a JSON Web Encryption (JWE [RFC7516]) Object in compact serialization form, because it contains personally identifiable information π This claim holds information about the Subject (for example, a user or an agent) that MAY be used to verify the signed JWT. If the received signed JWT contains a Subject claim, then any JWT subsequently generated for CDNI redirection MUST also contain a Subject claim, and the Subject value MUST be the same as in the received signed JWT. π A signed JWT generated for CDNI redirection MUST NOT add a Subject claim if no Subject claim existed in the received signed JWT. π ββοΈ
2.1.3. Audience (aud) Claim π
Okay so aud is optional, but the rules for it are strict. Section 4.1.3 of [RFC7519] MUST be followed, no exceptions π . Its whole job is making sure the CDN checking the JWT is actually one of the people it was meant for. The claim MUST contain an identity from the chain of entities handling the request (like the CSP or any CDN in the chain) that the recipient is set up to use for processing this request. π¦ A CDN MAY modify the claim as long it can generate a valid signature. Bestie, that's the main character move: edit it if you want, as long as the signature still checks out β¨.
2.1.4. Expiry Time (exp) Claim β°
exp is optional too, and it's giving "the clock is ticking" π. Section 4.1.4 of [RFC7519] MUST be followed, but URI Signing implementations MUST NOT allow for any time-synchronization "leeway" π. If this claim is used and the CDN verifying the signed JWT doesn't support Expiry Time verification, OR the Expiry Time is equal to or earlier than the time of the content request, the CDN MUST reject the request. Rude π. If the received signed JWT has an Expiry Time claim, then any JWT generated later for CDNI redirection MUST also have one, and the value MUST be the same as the received one π. A signed JWT generated for CDNI redirection MUST NOT add an Expiry Time claim if the received signed JWT didn't have one. No sneaky additions, periodt π .
2.1.5. Not Before (nbf) Claim πΈ
nbf is optional and it's the mirror image of exp πͺ. Section 4.1.5 of [RFC7519] MUST be followed, and URI Signing implementations MUST NOT allow for any time-synchronization "leeway" π«Ά. If this claim is used and the CDN verifying the signed JWT doesn't support Not Before time verification, OR the Not Before time is later than the time of the content request, the CDN MUST reject the request. If the received signed JWT has a Not Before time claim, any JWT generated later for CDNI redirection MUST also have one, with the Not Before time value MUST be the same as the received one β¨. A signed JWT generated for CDNI redirection MUST NOT add a Not Before time claim if the received signed JWT didn't have one. Same energy as exp, just flipped π.
2.1.6. Issued At (iat) Claim π
iat is optional, and Section 4.1.6 of [RFC7519] MUST be followed π§. If the received signed JWT has an Issued At claim, then any JWT generated later for CDNI redirection MUST also have one, and its Issued At value MUST be updated to show the time the new JWT was generated. Fresh timestamp, fresh start π. If the received signed JWT doesn't have an Issued At claim, an Issued At claim MAY be added to a signed JWT generated for CDNI redirection. Totally your call here, bestie π.
2.1.7. JWT ID (jti) Claim πͺͺ
jti is optional, and Section 4.1.7 of [RFC7519] MUST be followed π. Here's the lowkey genius part: a JWT ID can help stop replay attacks, but only if the CDN keeps a list of every value it's already used and checks that the current one has never shown up before π΅οΈββοΈ. If the signed JWT has a JWT ID claim and the CDN verifying it either doesn't support JWT ID storage OR has already seen that value in a request for the same content, the CDN MUST reject the request. No second chances π. If the received signed JWT has a JWT ID claim, then any JWT generated later for CDNI redirection MUST also have one, and the value MUST be the same as the received one. If the received signed JWT doesn't have a JWT ID claim, a JWT ID claim MUST NOT be added to a signed JWT generated for CDNI redirection. And the size of the JWT ID depends on the application and what security constraints it needs π―.
2.1.8. CDNI Claim Set Version (cdniv) Claim π·οΈ
The cdniv claim is how a signed JWT says which version of this spec its claim set belongs to π. It's there so changes and upgrades across specs can happen smoothly β¨. The type is a JSON integer, and the value MUST be set to "1" for this version of the specification. If the claim is missing, the value is assumed to be "1". For future versions, this claim will be mandatory π. Implementations MUST reject signed JWTs with unsupported CDNI Claim Set versions. Version check or you're out, babe π
ββοΈ.
2.1.9. CDNI Critical Claims Set (cdnicrit) Claim π¨
cdnicrit is optional, but it's the one that says "hey, you REALLY need to understand this" π€. It means extensions to this spec are being used, and they MUST be understood and processed. The value is a comma-separated list of the claims in the Signed JWT that use those extensions. If the recipient doesn't understand and support any of the listed extension claims, the Signed JWT MUST be rejected π
. Producers MUST NOT include claim names defined by this specification, duplicate names, or names that don't show up as claim names in the Signed JWT in the cdnicrit list. Producers MUST NOT use the empty list "" as the cdnicrit value. Recipients MAY consider the Signed JWT invalid if the cdnicrit list has any claim names defined by this specification, or if any other constraints on its use get violated π. This claim MUST be understood and processed by ALL implementations. Non-negotiable, bestie π«‘.
2.1.10. Client IP Address (cdniip) Claim π
cdniip is optional, and it holds an IP address or IP prefix that the Signed URI is valid for π. It's written in CIDR notation, with dotted decimal for IPv4 addresses [RFC0791] or canonical text representation for IPv6 addresses [RFC5952]. The request MUST be rejected if it comes from a client outside the specified IP range π«. Here's the privacy tea β: the Client IP counts as personally identifiable information, so this field MUST be a JSON Web Encryption (JWE [RFC7516]) Object in compact serialization form π. If the CDN verifying the signed JWT doesn't support Client IP verification, OR the Client IP in the signed JWT doesn't match the source IP address of the content request, the CDN MUST reject the request. The type of this claim is a JSON string holding the JWE. If the received signed JWT has a Client IP claim, then any JWT generated later for CDNI redirection MUST also have one, and the Client IP value MUST be the same as the received one. A signed JWT generated for CDNI redirection MUST NOT add a Client IP claim if the received signed JWT didn't have one.
It should be noted that this claim can cause issues. For example, with dual-stack IPv4 and IPv6 networks, MPTCP, QUIC, and mobile clients switching from Wi-Fi to Cellular, the client's source address can change, even between address families πΆ. This claim mainly exists for legacy feature parity reasons, so use it judiciously π§. A reasonable use case would be a signed JWT for an internal preview of an asset, where the end consumer understands they must come from the same IP for the whole session π¬. Using this claim at large is NOT RECOMMENDED π ββοΈ.
2.1.11. CDNI URI Container (cdniuc) Claim π¦
cdniuc is mandatory π«‘. The URI Container holds the URI representation from before a URI Signing Package is added. That representation can take one of several forms, detailed in Section 2.1.15. If the URI Container in the signed JWT doesn't match the URI of the content request, the CDN verifying the signed JWT MUST reject the request. When comparing URIs, the percent encoded form defined in Section 2.1 of [RFC3986] MUST be used π. When redirecting a URI, the CDN generating the new signed JWT MAY change the URI Container so it matches the URI being used in the redirection π.
2.1.12. CDNI Expiration Time Setting (cdniets) Claim β³
cdniets is optional, and it's how you set the Expiry Time (exp) claim when generating a later signed JWT during Signed Token Renewal π. Its type is a JSON numeric value, and it's the number of seconds added to the time the JWT is verified, which gives the exp value of the next signed JWT. The CDNI Expiration Time Setting (cdniets) SHOULD NOT be used when you're not using Signed Token Renewal, and it MUST be present when you ARE using Signed Token Renewal π.
2.1.13. CDNI Signed Token Transport (cdnistt) Claim π
cdnistt is optional, and it signals the method used to transport a new signed JWT from the CDN to the UA, and back again, for Signed Token Renewal π¬. Its type is a JSON integer, and its values are defined in Section 6.5. If you use this claim, you MUST also specify a CDNI Expiration Time Setting (cdniets) as noted above. Always pair your transport with your expiration setting, bestie β°.
2.1.14. CDNI Signed Token Depth (cdnistd) Claim π³
cdnistd is optional, and it links a later signed JWT, created as the result of a CDNI Signed Token Transport claim, to a specific URI subset π§. Its type is a JSON integer. Signed JWTs MUST NOT use a negative value for the CDNI Signed Token Depth claim. Negative depth? Absolutely not π ββοΈ.
If the transport used for Signed Token Transport lets the CDN associate the path component of a URI with tokens (like an HTTP Cookie Path, described in Section 4.1.2.4 of [RFC6265]), then the CDNI Signed Token Depth value is the number of path segments that should count for that association πͺ. A CDNI Signed Token Depth of zero means the client SHOULD be directed to return the token with requests for any path. If the CDNI Signed Token Depth is greater than zero, the CDN SHOULD send the client a token to return for future requests, where the first CDNI Signed Token Depth segments of the path match the first CDNI Signed Token Depth segments of the Signed URI path. This matching MUST use the URI with the token removed, as specified in Section 2.1.15 π§©.
If the URI path to match has fewer segments than the CDNI Signed Token Depth claim, a signed JWT MUST NOT be generated for Signed Token Renewal purposes π. If the CDNI Signed Token Depth claim is omitted, it means the same thing as a value of zero πΈ. If the received signed JWT has a CDNI Signed Token Depth claim, then any JWT generated later for CDNI redirection or Signed Token Transport MUST also have a CDNI Signed Token Depth claim, and the value MUST be the same as the received one π.
2.1.15. URI Container Forms β¨
okay so the URI Container (cdniuc) claim comes in one of two forms: hash: or regex: π. More forms may be added later to level up what it can do π¦
before you compare a URI with what's in this container, there are steps you MUST do (no skipping, bestie π ββοΈ):
- Before verification, strip the signed JWT out of the URI π . This removal is ONLY so you can figure out whether the URI matches, and every other purpose still uses the original URI. If the signed JWT ends with anything other than a sub-delimiter (as defined in Section 2.2 of [RFC3986]), you remove everything from the reserved character (as defined in Section 2.2 of [RFC3986]) that comes right before the URI Signing Package Attribute, all the way to the last character of the signed JWT, inclusive π«Ά. Otherwise, you remove everything from the first character of the URI Signing Package Attribute up to the sub-delimiter that ends the signed JWT, inclusive π§.
- Normalize the URI according to Section 2.7.3 of [RFC7230] and Sections 6.2.2 and 6.2.3 of [RFC3986]. This applies to both generation and verification of the signed JWT πΈ.
2.1.15.1. URI Hash Container (hash:) π
Prefixed with hash:, this string is a URL Segment form (Section 5 of [RFC6920]) of the URI. β¨
2.1.15.2. URI Regular Expression Container (regex:) π
Prefixed with regex:, this string is any regular expression compatible with POSIX Extended Regular Expression (Section 9 of [POSIX.1]) that gets used to match against the requested URI. These regular expressions MUST be evaluated in the POSIX locale (Section 7.2 of [POSIX.1]) π€.
Note: Because\has special meaning in JSON [RFC8259] as the escape character inside JSON strings, the regular expression character\MUST be escaped as\\π.
An example of a regex: is the following π:
[^:]*\\://[^/]*/dir/content/quality_[^/]*/segment.{3}\\.mp4(\\?.*)?
Note: Executing arbitrary regular expressions is computationally complex, so it is RECOMMENDED to only execute them after verifying the JWT to ensure its authenticity ππ.
2.2. JWT Header π
The header of the JWT MAY be passed via the CDNI Metadata interface instead of being included in the URISigningPackage π«§. The header value MUST be transmitted in the serialized encoded form and prepended to the JWT payload and signature passed in the URISigningPackage prior to verification. This reduces the size of the signed JWT token π.
3. URI Signing Token Renewal π¦
3.1. Overview πΈ
okay so for content that gets delivered over HTTP in a segmented way, like MPEG-DASH [MPEG-DASH] or HTTP Live Streaming (HLS) [RFC8216], special provisions need to be made so URI Signing can actually be applied π. Segmented protocols break large objects (like videos) into a sequence of small independent segments. Those segments are then referenced by a separate manifest file, which either includes a list of URLs to the segments or specifies an algorithm that a User Agent can use to construct the URLs to the segments π§. So requests for segments start from the manifest file and, unless the URLs in the manifest point to the CSP, they skip redirection and URI Signing entirely. That opens up a vulnerability where malicious User Agents can share the manifest file and deep link straight to the segments π.
One method for dealing with this vulnerability would be to put Signed URIs that point to the individual segments right in the manifest itself. Honestly, there are a bunch of issues with that approach π. First, the CDN delivering the manifest would have to rewrite the manifest file for each User Agent, which would mean the CDN has to know the exact segmentation protocol being used. Second, the expiration time of the Signed URIs could also need to be valid for an extended duration if the content described by the manifest is meant to be consumed in real time. For example, if the manifest file contained a segmented video stream more than 30 minutes long, the Signed URIs would need to be valid for at least 30 minutes, which makes them less effective and makes URI Signing in general less effective too π€. For a more detailed analysis of how segmented protocols such as HTTP Adaptive Streaming protocols affect CDNI, check out Models for HTTP-Adaptive-Streaming-Aware Content Distribution Network Interconnection (CDNI) [RFC6983] π.
The method in this section lets CDNs use URI Signing for segmented content without having to put the Signed URIs in the manifest files themselves β¨.
3.2. Signed Token Renewal Mechanism π
To allow for effective access control of segmented content, the URI Signing mechanism in this section is based on a method that links subsequent segment requests together π. As part of the JWT verification procedure, the CDN can generate a new signed JWT that the UA can use for a subsequent request. Basically, whenever a UA successfully retrieves a segment, it receives a signed JWT in the HTTP 2xx Successful message, and it can use that JWT whenever it requests the next segment π. As long as each successive signed JWT is correctly verified before a new one is generated, the model doesn't break and the User Agent can keep retrieving more segments π. With segmented protocols, it's usually not possible to know a priori which segment will be requested next (for example, when someone seeks within the content or switches to a different representation), so Signed Token Renewal uses the URI Regular Expression Container scoping mechanisms in the URI Container (cdniuc) claim to let a signed JWT be valid for more than one URL π.
For this renewal to work, a UA needs to pull the signed JWT out of the HTTP 2xx Successful message of an earlier request and use it to retrieve the next segment π§ββοΈ. The exact mechanism a client uses to do this is outside the scope of this document. But to also support legacy UAs that don't have any specific provisions for handling signed JWTs, Section 3.3 defines a mechanism using HTTP Cookies [RFC6265] that lets those UAs support renewing signed JWTs without needing any extra UA support πͺ.
3.2.1. Required Claims π«Ά
The cdnistt claim (Section 2.1.13) and cdniets claim (Section 2.1.12) MUST both be present for Signed Token Renewal. cdnistt MAY be set to a value of 0 to mean no Signed Token Renewal, but there still MUST be a corresponding cdniets that verifies as a JSON number. However, if you don't want Signed Token Renewal, it is RECOMMENDED to simply omit both π.
3.3. Communicating a Signed JWT in Signed Token Renewal π
This section assumes the value of the CDNI Signed Token Transport (cdnistt) claim has been set to 1 β¨.
When you're using the Signed Token Renewal mechanism, the signed JWT gets transported to the UA via a URISigningPackage cookie πͺ. That cookie gets added to the HTTP 2xx Successful message along with the content being returned to the UA, or to the HTTP 3xx Redirection message in case the UA is redirected to a different server π¦.
3.3.1. Support for Cross-Domain Redirection πΈ
For security purposes, cross-domain cookies aren't supported in some application environments π. Because of that, the Cookie-based method for transporting the Signed Token described in Section 3.3 might break if it's combined with an HTTP 3xx Redirection response where the target URL is in a different domain π¬. In those scenarios, Signed Token Renewal of a signed JWT SHOULD be communicated via the query string instead, kind of like how regular signed JWTs (outside of Signed Token Renewal) get communicated π§. Note that the value of the CDNI Signed Token Transport (cdnistt) claim MUST be set to 2 π.
Also, this whole process only works when both the manifest file and the segments that make up the segmented content are delivered from the same domain π. Put another way, any redirection between different domains has to happen while the manifest file is being retrieved π«§.
4. Relationship with CDNI Interfaces π
Some of the CDNI Interfaces need enhancements to support URI Signing π οΈ. A dCDN that supports URI Signing needs to be able to advertise this capability to the uCDN π£. The uCDN needs to select a dCDN based on that capability when the CSP requires access control to enforce its distribution policy via URI Signing π―. The uCDN also needs to be able to distribute, via the CDNI Metadata interface, the information the dCDN needs to verify a Signed URI ποΈ. And events that pertain to URI Signing (like request denial, or delivery after an access authorization decision has been made) need to be included in the logs communicated through the CDNI Logging interface π.
4.1. CDNI Control Interface π·
URI Signing has no impact on this interface πββοΈ.
4.2. CDNI Footprint & Capabilities Advertisement Interface π¦
The CDNI Request Routing: Footprint and Capabilities Semantics document [RFC8008] defines support for advertising CDNI Metadata capabilities via CDNI Payload Type. The CDNI Payload Type registered in Section 6.1 can be used for capability advertisement π’.
4.3. CDNI Request Routing Redirection Interface π§
The CDNI Request Routing Redirection Interface [RFC7975] describes the recursive request redirection method. For URI Signing, the uCDN signs the URI provided by the dCDN. So URI Signing has no impact on this interface π.
4.4. CDNI Metadata Interface π
okay so the CDNI Metadata Interface [RFC8006] is the thing that handles CDNI Metadata distribution, which is what makes content acquisition and delivery possible πβ¨ and for URI Signing there's a brand-new CDNI Metadata object, so new it's giving premiere π
The UriSigning Metadata object holds the info a dCDN needs to enable URI Signing and verify signed URIs π Here are the UriSigning properties:
enforceπ- Description: this is the URI Signing enforcement flag. It tells you whether access to content is subject to URI Signing. When it applies, the dCDN has to make sure the URI is signed and verified before it delivers content. Otherwise the dCDN doesn't do verification at all, whether or not the URI is signed.
- Type: Boolean
- Mandatory-to-Specify: No. The default is true.
issuersπ- Description: a list of valid Issuers that the Issuer claim in the signed JWT can get cross-referenced against.
- Type: Array of Strings
- Mandatory-to-Specify: No. The default is an empty list. An empty list means that any Issuer in the trusted key store of Issuers is acceptable.
package-attributeπΈ- Description: the attribute name to use for the URI Signing Package.
- Type: String
- Mandatory-to-Specify: No. The default is "URISigningPackage".
jwt-headerπ§- Description: the header part of the JWT that's used for verifying a signed JWT when the JWT token in the URI Signing Package doesn't contain a header part.
- Type: String
- Mandatory-to-Specify: No. By default, the header is assumed to be included in the JWT token.
Here's an example of a URI Signing metadata payload with all default values:
{
"generic-metadata-type": "MI.UriSigning"
"generic-metadata-value": {}
}
And here's one with explicit values π
{
"generic-metadata-type": "MI.UriSigning"
"generic-metadata-value":
{
"enforce": true,
"issuers": ["csp", "ucdn1", "ucdn2"],
"package-attribute": "usp",
"jwt-header":
{
"alg": "ES256",
"kid": "P5UpOv0eMq1wcxLf7WxIg09JdSYGYFDOWkldueaImf0"
}
}
}
4.5. CDNI Logging Interface π
for URI Signing, the dCDN reports that enforcement of the access control was applied to the request for content delivery π and when a request gets denied because of URI Signing enforcement, the reason gets logged. literally so helpful for the debugging girlies π«Ά
The following CDNI Logging field for URI Signing SHOULD be supported in the HTTP Request Logging Record, as specified in "Content Distribution Network Interconnection (CDNI) Logging Interface" [RFC7937], using the new "cdni_http_request_v2" record-type registered in Section 6.2.1.
s-uri-signing(mandatory): β¨- Format:
3DIGIT - Field value: this characterizes the URI Signing verification the Surrogate performed on the request. The allowed values are registered in Section 6.4.
- Occurrence: there MUST be zero or exactly one instance of this field.
- Format:
s-uri-signing-deny-reason(optional): π- Format:
QSTRING - Field value: a string for giving further information in case the signed JWT was rejected, e.g., for debugging purposes.
- Occurrence: there MUST be zero or exactly one instance of this field.
- Format:
5. URI Signing Message Flow π¦
URI Signing works with both HTTP-based and DNS-based request routing π JSON Web Token (JWT) [RFC7519] is a compact, URL-safe way of representing claims that get passed between two parties. The claims in a Signed JWT are encoded as a JSON object, which is used as the payload of a JSON Web Signature (JWS) structure. That lets the claims be digitally signed, or integrity protected with a Message Authentication Code (MAC). it's giving secure but make it cute π
5.1. HTTP Redirection
For HTTP-based request routing, a set of information that's unique to a given end-user content request goes into a Signed JWT. The key information used is specific to a pair of adjacent CDNI hops, like between the CSP and the uCDN, or between the uCDN and a dCDN π This lets a CDNI hop confirm that a request it got from the previous CDNI hop is authentic. main character verification energy β¨
The URI Signing method, assuming HTTP redirection, iterative request routing, and a CDN path with two CDNs, includes the following steps πΊοΈ
End-User dCDN uCDN CSP
| | | |
| 1.CDNI FCI used to | |
| advertise URI Signing capability | |
| |------------------->| |
| | | |
| 2.Provides information to verify Signed JWT |
| | |<-------------------|
| | | |
| 3.CDNI Metadata interface used to| |
| provide URI Signing attributes| |
| |<-------------------| |
: : : :
: (Later in time) : : :
|4.Authorization request | |
|------------------------------------------------------------->|
| | | [Apply distribution
| | | policy] |
| | | |
| | (ALT: Authorization decision)
|5.Request is denied | | <Negative> |
|<-------------------------------------------------------------|
| | | |
|6.CSP provides Signed URI | <Positive> |
|<-------------------------------------------------------------|
| | | |
|7.Content request | | |
|---------------------------------------->| [Verify URI |
| | | signature] |
| | | |
| | (ALT: Verification result) |
|8.Request is denied | <Negative>| |
|<----------------------------------------| |
| | | |
|9.Re-sign URI and redirect to <Positive>| |
| dCDN (newly Signed URI) | |
|<----------------------------------------| |
| | | |
|10.Content request | | |
|------------------->| [Verify URI | |
| | signature] | |
| | | |
| (ALT: Verification result) | |
|11.Request is denied| <Negative> | |
|<-------------------| | |
| | | |
|12.Content delivery | <Positive> | |
|<-------------------| | |
: : : :
: (Later in time) : : :
|13.CDNI Logging interface to include URI Signing information |
| |------------------->| |
Figure 3: HTTP-Based Request Routing with URI Signing π¬
- Using the CDNI Footprint & Capabilities Advertisement interface, the dCDN advertises its capabilities, including URI Signing support, to the uCDN. π£
- The CSP gives the uCDN the info needed to verify Signed URIs from that CSP. For example, this info includes one or more keys used for validation. π
- Using the CDNI Metadata interface, the uCDN tells a dCDN the info needed to verify Signed URIs from the uCDN for the given CSP. For example, this info may include the URI query string parameter name for the URI Signing Package Attribute, plus keys used for validation. π
- When a UA requests a piece of protected content from the CSP, the CSP makes a specific authorization decision for this unique request, based on its local distribution policy. π§
- If the authorization decision is negative, the CSP rejects the request and sends an error code (e.g., 403 Forbidden) in the HTTP response. π«
- If the authorization decision is positive, the CSP computes a Signed JWT based on unique parameters of that request, and hands it to the end user as the URI to use to request the content. β
- When the matching content request comes in, the uCDN verifies the Signed JWT in the URI using the info the CSP provided. π
- If the verification result is negative, the uCDN rejects the request and sends an error code 403 Forbidden in the HTTP response. π
- If the verification result is positive, the uCDN computes a Signed JWT based on unique parameters of that request, and gives it to the end user as the URI to use to further request the content from the dCDN. ποΈ
- When the corresponding content request arrives, the dCDN verifies the Signed JWT in the Signed URI using the info the uCDN provided in the CDNI Metadata. π΅οΈ
- If the verification result is negative, the dCDN rejects the request and sends an error code 403 Forbidden in the HTTP response. π
- If the verification result is positive, the dCDN serves the request and delivers the content. π
- At a later time, the dCDN reports logging events that include URI Signing information. ποΈ
With HTTP-based request routing, URI Signing fits really well with the general chain of trust model of CDNI. That's true with both symmetric and asymmetric keys, because the key info only needs to be specific to a pair of adjacent CDNI hops π«Ά
Note: While using a symmetric shared key is supported, it is NOT RECOMMENDED. See the Security Considerations (Section 7) about the limitations of shared keys. πβ οΈ
5.2. DNS Redirection πΈ
okay so for DNS-based request routing, the CSP and uCDN have to agree on a trust model that actually fits how sensitive the CSP's content is π this part matters!! Asymmetric public/private keys are lowkey the move, because the public key can go out to unlimited dCDNs without drama. If a shared secret key is needed instead, the distribution SHOULD be performed by the CSP directly, so the CSP is the one handing it off π«Ά
Note: Using a symmetric shared key is supported, but it is NOT RECOMMENDED. Check out the Security Considerations (Section 7) for the limitations of shared keys π
okay, the URI Signing method (assuming iterative DNS request routing and a CDN path with two CDNs) goes like this β¨
End-User dCDN uCDN CSP
| | | |
| 1.CDNI FCI used to | |
| advertise URI Signing capability | |
| |------------------->| |
| | | |
| 2.Provides information to verify Signed JWT |
| | |<-------------------|
| 3.CDNI Metadata interface used to| |
| provide URI Signing attributes| |
| |<-------------------| |
: : : :
: (Later in time) : : :
|4.Authorization request | |
|------------------------------------------------------------->|
| | | [Apply distribution
| | | policy] |
| | | |
| | (ALT: Authorization decision)
|5.Request is denied | | <Negative> |
|<-------------------------------------------------------------|
| | | |
|6.Provides Signed URI | <Positive> |
|<-------------------------------------------------------------|
| | | |
|7.DNS request | | |
|---------------------------------------->| |
| | | |
|8.Redirect DNS to dCDN | |
|<----------------------------------------| |
| | | |
|9.DNS request | | |
|------------------->| | |
| | | |
|10.IP address of Surrogate | |
|<-------------------| | |
| | | |
|11.Content request | | |
|------------------->| [Verify URI | |
| | signature] | |
| | | |
| (ALT: Verification result) | |
|12.Request is denied| <Negative> | |
|<-------------------| | |
| | | |
|13.Content delivery | <Positive> | |
|<-------------------| | |
: : : :
: (Later in time) : : :
|14.CDNI Logging interface to report URI Signing information |
| |------------------->| |
Figure 4: DNS-based Request Routing with URI Signing
- First up, the dCDN uses the CDNI Footprint & Capabilities Advertisement interface to tell the uCDN what it can do, including URI Signing support π£
- Next, the CSP hands the uCDN the info needed to verify Signed JWTs from that CSP. Think: one or more keys used for validation π
- Then the uCDN uses the CDNI Metadata interface to share that verification info with a dCDN (like the URI query string parameter name for the URI Signing Package Attribute). If it's a symmetric shared key, the uCDN MUST NOT share the key with a dCDN. no exceptions, bestie π ββοΈ
- When a UA asks for protected content from the CSP, the CSP makes a specific authorization decision for that one unique request, based on its local distribution policy π§
- If the decision is negative, the CSP rejects the request and sends back an error code (for example, 403 Forbidden) in the HTTP response π«
- If the decision is positive, the CSP computes a Signed JWT based on the unique parameters of that request and puts it in the URI given to the end user to request the content β¨
- The end user sends a DNS request to the uCDN π²
- When the uCDN gets that DNS request, it redirects the request to the dCDN βͺοΈ
- The end user sends a DNS request to the dCDN π²
- When the dCDN gets that DNS request, it responds with the IP address of one of its Surrogates π§
- When the matching content request comes in, the dCDN verifies the Signed JWT in the URI using the info the uCDN shared in the CDNI Metadata π
- If verification comes back negative, the dCDN rejects the request and sends an error code 403 Forbidden in the HTTP response π
- If verification comes back positive, the dCDN serves the request and delivers the content π
- Later on, the dCDN reports logging events that include URI Signing information π
okay, here's the tea π΅ With DNS-based request routing, URI Signing fits really well with the general chain of trust model of CDNI when asymmetric keys are used. Why? Because the only key info that has to travel across multiple, possibly untrusted, CDNI hops is the public key, and that's generally not confidential π¦
BUT, with DNS-based request routing, URI Signing does NOT fit well with the general chain of trust model of CDNI when symmetric keys are used. The symmetric key info would need to be spread across multiple CDNI hops to CDNs the CSP may have no trust relationship with. That's a real security concern for using URI Signing with symmetric keys in DNS-based inter-CDN request routing. Because of these flaws, this architecture MUST NOT be implemented. Not it. π ββοΈπ
Note: Using a symmetric shared key is supported, but it is NOT RECOMMENDED. Check out the Security Considerations (Section 7) for the limitations of shared keys π
6. IANA Considerations π
6.1. CDNI Payload Type π
IANA registered the following CDNI Payload Type in the IANA "CDNI Payload Types" registry π
+===============+===============+
| Payload Type | Specification |
+===============+===============+
| MI.UriSigning | RFC 9246 |
+---------------+---------------+
Table 1
6.1.1. CDNI UriSigning Payload Type π§
- Purpose: This payload type exists to tell UriSigning Metadata interface (MI) objects apart (and any associated capability advertisement) π·οΈ
- Interface: MI/FCI
- Encoding: see Section 4.4
6.2. CDNI Logging Record Type πΌ
IANA registered the following CDNI Logging record-type in the IANA "CDNI Logging record-types" registry π
+======================+===========+===========================+
| record-types | Reference | Description |
+======================+===========+===========================+
| cdni_http_request_v2 | RFC 9246 | Extension to CDNI Logging |
| | | Record version 1 for |
| | | content delivery using |
| | | HTTP, to include URI |
| | | Signing Logging fields |
+----------------------+-----------+---------------------------+
Table 2
6.2.1. CDNI Logging Record Version 2 for HTTP β¨
The cdni_http_request_v2 record-type supports every field that cdni_http_request_v1 supports [RFC7937], PLUS the two new fields s-uri-signing and s-uri-signing-deny-reason, which this document registers in Section 6.3 π«Ά The name, format, field value, and occurrence info for those two new fields lives in Section 4.5 of this document π
6.3. CDNI Logging Field Names π¦
IANA registered the following CDNI Logging fields in the IANA "CDNI Logging Field Names" registry πΈ
+===========================+===========+
| Field Name | Reference |
+===========================+===========+
| s-uri-signing | RFC 9246 |
+---------------------------+-----------+
| s-uri-signing-deny-reason | RFC 9246 |
+---------------------------+-----------+
Table 3
6.4. CDNI URI Signing Verification Code π
okay so IANA made a brand new "CDNI URI Signing Verification Code" subregistry inside the "Content Delivery Networks Interconnection (CDNI) Parameters" registry π This namespace is the list of valid values for the s-uri-signing CDNI Logging field. The CDNI URI Signing Verification Code is a 3DIGIT value, just like we saw in Section 4.5 π New additions go through the "Specification Required" policy from [RFC8126], and updates to this subregistry are expected to be pretty rare β¨
+=======+===========+=====================================+
| Value | Reference | Description |
+=======+===========+=====================================+
| 000 | RFC 9246 | No signed JWT verification |
| | | performed |
+-------+-----------+-------------------------------------+
| 200 | RFC 9246 | Signed JWT verification performed |
| | | and verified |
+-------+-----------+-------------------------------------+
| 400 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of incorrect |
| | | signature |
+-------+-----------+-------------------------------------+
| 401 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Issuer |
| | | enforcement |
+-------+-----------+-------------------------------------+
| 402 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Subject |
| | | enforcement |
+-------+-----------+-------------------------------------+
| 403 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Audience |
| | | enforcement |
+-------+-----------+-------------------------------------+
| 404 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Expiration |
| | | Time enforcement |
+-------+-----------+-------------------------------------+
| 405 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Not Before |
| | | enforcement |
+-------+-----------+-------------------------------------+
| 406 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because only one of |
| | | CDNI Signed Token Transport or CDNI |
| | | Expiration Time Setting present |
+-------+-----------+-------------------------------------+
| 407 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of JWT ID |
| | | enforcement |
+-------+-----------+-------------------------------------+
| 408 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Version |
| | | enforcement |
+-------+-----------+-------------------------------------+
| 409 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Critical |
| | | Extension enforcement |
+-------+-----------+-------------------------------------+
| 410 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of Client IP |
| | | enforcement |
+-------+-----------+-------------------------------------+
| 411 | RFC 9246 | Signed JWT verification performed |
| | | and rejected because of URI |
| | | Container enforcement |
+-------+-----------+-------------------------------------+
| 500 | RFC 9246 | Unable to perform signed JWT |
| | | verification because of malformed |
| | | URI |
+-------+-----------+-------------------------------------+
Table 4 πΈ
6.5. CDNI URI Signing Signed Token Transport π¦
IANA also made a new "CDNI URI Signing Signed Token Transport" subregistry in that same "Content Delivery Networks Interconnection (CDNI) Parameters" registry π§ This one is the list of values that may show up in the Signed Token Transport (cdnistt) JWT claim. New additions follow the "Specification Required" policy from [RFC8126], and updates are expected to be infrequent, same energy as before π
Here's the initial set of Enforcement Information Elements, so you know what's in the starter pack:
+=======+=============================================+==========+
| Value | Description | RFC |
+=======+=============================================+==========+
| 0 | Designates token transport is not enabled | RFC 9246 |
+-------+---------------------------------------------+----------+
| 1 | Designates token transport via cookie | RFC 9246 |
+-------+---------------------------------------------+----------+
| 2 | Designates token transport via query string | RFC 9246 |
+-------+---------------------------------------------+----------+
Table 5 β¨
6.6. JSON Web Token Claims Registration π
okay this is the part where the spec registers its claims in the IANA "JSON Web Token Claims" registry [IANA.JWT.Claims], which was set up by [RFC7519]. Main character moment π
6.6.1. Registry Contents π
Here are all the claims going in, with their details exactly as written:
Claim Name: cdniv
Claim Description: CDNI Claim Set Version
Change Controller: IESG
Specification Document(s): Section 2.1.8 of RFC 9246
Claim Name: cdnicrit
Claim Description: CDNI Critical Claims Set
Change Controller: IESG
Specification Document(s): Section 2.1.9 of RFC 9246
Claim Name: cdniip
Claim Description: CDNI IP Address
Change Controller: IESG
Specification Document(s): Section 2.1.10 of RFC 9246
Claim Name: cdniuc
Claim Description: CDNI URI Container
Change Controller: IESG
Specification Document(s): Section 2.1.11 of RFC 9246
Claim Name: cdniets
Claim Description: CDNI Expiration Time Setting for Signed Token
Renewal
Change Controller: IESG
Specification Document(s): Section 2.1.12 of RFC 9246
Claim Name: cdnistt
Claim Description: CDNI Signed Token Transport Method for Signed
Token Renewal
Change Controller: IESG
Specification Document(s): Section 2.1.13 of RFC 9246
Claim Name: cdnistd
Claim Description: CDNI Signed Token Depth
Change Controller: IESG
Specification Document(s): Section 2.1.14 of RFC 9246
6.7. Expert Review Guidance π«Ά
okay the vibe check for Expert Reviewers π Generally speaking, we should figure out whether the registration has a rational justification and doesn't duplicate an earlier registration. Early assignment is fine as long as there's a reasonable expectation that the specification will get formalized π₯ Reviewers should feel empowered to make calls, but mostly they should let new claims through unless they cause conflicts with implementations or stuff that could lead to confusion π And when it makes sense, they should also follow the guidelines in Section 5 of [RFC8126] π
7. Security Considerations πβ¨
Okay bestie, this section is the serious one π₯Ί URI Signing is all about making sure that only authorized UAs (user agents) can get at the content, with the CSP able to approve every single request. But it is NOT a content protection scheme π If a CSP wants to actually protect the content itself, stuff like DRM is way more appropriate.
CDNI URI Signing Signed Tokens are built on JSON Web Tokens, so the guidelines in [RFC8725] apply to all JWT interactions π«Ά
Here's the vibe: the more claims you pack into the signed JWT, the harder it gets for illegitimate access to slip through π The current version of this document has claims for enforcing Issuer, Client IP Address, Not Before time, and Expiration Time. But the list can be extended with more complex attributes that protect against some of the vulnerabilities we're about to talk about π
That said, there are a bunch of things that limit how secure URI Signing can be, and anyone implementing it needs to be aware of them π Let's go through them.
Replay attacks
A (valid) Signed URI can be used to perform replay attacks π You can make this less of a problem by picking a relatively short window between the Not Before time and Expiration Time attributes. The catch is that any HTTP-based request needs a window of at least a couple of seconds, so sudden network issues don't stop legitimate UAs from getting to the content. You can also cut down exposure to replay attacks by including a unique one-time access ID via the JWT ID attribute (jti claim) β¨ Whenever the dCDN gets a request with a given unique ID, it adds that ID to the list of 'used' IDs. If an illegitimate UA tries to reuse the same URI through a replay attack, the dCDN can deny the request based on the already used access ID π« This list should be kept bounded. A reasonable approach is to expire the entries based on the exp claim value. If no exp claim is present, a simple Least Recently Used (LRU) cache could be used, but that would let values eventually get reused π¬
Illegitimate clients behind a NAT
When there are multiple users behind the same NAT, all of them have the same IP address from the dCDN's point of view π« That means the dCDN can't tell the users apart based on Client IP Address, and illegitimate users might end up accessing the content. One way to reduce exposure to this kind of attack is to check not only the Client IP but also other attributes, e.g., attributes that can be found in HTTP headers. However, a sophisticated attacker can easily circumvent this π΅οΈββοΈ
Shared keys
A shared key distributed between CSP and uCDN is more likely to be compromised π© Since this key can be used to legitimately sign a URL for content access authorization, it's really important to know what a compromised shared key would mean. Using a shared key scheme can be convenient, but this architecture is NOT RECOMMENDED because of the risks involved π¨ It's only included for legacy feature parity and is highly discouraged in new implementations.
Denial of service via compromised keys
If a shared key usable for signing gets compromised, an attacker can use it to perform a denial-of-service attack by forcing the CDN to evaluate prohibitively expensive regular expressions embedded in a URI Container (cdniuc) claim π₯ So compromised keys should be timely revoked to prevent exploitation.
Skeleton keys via wildcards
The URI Container (cdniuc) claim can be given a wildcard value π Combined with the fact that it's the only mandatory claim, this means you can effectively make a skeleton key π Doing this doesn't sufficiently limit the scope of the JWT, so it is NOT RECOMMENDED π ββοΈ The only way to stop such a key from being used after it's distributed is to revoke the signing key so it no longer validates.
8. Privacy ππ
The privacy protection concerns described in "Content Distribution Network Interconnection (CDNI) Logging Interface" [RFC7937] apply when the client's IP address (cdniip) or Subject (sub) is embedded in the Signed URI π That's why the mechanism described in Section 2 encrypts the Client IP or Subject before including it in the URI Signing Package (and thus the URL itself) π«Ά
9. References ππ
9.1. Normative References
[POSIX.1] The Open Group, "IEEE Standard for Information Technology
-- Portable Operating System Interface (POSIX(TM)) Base
Specifications, Issue 7", (Revision of IEEE Std
1003.1-2008), IEEE Std 1003.1-2017, January 2018,
<https://pubs.opengroup.org/onlinepubs/9699919799/>.
[RFC0791] Postel, J., "Internet Protocol", STD 5, RFC 791,
DOI 10.17487/RFC0791, September 1981,
<https://www.rfc-editor.org/info/rfc791>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66,
RFC 3986, DOI 10.17487/RFC3986, January 2005,
<https://www.rfc-editor.org/info/rfc3986>.
[RFC5905] Mills, D., Martin, J., Ed., Burbank, J., and W. Kasch,
"Network Time Protocol Version 4: Protocol and Algorithms
Specification", RFC 5905, DOI 10.17487/RFC5905, June 2010,
<https://www.rfc-editor.org/info/rfc5905>.
[RFC5952] Kawamura, S. and M. Kawashima, "A Recommendation for IPv6
Address Text Representation", RFC 5952,
DOI 10.17487/RFC5952, August 2010,
<https://www.rfc-editor.org/info/rfc5952>.
[RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265,
DOI 10.17487/RFC6265, April 2011,
<https://www.rfc-editor.org/info/rfc6265>.
[RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M.,
and D. Orchard, "URI Template", RFC 6570,
DOI 10.17487/RFC6570, March 2012,
<https://www.rfc-editor.org/info/rfc6570>.
[RFC6707] Niven-Jenkins, B., Le Faucheur, F., and N. Bitar, "Content
Distribution Network Interconnection (CDNI) Problem
Statement", RFC 6707, DOI 10.17487/RFC6707, September
2012, <https://www.rfc-editor.org/info/rfc6707>.
[RFC6920] Farrell, S., Kutscher, D., Dannewitz, C., Ohlman, B.,
Keranen, A., and P. Hallam-Baker, "Naming Things with
Hashes", RFC 6920, DOI 10.17487/RFC6920, April 2013,
<https://www.rfc-editor.org/info/rfc6920>.
[RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
Protocol (HTTP/1.1): Message Syntax and Routing",
RFC 7230, DOI 10.17487/RFC7230, June 2014,
<https://www.rfc-editor.org/info/rfc7230>.
[RFC7516] Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)",
RFC 7516, DOI 10.17487/RFC7516, May 2015,
<https://www.rfc-editor.org/info/rfc7516>.
[RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token
(JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015,
<https://www.rfc-editor.org/info/rfc7519>.
[RFC7937] Le Faucheur, F., Ed., Bertrand, G., Ed., Oprescu, I., Ed.,
and R. Peterkofsky, "Content Distribution Network
Interconnection (CDNI) Logging Interface", RFC 7937,
DOI 10.17487/RFC7937, August 2016,
<https://www.rfc-editor.org/info/rfc7937>.
[RFC8006] Niven-Jenkins, B., Murray, R., Caulfield, M., and K. Ma,
"Content Delivery Network Interconnection (CDNI)
Metadata", RFC 8006, DOI 10.17487/RFC8006, December 2016,
<https://www.rfc-editor.org/info/rfc8006>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for
Writing an IANA Considerations Section in RFCs", BCP 26,
RFC 8126, DOI 10.17487/RFC8126, June 2017,
<https://www.rfc-editor.org/info/rfc8126>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", STD 90, RFC 8259,
DOI 10.17487/RFC8259, December 2017,
<https://www.rfc-editor.org/info/rfc8259>.
9.2. Informative References
[IANA.JWT.Claims]
IANA, "JSON Web Token (JWT)",
<https://www.iana.org/assignments/jwt>.
[MPEG-DASH]
ISO, "Information technology -- Dynamic adaptive streaming
over HTTP (DASH) -- Part 1: Media presentation description
and segment formats", ISO/IEC 23009-1:2019, Edition 4,
December 2019, <https://www.iso.org/standard/79329.html>.
[RFC6983] van Brandenburg, R., van Deventer, O., Le Faucheur, F.,
and K. Leung, "Models for HTTP-Adaptive-Streaming-Aware
Content Distribution Network Interconnection (CDNI)",
RFC 6983, DOI 10.17487/RFC6983, July 2013,
<https://www.rfc-editor.org/info/rfc6983>.
[RFC7336] Peterson, L., Davie, B., and R. van Brandenburg, Ed.,
"Framework for Content Distribution Network
Interconnection (CDNI)", RFC 7336, DOI 10.17487/RFC7336,
August 2014, <https://www.rfc-editor.org/info/rfc7336>.
[RFC7337] Leung, K., Ed. and Y. Lee, Ed., "Content Distribution
Network Interconnection (CDNI) Requirements", RFC 7337,
DOI 10.17487/RFC7337, August 2014,
<https://www.rfc-editor.org/info/rfc7337>.
[RFC7517] Jones, M., "JSON Web Key (JWK)", RFC 7517,
DOI 10.17487/RFC7517, May 2015,
<https://www.rfc-editor.org/info/rfc7517>.
[RFC7975] Niven-Jenkins, B., Ed. and R. van Brandenburg, Ed.,
"Request Routing Redirection Interface for Content
Delivery Network (CDN) Interconnection", RFC 7975,
DOI 10.17487/RFC7975, October 2016,
<https://www.rfc-editor.org/info/rfc7975>.
[RFC8008] Seedorf, J., Peterson, J., Previdi, S., van Brandenburg,
R., and K. Ma, "Content Delivery Network Interconnection
(CDNI) Request Routing: Footprint and Capabilities
Semantics", RFC 8008, DOI 10.17487/RFC8008, December 2016,
<https://www.rfc-editor.org/info/rfc8008>.
[RFC8216] Pantos, R., Ed. and W. May, "HTTP Live Streaming",
RFC 8216, DOI 10.17487/RFC8216, August 2017,
<https://www.rfc-editor.org/info/rfc8216>.
[RFC8725] Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token Best
Current Practices", BCP 225, RFC 8725,
DOI 10.17487/RFC8725, February 2020,
<https://www.rfc-editor.org/info/rfc8725>.
Appendix A. Signed URI Package Example β¨
okay bestie, this appendix has three examples of token usage π first up is a simple one with only the required claim present, then a complex one that shows off the full JWT claims set, including an encrypted Client IP Address (cdniip) π, and finally one that uses a Signed Token Renewal π
Note: all of the examples have extra empty space added so they're easier to read, but that space is not in the generated content π
Every example uses the same JWK Set [RFC7517] ποΈ
{ "keys": [
{
"kty": "EC",
"kid": "P5UpOv0eMq1wcxLf7WxIg09JdSYGYFDOWkldueaImf0",
"use": "sig",
"alg": "ES256",
"crv": "P-256",
"x": "be807S4O7dzB6I4hTiCUvmxCI6FuxWba1xYBlLSSsZ8",
"y": "rOGC4vI69g-WF9AGEVI37sNNwbjIzBxSjLvIL7f3RBA"
},
{
"kty": "EC",
"kid": "P5UpOv0eMq1wcxLf7WxIg09JdSYGYFDOWkldueaImf0",
"use": "sig",
"alg": "ES256",
"crv": "P-256",
"x": "be807S4O7dzB6I4hTiCUvmxCI6FuxWba1xYBlLSSsZ8",
"y": "rOGC4vI69g-WF9AGEVI37sNNwbjIzBxSjLvIL7f3RBA",
"d": "yaowezrCLTU6yIwUL5RQw67cHgvZeMTLVZXjUGb1A1M"
},
{
"kty": "oct",
"kid": "f-WbjxBC3dPuI3d24kP2hfvos7Qz688UTi6aB0hN998",
"use": "enc",
"alg": "A128GCM",
"k": "4uFxxV7fhNmrtiah2d1fFg"
}
]}
Note: these are the public signing key, the private signing key, and the shared secret encryption key, in that order π the public and private signing keys have the same fingerprint and only differ by the d parameter, which is missing from the public signing key π«Ά
A.1. Simple Example
this one is a simple, common usage example with a minimal subset of claims that the authors find most useful π
The JWT Claim Set before signing:
Note: "sha-256;2tderfWPa86Ku7YnzW51YUp7dGUjBS_3SW3ELx4hmWY" is the URL Segment form (Section 5 of [RFC6920]) of "http://cdni.example/foo/bar" πΈ
{
"exp": 1646867369,
"iss": "uCDN Inc",
"cdniuc":
"hash:sha-256;2tderfWPa86Ku7YnzW51YUp7dGUjBS_3SW3ELx4hmWY"
}
The signed JWT:
eyJhbGciOiJFUzI1NiIsImtpZCI6IlA1VXBPdjBlTXExd2N4TGY3V3hJZzA5SmRTWU
dZRkRPV2tsZHVlYUltZjAifQ.eyJleHAiOjE2NDY4NjczNjksImlzcyI6InVDRE4gS
W5jIiwiY2RuaXVjIjoiaGFzaDpzaGEtMjU2OzJ0ZGVyZldQYTg2S3U3WW56VzUxWVV
wN2RHVWpCU18zU1czRUx4NGhtV1kifQ.TaNlJM3D96i_9J9XvlICO6FUIDFTqt3E2Y
JkEUOLfcH0b89wYRKTbJ9Yj6h_GRgSoZoQO0cps3yUPcWGK3smCw
A.2. Complex Example
this one is the main character π it uses every field except the ones for Signed Token Renewal, including Client IP Address (cdniip) and Subject (sub), which are both encrypted π that makes the signed JWT token a lot bigger, so heads up π
JWE for Client IP Address (cdniip) of [2001:db8::1/32]:
eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiZGlyIiwia2lkIjoiZi1XYmp4QkMzZFB1ST
NkMjRrUDJoZnZvczdRejY4OFVUaTZhQjBoTjk5OCJ9..aUDDFEQBIc3nWjOb.bGXWT
HPkntmPCKn0pPPNEQ.iyTttnFybO2YBLqwl_YSjA
JWE for Subject (sub) of "UserToken":
eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiZGlyIiwia2lkIjoiZi1XYmp4QkMzZFB1ST
NkMjRrUDJoZnZvczdRejY4OFVUaTZhQjBoTjk5OCJ9..CLAu80xclc8Bp-Ui.6P1A3
F6ip2Dv.CohdtLLpgBnTvRJQCFuz-g
The JWT Claim Set before signing:
{
"aud": "dCDN LLC",
"sub": "eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiZGlyIiwia2lkIjoiZi1XYmp4
QkMzZFB1STNkMjRrUDJoZnZvczdRejY4OFVUaTZhQjBoTjk5OCJ9..CLAu80xclc8B
p-Ui.6P1A3F6ip2Dv.CohdtLLpgBnTvRJQCFuz-g",
"cdniip": "eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiZGlyIiwia2lkIjoiZi1XY
mp4QkMzZFB1STNkMjRrUDJoZnZvczdRejY4OFVUaTZhQjBoTjk5OCJ9..aUDDFEQBI
c3nWjOb.bGXWTHPkntmPCKn0pPPNEQ.iyTttnFybO2YBLqwl_YSjA",
"cdniv": 1,
"exp": 1646867369,
"iat": 1646694569,
"iss": "uCDN Inc",
"jti": "5DAafLhZAfhsbe",
"nbf": 1646780969,
"cdniuc": "regex:http://cdni\\.example/foo/bar/[0-9]{3}\\.png"
}
The signed JWT:
eyJhbGciOiJFUzI1NiIsImtpZCI6IlA1VXBPdjBlTXExd2N4TGY3V3hJZzA5SmRTWU
dZRkRPV2tsZHVlYUltZjAifQ.eyJhdWQiOiJkQ0ROIExMQyIsInN1YiI6ImV5Smxib
U1pT2lKQk1USTRSME5OSWl3aVlXeG5Jam9pWkdseUlpd2lhMmxrSWpvaVppMVhZbXA
0UWtNelpGQjFTVE5rTWpSclVESm9ablp2Y3pkUmVqWTRPRlZVYVRaaFFqQm9Uams1T
0NKOS4uQ0xBdTgweGNsYzhCcC1VaS42UDFBM0Y2aXAyRHYuQ29oZHRMTHBnQm5UdlJ
KUUNGdXotZyIsImNkbmlpcCI6ImV5SmxibU1pT2lKQk1USTRSME5OSWl3aVlXeG5Ja
m9pWkdseUlpd2lhMmxrSWpvaVppMVhZbXA0UWtNelpGQjFTVE5rTWpSclVESm9ablp
2Y3pkUmVqWTRPRlZVYVRaaFFqQm9Uams1T0NKOS4uYVVEREZFUUJJYzNuV2pPYi5iR
1hXVEhQa250bVBDS24wcFBQTkVRLml5VHR0bkZ5Yk8yWUJMcXdsX1lTakEiLCJjZG5
pdiI6MSwiZXhwIjoxNjQ2ODY3MzY5LCJpYXQiOjE2NDY2OTQ1NjksImlzcyI6InVDR
E4gSW5jIiwianRpIjoiNURBYWZMaFpBZmhzYmUiLCJuYmYiOjE2NDY3ODA5NjksImN
kbml1YyI6InJlZ2V4Omh0dHA6Ly9jZG5pXFwuZXhhbXBsZS9mb28vYmFyL1swLTlde
zN9XFwucG5nIn0.IjmVX0uD5MYqArc-M08uEsEeoDQn8kuYXZ9HGHDmDDxsHikT0c8
jcX8xYD0z3LzQclMG65i1kT2sRbZ7isUw8w
A.3. Signed Token Renewal Example
last but not least, this one shows the fields for Signed Token Renewal πβ¨
The JWT Claim Set before signing:
{
"cdniets": 30,
"cdnistt": 1,
"cdnistd": 2,
"exp": 1646867369,
"cdniuc": "regex:http://cdni\\.example/foo/bar/[0-9]{3}\\.ts"
}
The signed JWT:
eyJhbGciOiJFUzI1NiIsImtpZCI6IlA1VXBPdjBlTXExd2N4TGY3V3hJZzA5SmRTWU
dZRkRPV2tsZHVlYUltZjAifQ.eyJjZG5pZXRzIjozMCwiY2RuaXN0dCI6MSwiY2Rua
XN0ZCI6MiwiZXhwIjoxNjQ2ODY3MzY5LCJjZG5pdWMiOiJyZWdleDpodHRwOi8vY2R
uaVxcLmV4YW1wbGUvZm9vL2Jhci9bMC05XXszfVxcLnRzIn0.tlPvoKw3BCClw4Lx9
PQu7MK6b2IN55ZoCPSaxovGK0zS53Wpb1MbJBow7G8LiGR39h6-2Iq7PWUSr3MdTIz
HYw
Once the server verifies the signed JWT, it sends back a brand-new signed JWT with an updated Expiry Time (exp), as shown below π notice that the Expiry Time goes up by the expiration time setting (cdniets) value β°
The JWT Claim Set before signing:
{
"cdniets": 30,
"cdnistt": 1,
"cdnistd": 2,
"exp": 1646867399,
"cdniuc": "regex:http://cdni\\.example/foo/bar/[0-9]{3}\\.ts"
}
The signed JWT:
eyJhbGciOiJFUzI1NiIsImtpZCI6IlA1VXBPdjBlTXExd2N4TGY3V3hJZzA5SmRTWU
dZRkRPV2tsZHVlYUltZjAifQ.eyJjZG5pZXRzIjozMCwiY2RuaXN0dCI6MSwiY2Rua
XN0ZCI6MiwiZXhwIjoxNjQ2ODY3Mzk5LCJjZG5pdWMiOiJyZWdleDpodHRwOi8vY2R
uaVxcLmV4YW1wbGUvZm9vL2Jhci9bMC05XXszfVxcLnRzIn0.ivY5d_fKGd-OHTpUs
8uJUrnHvt-rduzu5H4zM7167pUUAghub53FqDQ5G16jRYX2sY73mA_uLpYDdb-CPts
8FA
Acknowledgements
the authors would like to give a huge thank you π«Ά to these people for reviewing this document and giving feedback: Scott Leibrand, Kevin Ma, Ben Niven-Jenkins, Thierry Magnien, Dan York, Bhaskar Bhupalam, Matt Caulfield, Samuel Rajakumar, Iuniana Oprescu, Leif Hedstrom, Gancho Tenev, Brian Campbell, and Chris Lemmons π
Contributors
and then there are the people who contributed whole significant sections, so they get extra special mentions π
- Matt Caulfield provided content for Section 4.4, "CDNI Metadata Interface".
- Emmanuel Thomas provided content for HTTP Adaptive Streaming.
- Matt Miller provided consultation on JWT usage as well as code to generate working JWT examples.
Authors' Addresses
Ray van Brandenburg Tiledmedia Anna van Buerenplein 1 2595DA Den Haag Netherlands Phone: +31 88 866 7000 Email: ray@tiledmedia.com
Kent Leung Email: mail4kentl@gmail.com
Phil Sorber Apple, Inc. Suite 410 1800 Wazee Street Denver, CO 80202 United States Email: sorber@apple.com
π¦ where this page comes from
- ietf: rfc9246 2022-06
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms