@@ -13,7 +13,12 @@ import {
1313 AssertionConfig ,
1414 AssertionVerificationKeys ,
1515} from '../tdf3/src/assertions.js' ;
16- import { type KasPublicKeyAlgorithm , OriginAllowList , isPublicKeyAlgorithm } from './access.js' ;
16+ import {
17+ type KasPublicKeyAlgorithm ,
18+ OriginAllowList ,
19+ fetchKeyAccessServers ,
20+ isPublicKeyAlgorithm ,
21+ } from './access.js' ;
1722import { type Manifest } from '../tdf3/src/models/manifest.js' ;
1823import { type Payload } from '../tdf3/src/models/payload.js' ;
1924import {
@@ -87,6 +92,7 @@ export type CreateNanoTDFOptions = CreateOptions & {
8792} ;
8893
8994export type CreateNanoTDFCollectionOptions = CreateNanoTDFOptions & {
95+ platformUrl : string ;
9096 // The maximum number of key iterations to use for a single DEK.
9197 maxKeyIterations ?: number ;
9298} ;
@@ -136,6 +142,8 @@ export type CreateZTDFOptions = CreateOptions & {
136142export type ReadOptions = {
137143 // ciphertext
138144 source : Source ;
145+ // Platform URL
146+ platformUrl ?: string ;
139147 // list of KASes that may be contacted for a rewrap
140148 allowedKASEndpoints ?: string [ ] ;
141149 // Optionally disable checking the allowlist
@@ -157,6 +165,9 @@ export type OpenTDFOptions = {
157165 // Policy service endpoint
158166 policyEndpoint ?: string ;
159167
168+ // Platform URL
169+ platformUrl ?: string ;
170+
160171 // Auth provider for connections to the policy service and KASes.
161172 authProvider : AuthProvider ;
162173
@@ -286,6 +297,7 @@ export type TDFReader = {
286297// SDK for dealing with OpenTDF data and policy services.
287298export class OpenTDF {
288299 // Configuration service and more is at this URL/connectRPC endpoint
300+ readonly platformUrl : string ;
289301 readonly policyEndpoint : string ;
290302 readonly authProvider : AuthProvider ;
291303 readonly dpopEnabled : boolean ;
@@ -305,11 +317,19 @@ export class OpenTDF {
305317 disableDPoP,
306318 policyEndpoint,
307319 rewrapCacheOptions,
320+ platformUrl,
308321 } : OpenTDFOptions ) {
309322 this . authProvider = authProvider ;
310323 this . defaultCreateOptions = defaultCreateOptions || { } ;
311324 this . defaultReadOptions = defaultReadOptions || { } ;
312325 this . dpopEnabled = ! ! disableDPoP ;
326+ if ( platformUrl ) {
327+ this . platformUrl = platformUrl ;
328+ } else {
329+ console . warn (
330+ "Warning: 'platformUrl' is required for security to ensure the SDK uses the platform-configured Key Access Server list"
331+ ) ;
332+ }
313333 this . policyEndpoint = policyEndpoint || '' ;
314334 this . rewrapCache = new RewrapCache ( rewrapCacheOptions ) ;
315335 this . tdf3Client = new TDF3Client ( {
@@ -333,8 +353,14 @@ export class OpenTDF {
333353 }
334354
335355 async createNanoTDF ( opts : CreateNanoTDFOptions ) : Promise < DecoratedStream > {
336- opts = { ...this . defaultCreateOptions , ...opts } ;
337- const collection = await this . createNanoTDFCollection ( opts ) ;
356+ opts = {
357+ ...this . defaultCreateOptions ,
358+ ...opts ,
359+ } ;
360+ const collection = await this . createNanoTDFCollection ( {
361+ ...opts ,
362+ platformUrl : this . platformUrl ,
363+ } ) ;
338364 try {
339365 return await collection . encrypt ( opts . source ) ;
340366 } finally {
@@ -415,6 +441,9 @@ class UnknownTypeReader {
415441 this . state = 'resolving' ;
416442 const chunker = await fromSource ( this . opts . source ) ;
417443 const prefix = await chunker ( 0 , 3 ) ;
444+ if ( ! this . opts . platformUrl && this . outer . platformUrl ) {
445+ this . opts . platformUrl = this . outer . platformUrl ;
446+ }
418447 if ( prefix [ 0 ] === 0x50 && prefix [ 1 ] === 0x4b ) {
419448 this . state = 'loaded' ;
420449 return new ZTDFReader ( this . outer . tdf3Client , this . opts , chunker ) ;
@@ -466,6 +495,13 @@ class NanoTDFReader {
466495 readonly chunker : Chunker ,
467496 private readonly rewrapCache : RewrapCache
468497 ) {
498+ if (
499+ ! this . opts . ignoreAllowlist &&
500+ ! this . outer . platformUrl &&
501+ ! this . opts . allowedKASEndpoints ?. length
502+ ) {
503+ throw new ConfigurationError ( 'platformUrl is required when allowedKasEndpoints is empty' ) ;
504+ }
469505 // lazily load the container
470506 this . container = new Promise ( async ( resolve , reject ) => {
471507 try {
@@ -493,6 +529,7 @@ class NanoTDFReader {
493529 dpopEnabled : this . outer . dpopEnabled ,
494530 dpopKeys : this . outer . dpopKeys ,
495531 kasEndpoint : this . opts . allowedKASEndpoints ?. [ 0 ] || 'https://disallow.all.invalid' ,
532+ platformUrl : this . outer . platformUrl ,
496533 } ) ;
497534 // TODO: The version number should be fetched from the API
498535 const version = '0.0.1' ;
@@ -550,17 +587,29 @@ class ZTDFReader {
550587 noVerify : noVerifyAssertions ,
551588 wrappingKeyAlgorithm,
552589 } = this . opts ;
553- const allowList = new OriginAllowList (
554- this . opts . allowedKASEndpoints ?? [ ] ,
555- this . opts . ignoreAllowlist
556- ) ;
590+
591+ if ( ! this . opts . ignoreAllowlist && ! this . opts . allowedKASEndpoints && ! this . opts . platformUrl ) {
592+ throw new ConfigurationError ( 'platformUrl is required when allowedKasEndpoints is empty' ) ;
593+ }
594+
557595 const dpopKeys = await this . client . dpopKeys ;
558596
559597 const { authProvider, cryptoService } = this . client ;
560598 if ( ! authProvider ) {
561599 throw new ConfigurationError ( 'authProvider is required' ) ;
562600 }
563601
602+ let allowList : OriginAllowList | undefined ;
603+
604+ if ( this . opts . allowedKASEndpoints ?. length || this . opts . ignoreAllowlist ) {
605+ allowList = new OriginAllowList (
606+ this . opts . allowedKASEndpoints || [ ] ,
607+ this . opts . ignoreAllowlist
608+ ) ;
609+ } else if ( this . opts . platformUrl ) {
610+ allowList = await fetchKeyAccessServers ( this . opts . platformUrl , authProvider ) ;
611+ }
612+
564613 const overview = await this . overview ;
565614 const oldStream = await decryptStreamFrom (
566615 {
@@ -646,6 +695,7 @@ class Collection {
646695 authProvider,
647696 kasEndpoint : opts . defaultKASEndpoint ?? 'https://disallow.all.invalid' ,
648697 maxKeyIterations : opts . maxKeyIterations ,
698+ platformUrl : opts . platformUrl ,
649699 } ) ;
650700 }
651701
0 commit comments