@atlasauth/backend 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/dist/access-control.d.ts +53 -0
- package/dist/access-control.js +46 -0
- package/dist/access-control.js.map +1 -0
- package/dist/algs.d.ts +7 -0
- package/dist/algs.js +11 -0
- package/dist/algs.js.map +1 -0
- package/dist/client/api-keys.d.ts +49 -4
- package/dist/client/api-keys.js +6 -2
- package/dist/client/api-keys.js.map +1 -1
- package/dist/client/app-roles.d.ts +76 -0
- package/dist/client/app-roles.js +39 -0
- package/dist/client/app-roles.js.map +1 -0
- package/dist/client/email-templates.d.ts +1 -1
- package/dist/client/email-templates.js.map +1 -1
- package/dist/client/index.d.ts +49 -3
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/instance-security.d.ts +34 -0
- package/dist/client/instance-security.js +8 -0
- package/dist/client/instance-security.js.map +1 -1
- package/dist/client/notifications.d.ts +1 -1
- package/dist/client/notifications.js.map +1 -1
- package/dist/client/oauth-clients.d.ts +57 -2
- package/dist/client/oauth-clients.js +13 -0
- package/dist/client/oauth-clients.js.map +1 -1
- package/dist/client/referrals.d.ts +7 -1
- package/dist/client/referrals.js.map +1 -1
- package/dist/client/resource-servers.d.ts +12 -3
- package/dist/client/resource-servers.js.map +1 -1
- package/dist/client/scim-tokens.d.ts +18 -0
- package/dist/client/scim-tokens.js +4 -0
- package/dist/client/scim-tokens.js.map +1 -1
- package/dist/client/sso-connections.d.ts +22 -0
- package/dist/client/sso-connections.js.map +1 -1
- package/dist/client/users.d.ts +40 -4
- package/dist/client/users.js +8 -3
- package/dist/client/users.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/logout-token.d.ts +1 -1
- package/dist/logout-token.js +3 -2
- package/dist/logout-token.js.map +1 -1
- package/dist/oauth-resource.d.ts +145 -0
- package/dist/oauth-resource.js +294 -0
- package/dist/oauth-resource.js.map +1 -0
- package/dist/oidc.d.ts +1 -1
- package/dist/oidc.js +5 -3
- package/dist/oidc.js.map +1 -1
- package/dist/referral-test-calls.d.ts +7 -7
- package/dist/referral-test-calls.js +2 -2
- package/dist/testing.d.ts +6 -4
- package/dist/testing.js +7 -6
- package/dist/testing.js.map +1 -1
- package/dist/verify.d.ts +11 -0
- package/dist/verify.js +15 -1
- package/dist/verify.js.map +1 -1
- package/package.json +3 -3
package/dist/logout-token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logout-token.js","sourceRoot":"","sources":["../src/logout-token.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"logout-token.js","sourceRoot":"","sources":["../src/logout-token.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { type Jwks } from './jwks-cache';
|
|
2
|
+
/**
|
|
3
|
+
* Protecting YOUR API — or your own MCP server — with access tokens Atlas
|
|
4
|
+
* issues to OAuth clients (authorization code, device, client credentials,
|
|
5
|
+
* token exchange). Atlas is the authorization server; your API is the
|
|
6
|
+
* resource server. This module:
|
|
7
|
+
* - verifies the access token locally against the instance JWKS (cached;
|
|
8
|
+
* no call to Atlas on the hot path): signature, `iss`, `exp`/`nbf`, that it
|
|
9
|
+
* IS an access token, and that its `aud` names your API (RFC 8707);
|
|
10
|
+
* - enforces required scopes;
|
|
11
|
+
* - enforces sender constraint: a DPoP-bound token (`cnf.jkt`) must arrive
|
|
12
|
+
* with a valid DPoP proof for the same key (RFC 9449), and is never accepted
|
|
13
|
+
* as a plain Bearer token;
|
|
14
|
+
* - answers failures with the RFC 6750 / RFC 9728 `WWW-Authenticate`
|
|
15
|
+
* challenge (`resource_metadata`, `insufficient_scope` + the scopes needed),
|
|
16
|
+
* which is exactly what an MCP client needs to discover how to sign in;
|
|
17
|
+
* - builds the RFC 9728 protected-resource metadata document to serve at
|
|
18
|
+
* `/.well-known/oauth-protected-resource` on your API's host.
|
|
19
|
+
* Framework-agnostic: hand it any request with `method`, `url` and `headers`.
|
|
20
|
+
*/
|
|
21
|
+
/** Clock skew tolerated on `exp`/`nbf` and on DPoP proof `iat`. */
|
|
22
|
+
export declare const ACCESS_TOKEN_CLOCK_SKEW_SECONDS = 5;
|
|
23
|
+
/** How old a DPoP proof may be. */
|
|
24
|
+
export declare const DPOP_PROOF_MAX_AGE_SECONDS = 300;
|
|
25
|
+
export interface AccessTokenClaims {
|
|
26
|
+
iss: string;
|
|
27
|
+
sub: string;
|
|
28
|
+
aud?: string | string[];
|
|
29
|
+
exp: number;
|
|
30
|
+
iat?: number;
|
|
31
|
+
scope?: string;
|
|
32
|
+
client_id?: string;
|
|
33
|
+
azp?: string;
|
|
34
|
+
permissions?: string[];
|
|
35
|
+
cnf?: {
|
|
36
|
+
jkt?: string;
|
|
37
|
+
'x5t#S256'?: string;
|
|
38
|
+
};
|
|
39
|
+
token_use?: string;
|
|
40
|
+
[claim: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
export interface ResourceRequestLike {
|
|
43
|
+
method?: string;
|
|
44
|
+
/** Absolute URL, or a path (combined with `resource` origin for the DPoP `htu` check). */
|
|
45
|
+
url?: string;
|
|
46
|
+
headers: Record<string, string | string[] | undefined> | {
|
|
47
|
+
get(name: string): string | null;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Replay guard for DPoP proof `jti`s. The in-memory one is for a single process. */
|
|
51
|
+
export interface DpopReplayStore {
|
|
52
|
+
/** Record `jti` until `expiresAt` (ms); return false when it was already seen. */
|
|
53
|
+
claim(jti: string, expiresAt: number): Promise<boolean> | boolean;
|
|
54
|
+
}
|
|
55
|
+
export declare function memoryDpopReplayStore(max?: number): DpopReplayStore;
|
|
56
|
+
export interface AccessTokenVerifierOptions {
|
|
57
|
+
/** Your Atlas instance's issuer (frontend API origin), e.g. https://clerk.example.com. */
|
|
58
|
+
issuer: string;
|
|
59
|
+
/**
|
|
60
|
+
* Your API's identifier (the Resource Server identifier registered in Atlas,
|
|
61
|
+
* RFC 8707 `resource`). The token's `aud` must contain one of these. Pass
|
|
62
|
+
* `false` only to accept tokens with no audience (userinfo-style tokens).
|
|
63
|
+
*/
|
|
64
|
+
audience: string | readonly string[] | false;
|
|
65
|
+
/** Scopes every request must carry (all of them). */
|
|
66
|
+
requiredScopes?: readonly string[];
|
|
67
|
+
/** The JWKS URL; default `${issuer}/.well-known/jwks.json`. */
|
|
68
|
+
jwksUrl?: string;
|
|
69
|
+
/** A static key set (tests / offline). Mutually exclusive with `jwksUrl`. */
|
|
70
|
+
jwks?: Jwks;
|
|
71
|
+
/**
|
|
72
|
+
* Where your protected-resource metadata lives, advertised in every 401 as
|
|
73
|
+
* `resource_metadata` so an MCP / OAuth client can discover Atlas. Typically
|
|
74
|
+
* `https://api.example.com/.well-known/oauth-protected-resource`.
|
|
75
|
+
*/
|
|
76
|
+
resourceMetadataUrl?: string;
|
|
77
|
+
/** Require a DPoP-bound token on every request (never accept plain Bearer). */
|
|
78
|
+
requireDpop?: boolean;
|
|
79
|
+
/** The public origin of this API, for DPoP `htu` when `request.url` is a path. */
|
|
80
|
+
publicOrigin?: string;
|
|
81
|
+
dpopReplayStore?: DpopReplayStore;
|
|
82
|
+
/** `WWW-Authenticate` realm. */
|
|
83
|
+
realm?: string;
|
|
84
|
+
fetchImpl?: typeof fetch;
|
|
85
|
+
now?: () => number;
|
|
86
|
+
}
|
|
87
|
+
export type AccessTokenErrorCode = 'invalid_request' | 'invalid_token' | 'insufficient_scope' | 'invalid_dpop_proof';
|
|
88
|
+
export type AccessTokenResult = {
|
|
89
|
+
ok: true;
|
|
90
|
+
claims: AccessTokenClaims;
|
|
91
|
+
scopes: string[];
|
|
92
|
+
subject: string;
|
|
93
|
+
clientId: string | null;
|
|
94
|
+
dpopBound: boolean;
|
|
95
|
+
} | {
|
|
96
|
+
ok: false;
|
|
97
|
+
status: 400 | 401 | 403;
|
|
98
|
+
error: AccessTokenErrorCode | null;
|
|
99
|
+
description: string;
|
|
100
|
+
/** Set this response header verbatim. */
|
|
101
|
+
wwwAuthenticate: string;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Build an RFC 6750 / RFC 9449 / RFC 9728 `WWW-Authenticate` challenge.
|
|
105
|
+
* Without an `error`, it is the bare "authentication required" challenge
|
|
106
|
+
* (no token was sent), as RFC 6750 §3.1 asks.
|
|
107
|
+
*/
|
|
108
|
+
export declare function buildWwwAuthenticate(opts: {
|
|
109
|
+
scheme?: 'Bearer' | 'DPoP';
|
|
110
|
+
realm?: string;
|
|
111
|
+
error?: AccessTokenErrorCode | null;
|
|
112
|
+
description?: string;
|
|
113
|
+
scope?: readonly string[];
|
|
114
|
+
resourceMetadataUrl?: string;
|
|
115
|
+
dpopAlgs?: readonly string[];
|
|
116
|
+
}): string;
|
|
117
|
+
/**
|
|
118
|
+
* A reusable verifier (one JWKS cache for the life of the process). Call it per
|
|
119
|
+
* request; it never throws for a bad token — it returns the status + challenge.
|
|
120
|
+
*/
|
|
121
|
+
export declare function createAccessTokenVerifier(options: AccessTokenVerifierOptions): (request: ResourceRequestLike, extra?: {
|
|
122
|
+
requiredScopes?: readonly string[];
|
|
123
|
+
}) => Promise<AccessTokenResult>;
|
|
124
|
+
/** One-shot form of {@link createAccessTokenVerifier} (builds a fresh JWKS cache each call — prefer the factory). */
|
|
125
|
+
export declare function verifyAccessToken(request: ResourceRequestLike, options: AccessTokenVerifierOptions): Promise<AccessTokenResult>;
|
|
126
|
+
/**
|
|
127
|
+
* The RFC 9728 protected-resource metadata document for your API. Serve it as
|
|
128
|
+
* JSON at `https://<your api host>/.well-known/oauth-protected-resource` (and,
|
|
129
|
+
* for a resource with a path, at `/.well-known/oauth-protected-resource<path>`),
|
|
130
|
+
* and point `resourceMetadataUrl` at it. Atlas can also serve this document for
|
|
131
|
+
* you when the API is registered with metadata publishing turned on.
|
|
132
|
+
*/
|
|
133
|
+
export declare function protectedResourceMetadata(opts: {
|
|
134
|
+
/** Your API's identifier (the same value as the verifier's `audience`). */
|
|
135
|
+
resource: string;
|
|
136
|
+
/** Your Atlas instance issuer. */
|
|
137
|
+
issuer: string;
|
|
138
|
+
scopesSupported?: readonly string[];
|
|
139
|
+
resourceName?: string;
|
|
140
|
+
resourceDocumentation?: string;
|
|
141
|
+
/** Advertise that tokens must be DPoP-bound. */
|
|
142
|
+
dpopBoundAccessTokensRequired?: boolean;
|
|
143
|
+
}): Record<string, unknown>;
|
|
144
|
+
/** The RFC 9728 well-known path for a resource identifier (path-inserted form). */
|
|
145
|
+
export declare function protectedResourceMetadataPath(resource: string): string;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DPOP_PROOF_MAX_AGE_SECONDS = exports.ACCESS_TOKEN_CLOCK_SKEW_SECONDS = void 0;
|
|
4
|
+
exports.memoryDpopReplayStore = memoryDpopReplayStore;
|
|
5
|
+
exports.buildWwwAuthenticate = buildWwwAuthenticate;
|
|
6
|
+
exports.createAccessTokenVerifier = createAccessTokenVerifier;
|
|
7
|
+
exports.verifyAccessToken = verifyAccessToken;
|
|
8
|
+
exports.protectedResourceMetadata = protectedResourceMetadata;
|
|
9
|
+
exports.protectedResourceMetadataPath = protectedResourceMetadataPath;
|
|
10
|
+
const jose_1 = require("jose");
|
|
11
|
+
const jwks_cache_1 = require("./jwks-cache");
|
|
12
|
+
const algs_1 = require("./algs");
|
|
13
|
+
/**
|
|
14
|
+
* Protecting YOUR API — or your own MCP server — with access tokens Atlas
|
|
15
|
+
* issues to OAuth clients (authorization code, device, client credentials,
|
|
16
|
+
* token exchange). Atlas is the authorization server; your API is the
|
|
17
|
+
* resource server. This module:
|
|
18
|
+
* - verifies the access token locally against the instance JWKS (cached;
|
|
19
|
+
* no call to Atlas on the hot path): signature, `iss`, `exp`/`nbf`, that it
|
|
20
|
+
* IS an access token, and that its `aud` names your API (RFC 8707);
|
|
21
|
+
* - enforces required scopes;
|
|
22
|
+
* - enforces sender constraint: a DPoP-bound token (`cnf.jkt`) must arrive
|
|
23
|
+
* with a valid DPoP proof for the same key (RFC 9449), and is never accepted
|
|
24
|
+
* as a plain Bearer token;
|
|
25
|
+
* - answers failures with the RFC 6750 / RFC 9728 `WWW-Authenticate`
|
|
26
|
+
* challenge (`resource_metadata`, `insufficient_scope` + the scopes needed),
|
|
27
|
+
* which is exactly what an MCP client needs to discover how to sign in;
|
|
28
|
+
* - builds the RFC 9728 protected-resource metadata document to serve at
|
|
29
|
+
* `/.well-known/oauth-protected-resource` on your API's host.
|
|
30
|
+
* Framework-agnostic: hand it any request with `method`, `url` and `headers`.
|
|
31
|
+
*/
|
|
32
|
+
/** Clock skew tolerated on `exp`/`nbf` and on DPoP proof `iat`. */
|
|
33
|
+
exports.ACCESS_TOKEN_CLOCK_SKEW_SECONDS = 5;
|
|
34
|
+
/** How old a DPoP proof may be. */
|
|
35
|
+
exports.DPOP_PROOF_MAX_AGE_SECONDS = 300;
|
|
36
|
+
const DPOP_ALGS = ['ES256', 'ES384', 'ES512', 'RS256', 'RS384', 'RS512', 'PS256', 'PS384', 'PS512', 'EdDSA'];
|
|
37
|
+
function memoryDpopReplayStore(max = 10_000) {
|
|
38
|
+
const seen = new Map();
|
|
39
|
+
return {
|
|
40
|
+
claim(jti, expiresAt) {
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
if ((seen.get(jti) ?? 0) > now)
|
|
43
|
+
return false;
|
|
44
|
+
seen.set(jti, expiresAt);
|
|
45
|
+
if (seen.size > max) {
|
|
46
|
+
for (const [k, v] of seen)
|
|
47
|
+
if (v <= now)
|
|
48
|
+
seen.delete(k);
|
|
49
|
+
while (seen.size > max)
|
|
50
|
+
seen.delete(seen.keys().next().value);
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function header(req, name) {
|
|
57
|
+
const h = req.headers;
|
|
58
|
+
if (typeof h.get === 'function')
|
|
59
|
+
return h.get(name) ?? undefined;
|
|
60
|
+
const v = h[name] ?? h[name.toLowerCase()];
|
|
61
|
+
return Array.isArray(v) ? v[0] : v;
|
|
62
|
+
}
|
|
63
|
+
const quote = (v) => `"${v.replace(/["\\]/g, '\\$&')}"`;
|
|
64
|
+
/**
|
|
65
|
+
* Build an RFC 6750 / RFC 9449 / RFC 9728 `WWW-Authenticate` challenge.
|
|
66
|
+
* Without an `error`, it is the bare "authentication required" challenge
|
|
67
|
+
* (no token was sent), as RFC 6750 §3.1 asks.
|
|
68
|
+
*/
|
|
69
|
+
function buildWwwAuthenticate(opts) {
|
|
70
|
+
const parts = [];
|
|
71
|
+
if (opts.realm)
|
|
72
|
+
parts.push(`realm=${quote(opts.realm)}`);
|
|
73
|
+
if (opts.error)
|
|
74
|
+
parts.push(`error=${quote(opts.error)}`);
|
|
75
|
+
if (opts.error && opts.description)
|
|
76
|
+
parts.push(`error_description=${quote(opts.description)}`);
|
|
77
|
+
if (opts.scope && opts.scope.length > 0)
|
|
78
|
+
parts.push(`scope=${quote(opts.scope.join(' '))}`);
|
|
79
|
+
if (opts.resourceMetadataUrl)
|
|
80
|
+
parts.push(`resource_metadata=${quote(opts.resourceMetadataUrl)}`);
|
|
81
|
+
if (opts.scheme === 'DPoP' && opts.dpopAlgs)
|
|
82
|
+
parts.push(`algs=${quote(opts.dpopAlgs.join(' '))}`);
|
|
83
|
+
return `${opts.scheme ?? 'Bearer'}${parts.length ? ` ${parts.join(', ')}` : ''}`;
|
|
84
|
+
}
|
|
85
|
+
async function sha256b64u(input) {
|
|
86
|
+
const digest = new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input)));
|
|
87
|
+
let bin = '';
|
|
88
|
+
for (const b of digest)
|
|
89
|
+
bin += String.fromCharCode(b);
|
|
90
|
+
return btoa(bin).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
91
|
+
}
|
|
92
|
+
/** Strip query + fragment (RFC 9449 §4.3 `htu` comparison). */
|
|
93
|
+
function htuOf(url) {
|
|
94
|
+
try {
|
|
95
|
+
const u = new URL(url);
|
|
96
|
+
return `${u.protocol}//${u.host}${u.pathname}`;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A reusable verifier (one JWKS cache for the life of the process). Call it per
|
|
104
|
+
* request; it never throws for a bad token — it returns the status + challenge.
|
|
105
|
+
*/
|
|
106
|
+
function createAccessTokenVerifier(options) {
|
|
107
|
+
if (!options.issuer)
|
|
108
|
+
throw new Error('createAccessTokenVerifier needs `issuer`.');
|
|
109
|
+
if (options.jwks && options.jwksUrl)
|
|
110
|
+
throw new Error('Pass `jwks` or `jwksUrl`, not both.');
|
|
111
|
+
const issuer = options.issuer.replace(/\/+$/, '');
|
|
112
|
+
const now = () => (options.now ?? Date.now)();
|
|
113
|
+
const jwks = new jwks_cache_1.JwksCache({
|
|
114
|
+
url: options.jwks ? undefined : (options.jwksUrl ?? `${issuer}/.well-known/jwks.json`),
|
|
115
|
+
staticJwks: options.jwks,
|
|
116
|
+
fetchImpl: options.fetchImpl,
|
|
117
|
+
now: options.now,
|
|
118
|
+
});
|
|
119
|
+
const audiences = options.audience === false ? null : typeof options.audience === 'string' ? [options.audience] : [...options.audience];
|
|
120
|
+
const replay = options.dpopReplayStore ?? memoryDpopReplayStore();
|
|
121
|
+
return async (request, extra) => {
|
|
122
|
+
const required = [...(options.requiredScopes ?? []), ...(extra?.requiredScopes ?? [])];
|
|
123
|
+
const scheme = options.requireDpop ? 'DPoP' : 'Bearer';
|
|
124
|
+
const fail = (status, error, description, challengeScheme = scheme) => ({
|
|
125
|
+
ok: false,
|
|
126
|
+
status,
|
|
127
|
+
error,
|
|
128
|
+
description,
|
|
129
|
+
wwwAuthenticate: buildWwwAuthenticate({
|
|
130
|
+
scheme: challengeScheme,
|
|
131
|
+
realm: options.realm,
|
|
132
|
+
error,
|
|
133
|
+
description,
|
|
134
|
+
scope: error === 'insufficient_scope' || error === null ? required : undefined,
|
|
135
|
+
resourceMetadataUrl: options.resourceMetadataUrl,
|
|
136
|
+
dpopAlgs: DPOP_ALGS,
|
|
137
|
+
}),
|
|
138
|
+
});
|
|
139
|
+
const authz = header(request, 'authorization');
|
|
140
|
+
if (!authz)
|
|
141
|
+
return fail(401, null, 'Authentication required.');
|
|
142
|
+
const m = /^(Bearer|DPoP)\s+([A-Za-z0-9\-._~+/]+=*)$/i.exec(authz.trim());
|
|
143
|
+
if (!m)
|
|
144
|
+
return fail(400, 'invalid_request', 'Malformed Authorization header.');
|
|
145
|
+
const presentedScheme = m[1].toLowerCase() === 'dpop' ? 'DPoP' : 'Bearer';
|
|
146
|
+
const token = m[2];
|
|
147
|
+
if (token.split('.').length !== 3)
|
|
148
|
+
return fail(401, 'invalid_token', 'The access token is malformed.');
|
|
149
|
+
const keys = await jwks.get((0, jwks_cache_1.readKid)(token));
|
|
150
|
+
if (!keys || keys.keys.length === 0)
|
|
151
|
+
return fail(401, 'invalid_token', 'No signing keys are available to verify the token.');
|
|
152
|
+
let claims;
|
|
153
|
+
try {
|
|
154
|
+
const { payload } = await (0, jose_1.jwtVerify)(token, (0, jose_1.createLocalJWKSet)(keys), {
|
|
155
|
+
issuer,
|
|
156
|
+
algorithms: algs_1.ATLAS_SIGNING_ALGS,
|
|
157
|
+
clockTolerance: exports.ACCESS_TOKEN_CLOCK_SKEW_SECONDS,
|
|
158
|
+
currentDate: new Date(now()),
|
|
159
|
+
});
|
|
160
|
+
claims = payload;
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
return fail(401, 'invalid_token', 'The access token is invalid or expired.');
|
|
164
|
+
}
|
|
165
|
+
if (claims.token_use !== undefined && claims.token_use !== 'access_token') {
|
|
166
|
+
return fail(401, 'invalid_token', 'The token is not an access token.');
|
|
167
|
+
}
|
|
168
|
+
if (audiences) {
|
|
169
|
+
const aud = claims.aud === undefined ? [] : Array.isArray(claims.aud) ? claims.aud : [claims.aud];
|
|
170
|
+
if (!aud.some((a) => audiences.includes(a))) {
|
|
171
|
+
return fail(401, 'invalid_token', 'The access token was not issued for this resource.');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Sender constraint (RFC 9449). A bound token is only ever a DPoP token.
|
|
175
|
+
const jkt = claims.cnf?.jkt;
|
|
176
|
+
if (jkt || options.requireDpop || presentedScheme === 'DPoP') {
|
|
177
|
+
if (!jkt)
|
|
178
|
+
return fail(401, 'invalid_token', 'This resource requires a DPoP-bound access token.', 'DPoP');
|
|
179
|
+
if (presentedScheme !== 'DPoP') {
|
|
180
|
+
return fail(401, 'invalid_token', 'A DPoP-bound access token must be sent with the DPoP scheme.', 'DPoP');
|
|
181
|
+
}
|
|
182
|
+
const proof = header(request, 'dpop');
|
|
183
|
+
if (!proof)
|
|
184
|
+
return fail(401, 'invalid_dpop_proof', 'A DPoP proof is required.', 'DPoP');
|
|
185
|
+
const proofError = await checkDpopProof(proof, {
|
|
186
|
+
token,
|
|
187
|
+
jkt,
|
|
188
|
+
method: (request.method ?? 'GET').toUpperCase(),
|
|
189
|
+
url: request.url ?? '',
|
|
190
|
+
publicOrigin: options.publicOrigin,
|
|
191
|
+
now: now(),
|
|
192
|
+
replay,
|
|
193
|
+
});
|
|
194
|
+
if (proofError)
|
|
195
|
+
return fail(401, 'invalid_dpop_proof', proofError, 'DPoP');
|
|
196
|
+
}
|
|
197
|
+
const scopes = (claims.scope ?? '').split(' ').filter(Boolean);
|
|
198
|
+
const granted = new Set([...scopes, ...(claims.permissions ?? [])]);
|
|
199
|
+
const missing = required.filter((s) => !granted.has(s));
|
|
200
|
+
if (missing.length > 0) {
|
|
201
|
+
return fail(403, 'insufficient_scope', `The access token is missing the required scope(s): ${missing.join(' ')}.`);
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
ok: true,
|
|
205
|
+
claims,
|
|
206
|
+
scopes,
|
|
207
|
+
subject: claims.sub,
|
|
208
|
+
clientId: (claims.client_id ?? claims.azp ?? null),
|
|
209
|
+
dpopBound: !!jkt,
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
async function checkDpopProof(proof, ctx) {
|
|
214
|
+
let jwk;
|
|
215
|
+
let alg;
|
|
216
|
+
try {
|
|
217
|
+
const h = (0, jose_1.decodeProtectedHeader)(proof);
|
|
218
|
+
if (h.typ !== 'dpop+jwt')
|
|
219
|
+
return 'The DPoP proof must have typ dpop+jwt.';
|
|
220
|
+
if (!h.alg || !DPOP_ALGS.includes(h.alg))
|
|
221
|
+
return 'The DPoP proof uses an unsupported algorithm.';
|
|
222
|
+
if (!h.jwk || typeof h.jwk !== 'object')
|
|
223
|
+
return 'The DPoP proof must carry its public key.';
|
|
224
|
+
jwk = h.jwk;
|
|
225
|
+
if ('d' in jwk || 'k' in jwk)
|
|
226
|
+
return 'The DPoP proof key must be a public key.';
|
|
227
|
+
alg = h.alg;
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
return 'The DPoP proof is malformed.';
|
|
231
|
+
}
|
|
232
|
+
let payload;
|
|
233
|
+
try {
|
|
234
|
+
const key = await (0, jose_1.importJWK)(jwk, alg);
|
|
235
|
+
({ payload } = await (0, jose_1.jwtVerify)(proof, key, { algorithms: [alg], typ: 'dpop+jwt', currentDate: new Date(ctx.now) }));
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
return 'The DPoP proof signature is invalid.';
|
|
239
|
+
}
|
|
240
|
+
if ((await (0, jose_1.calculateJwkThumbprint)(jwk, 'sha256')) !== ctx.jkt) {
|
|
241
|
+
return 'The DPoP proof key does not match the token binding.';
|
|
242
|
+
}
|
|
243
|
+
if (payload.htm !== ctx.method)
|
|
244
|
+
return 'The DPoP proof htm does not match the request method.';
|
|
245
|
+
const absolute = /^https?:\/\//i.test(ctx.url) ? ctx.url : ctx.publicOrigin ? new URL(ctx.url, ctx.publicOrigin).toString() : null;
|
|
246
|
+
const expected = absolute ? htuOf(absolute) : null;
|
|
247
|
+
if (!expected || typeof payload.htu !== 'string' || htuOf(payload.htu) !== expected) {
|
|
248
|
+
return 'The DPoP proof htu does not match the request URL.';
|
|
249
|
+
}
|
|
250
|
+
const iat = typeof payload.iat === 'number' ? payload.iat * 1000 : NaN;
|
|
251
|
+
if (!Number.isFinite(iat) ||
|
|
252
|
+
iat > ctx.now + exports.ACCESS_TOKEN_CLOCK_SKEW_SECONDS * 1000 ||
|
|
253
|
+
ctx.now - iat > exports.DPOP_PROOF_MAX_AGE_SECONDS * 1000) {
|
|
254
|
+
return 'The DPoP proof is too old or from the future.';
|
|
255
|
+
}
|
|
256
|
+
if (payload.ath !== (await sha256b64u(ctx.token)))
|
|
257
|
+
return 'The DPoP proof ath does not match the access token.';
|
|
258
|
+
if (typeof payload.jti !== 'string' || !payload.jti)
|
|
259
|
+
return 'The DPoP proof needs a jti.';
|
|
260
|
+
if (!(await ctx.replay.claim(`${ctx.jkt}:${payload.jti}`, iat + exports.DPOP_PROOF_MAX_AGE_SECONDS * 1000))) {
|
|
261
|
+
return 'The DPoP proof has already been used.';
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
/** One-shot form of {@link createAccessTokenVerifier} (builds a fresh JWKS cache each call — prefer the factory). */
|
|
266
|
+
function verifyAccessToken(request, options) {
|
|
267
|
+
return createAccessTokenVerifier(options)(request);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* The RFC 9728 protected-resource metadata document for your API. Serve it as
|
|
271
|
+
* JSON at `https://<your api host>/.well-known/oauth-protected-resource` (and,
|
|
272
|
+
* for a resource with a path, at `/.well-known/oauth-protected-resource<path>`),
|
|
273
|
+
* and point `resourceMetadataUrl` at it. Atlas can also serve this document for
|
|
274
|
+
* you when the API is registered with metadata publishing turned on.
|
|
275
|
+
*/
|
|
276
|
+
function protectedResourceMetadata(opts) {
|
|
277
|
+
return {
|
|
278
|
+
resource: opts.resource,
|
|
279
|
+
authorization_servers: [opts.issuer.replace(/\/+$/, '')],
|
|
280
|
+
bearer_methods_supported: ['header'],
|
|
281
|
+
...(opts.scopesSupported ? { scopes_supported: [...opts.scopesSupported] } : {}),
|
|
282
|
+
...(opts.resourceName ? { resource_name: opts.resourceName } : {}),
|
|
283
|
+
...(opts.resourceDocumentation ? { resource_documentation: opts.resourceDocumentation } : {}),
|
|
284
|
+
dpop_signing_alg_values_supported: DPOP_ALGS,
|
|
285
|
+
...(opts.dpopBoundAccessTokensRequired ? { dpop_bound_access_tokens_required: true } : {}),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
/** The RFC 9728 well-known path for a resource identifier (path-inserted form). */
|
|
289
|
+
function protectedResourceMetadataPath(resource) {
|
|
290
|
+
const u = new URL(resource);
|
|
291
|
+
const path = u.pathname === '/' ? '' : u.pathname.replace(/\/+$/, '');
|
|
292
|
+
return `/.well-known/oauth-protected-resource${path}`;
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=oauth-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-resource.js","sourceRoot":"","sources":["../src/oauth-resource.ts"],"names":[],"mappings":"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"}
|
package/dist/oidc.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { type JWTPayload } from 'jose';
|
|
|
20
20
|
* minute so a burst of callbacks cannot become an outbound request flood),
|
|
21
21
|
* the code exchange with the client's authentication method, and the JWKS
|
|
22
22
|
* (the package's rate-limited kid-miss cache).
|
|
23
|
-
* - ID-token verification with the algorithm PINNED to RS256 (so `alg: none`
|
|
23
|
+
* - ID-token verification with the algorithm PINNED to RS256 or ES256 (so `alg: none`
|
|
24
24
|
* and HS* confusion are refused), `iss` exact, `aud` containing the client id
|
|
25
25
|
* (and `azp` equal to it when there are several audiences or an `azp` at all),
|
|
26
26
|
* `nonce` equal to the cookie's, `exp`/`iat` with a small tolerance, and
|
package/dist/oidc.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.resetOidcCaches = resetOidcCaches;
|
|
|
10
10
|
const jose_1 = require("jose");
|
|
11
11
|
const handshake_1 = require("./handshake");
|
|
12
12
|
const jwks_cache_1 = require("./jwks-cache");
|
|
13
|
+
const algs_1 = require("./algs");
|
|
13
14
|
class AtlasOidcError extends Error {
|
|
14
15
|
code;
|
|
15
16
|
/** The OAuth `error` value from the authorization or token endpoint, when there was one. */
|
|
@@ -247,8 +248,9 @@ async function verifyIdToken(idToken, discovery, opts) {
|
|
|
247
248
|
if (!header)
|
|
248
249
|
throw invalid('it is not a JWT');
|
|
249
250
|
// Pinned before any key lookup, so `none` and HS* never get near a key.
|
|
250
|
-
if (header.alg !== '
|
|
251
|
-
throw invalid(`its algorithm is ${String(header.alg)}, not RS256`);
|
|
251
|
+
if (typeof header.alg !== 'string' || !algs_1.ATLAS_SIGNING_ALGS.includes(header.alg)) {
|
|
252
|
+
throw invalid(`its algorithm is ${String(header.alg)}, not RS256 or ES256`);
|
|
253
|
+
}
|
|
252
254
|
const keys = await jwksFor(discovery.jwks_uri, opts).get(typeof header.kid === 'string' ? header.kid : undefined);
|
|
253
255
|
if (!keys || keys.keys.length === 0) {
|
|
254
256
|
throw new AtlasOidcError('discovery_failed', `The issuer's signing keys could not be fetched from ${discovery.jwks_uri}.`);
|
|
@@ -256,7 +258,7 @@ async function verifyIdToken(idToken, discovery, opts) {
|
|
|
256
258
|
let payload;
|
|
257
259
|
try {
|
|
258
260
|
({ payload } = await (0, jose_1.jwtVerify)(idToken, (0, jose_1.createLocalJWKSet)(keys), {
|
|
259
|
-
algorithms:
|
|
261
|
+
algorithms: algs_1.ATLAS_SIGNING_ALGS,
|
|
260
262
|
issuer: discovery.issuer,
|
|
261
263
|
audience: opts.clientId,
|
|
262
264
|
clockTolerance: opts.clockToleranceSec,
|