Skip to content

Commit 29a9b82

Browse files
fix: add ignoreAllowList flag (#331)
* feat(cli): Adds --allowList parameter to cli e.g. ``` opentdf.mjs --allowList https://kas.a,https://kas.b ``` --------- Signed-off-by: Tyler Biscoe <[email protected]> Co-authored-by: David Mihalcik <[email protected]> Co-authored-by: elizabethhealy <[email protected]>
1 parent 297cec6 commit 29a9b82

File tree

6 files changed

+55
-11
lines changed

6 files changed

+55
-11
lines changed

cli/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/src/cli.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ export const handleArgs = (args: string[]) => {
185185
type: 'string',
186186
validate: (attributes: string) => attributes.split(','),
187187
})
188+
.boolean('ignoreAllowList')
188189
.option('auth', {
189190
group: 'Authentication:',
190191
type: 'string',
@@ -293,6 +294,7 @@ export const handleArgs = (args: string[]) => {
293294
async (argv) => {
294295
log('DEBUG', 'Running decrypt command');
295296
const allowedKases = argv.allowList?.split(',');
297+
const ignoreAllowList = !!argv.ignoreAllowList;
296298
const authProvider = await processAuth(argv);
297299
log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`);
298300

@@ -301,6 +303,7 @@ export const handleArgs = (args: string[]) => {
301303
log('DEBUG', `TDF3 Client`);
302304
const client = new TDF3Client({
303305
allowedKases,
306+
ignoreAllowList,
304307
authProvider,
305308
kasEndpoint,
306309
dpopEnabled: argv.dpop,
@@ -318,9 +321,16 @@ export const handleArgs = (args: string[]) => {
318321
const dpopEnabled = !!argv.dpop;
319322
const client =
320323
argv.containerType === 'nano'
321-
? new NanoTDFClient({ allowedKases, authProvider, kasEndpoint, dpopEnabled })
324+
? new NanoTDFClient({
325+
allowedKases,
326+
ignoreAllowList,
327+
authProvider,
328+
kasEndpoint,
329+
dpopEnabled,
330+
})
322331
: new NanoTDFDatasetClient({
323332
allowedKases,
333+
ignoreAllowList,
324334
authProvider,
325335
kasEndpoint,
326336
dpopEnabled,
@@ -376,12 +386,14 @@ export const handleArgs = (args: string[]) => {
376386
const authProvider = await processAuth(argv);
377387
log('DEBUG', `Initialized auth provider ${JSON.stringify(authProvider)}`);
378388
const kasEndpoint = argv.kasEndpoint;
389+
const ignoreAllowList = !!argv.ignoreAllowList;
379390
const allowedKases = argv.allowList?.split(',');
380391

381392
if ('tdf3' === argv.containerType) {
382393
log('DEBUG', `TDF3 Client`);
383394
const client = new TDF3Client({
384395
allowedKases,
396+
ignoreAllowList,
385397
authProvider,
386398
kasEndpoint,
387399
dpopEnabled: argv.dpop,

lib/src/access.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,16 @@ const origin = (u: string): string => {
7272

7373
export class OriginAllowList {
7474
origins: string[];
75-
constructor(urls: string[]) {
75+
allowAll: boolean;
76+
constructor(urls: string[], allowAll?: boolean) {
7677
this.origins = urls.map(origin);
7778
urls.forEach(validateSecureUrl);
79+
this.allowAll = !!allowAll;
7880
}
7981
allows(url: string): boolean {
82+
if (this.allowAll) {
83+
return true;
84+
}
8085
return this.origins.includes(origin(url));
8186
}
8287
}

lib/src/nanotdf/Client.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { cryptoPublicToPem, pemToCryptoPublicKey, validateSecureUrl } from '../u
1010

1111
export interface ClientConfig {
1212
allowedKases?: string[];
13+
ignoreAllowList?: boolean;
1314
authProvider: AuthProvider;
1415
dpopEnabled?: boolean;
1516
dpopKeys?: Promise<CryptoKeyPair>;
@@ -145,13 +146,20 @@ export default class Client {
145146
}
146147
this.iv = 1;
147148
} else {
148-
const { allowedKases, authProvider, dpopEnabled, dpopKeys, ephemeralKeyPair, kasEndpoint } =
149-
optsOrOldAuthProvider;
149+
const {
150+
allowedKases,
151+
ignoreAllowList,
152+
authProvider,
153+
dpopEnabled,
154+
dpopKeys,
155+
ephemeralKeyPair,
156+
kasEndpoint,
157+
} = optsOrOldAuthProvider;
150158
this.authProvider = authProvider;
151159
// TODO Disallow http KAS. For now just log as error
152160
validateSecureUrl(kasEndpoint);
153161
this.kasUrl = kasEndpoint;
154-
this.allowedKases = new OriginAllowList(allowedKases || [kasEndpoint]);
162+
this.allowedKases = new OriginAllowList(allowedKases || [kasEndpoint], !!ignoreAllowList);
155163
this.dpopEnabled = !!dpopEnabled;
156164
if (dpopKeys) {
157165
this.requestSignerKeyPair = dpopKeys;

lib/tdf3/src/client/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ export interface ClientConfig {
137137
* Defaults to `[kasEndpoint]`.
138138
*/
139139
allowedKases?: string[];
140+
ignoreAllowList?: boolean;
140141
easEndpoint?: string;
141142
// DEPRECATED Ignored
142143
keyRewrapEndpoint?: string;
@@ -275,7 +276,10 @@ export class Client {
275276

276277
const kasOrigin = new URL(this.kasEndpoint).origin;
277278
if (clientConfig.allowedKases) {
278-
this.allowedKases = new OriginAllowList(clientConfig.allowedKases);
279+
this.allowedKases = new OriginAllowList(
280+
clientConfig.allowedKases,
281+
!!clientConfig.ignoreAllowList
282+
);
279283
if (!validateSecureUrl(this.kasEndpoint) && !this.allowedKases.allows(kasOrigin)) {
280284
throw new TdfError(`Invalid KAS endpoint [${this.kasEndpoint}]`);
281285
}
@@ -285,7 +289,7 @@ export class Client {
285289
`Invalid KAS endpoint [${this.kasEndpoint}]; to force, please list it among allowedKases`
286290
);
287291
}
288-
this.allowedKases = new OriginAllowList([kasOrigin]);
292+
this.allowedKases = new OriginAllowList([kasOrigin], !!clientConfig.ignoreAllowList);
289293
}
290294

291295
this.authProvider = config.authProvider;

lib/tests/mocha/unit/tdf.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ describe('splitLookupTableFactory', () => {
111111
});
112112
});
113113

114+
it('should return a correct split table for valid input with ignoreAllowList', () => {
115+
const keyAccess: KeyAccessObject[] = [
116+
{ sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' },
117+
{ sid: 'split2', type: 'remote', url: 'https://kas2', protocol: 'kas' },
118+
];
119+
const allowedKases = new OriginAllowList([], true);
120+
121+
const result = TDF.splitLookupTableFactory(keyAccess, allowedKases);
122+
123+
expect(result).to.deep.equal({
124+
split1: { 'https://kas1': keyAccess[0] },
125+
split2: { 'https://kas2': keyAccess[1] },
126+
});
127+
});
128+
114129
it('should throw KasDecryptError for disallowed KASes', () => {
115130
const keyAccess: KeyAccessObject[] = [
116131
{ sid: 'split1', type: 'remote', url: 'https://kas1', protocol: 'kas' },

0 commit comments

Comments
 (0)