@atlasauth/backend 0.1.1 → 0.1.3

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/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export * from './jwks-cache';
2
2
  export * from './verify';
3
3
  export * from './handshake';
4
+ export * from './webhooks';
4
5
  export { createAtlasClient } from './client';
5
6
  export type { AtlasClient } from './client';
6
7
  export * from './client';
8
+ export { createTestIssuer } from './testing';
9
+ export type { TestIssuer, CreateTestIssuerOptions } from './testing';
package/dist/index.js CHANGED
@@ -14,13 +14,20 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.createAtlasClient = void 0;
17
+ exports.createTestIssuer = exports.createAtlasClient = void 0;
18
18
  // §7.3 token verification — the original surface, unchanged.
19
19
  __exportStar(require("./jwks-cache"), exports);
20
20
  __exportStar(require("./verify"), exports);
21
21
  __exportStar(require("./handshake"), exports);
22
+ // §12.2 inbound webhook verification for consumers.
23
+ __exportStar(require("./webhooks"), exports);
22
24
  // The typed management client for the secret-key Backend API.
23
25
  var client_1 = require("./client");
24
26
  Object.defineProperty(exports, "createAtlasClient", { enumerable: true, get: function () { return client_1.createAtlasClient; } });
25
27
  __exportStar(require("./client"), exports);
28
+ // §1.3(c) dev/test tooling — offline fixtures for verifying Atlas-minted
29
+ // session JWTs with no network call (Clerk's `@clerk/testing` equivalent).
30
+ // Its own module, so it never sits on the hot verification path.
31
+ var testing_1 = require("./testing");
32
+ Object.defineProperty(exports, "createTestIssuer", { enumerable: true, get: function () { return testing_1.createTestIssuer; } });
26
33
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,2CAAyB;AACzB,8CAA4B;AAE5B,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,6DAA6D;AAC7D,+CAA6B;AAC7B,2CAAyB;AACzB,8CAA4B;AAE5B,oDAAoD;AACpD,6CAA2B;AAE3B,8DAA8D;AAC9D,mCAA6C;AAApC,2GAAA,iBAAiB,OAAA;AAE1B,2CAAyB;AAEzB,yEAAyE;AACzE,2EAA2E;AAC3E,iEAAiE;AACjE,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA"}
@@ -25,7 +25,15 @@ export interface Jwks {
25
25
  }>;
26
26
  }
27
27
  export interface JwksCacheDeps {
28
- url: string;
28
+ /** The instance's JWKS URL. Optional only when `staticJwks` is supplied. */
29
+ url?: string;
30
+ /**
31
+ * A fixed, in-memory key set. When present the cache serves it directly and
32
+ * NEVER calls `fetch` — the offline path a customer's CI uses to verify
33
+ * Atlas-minted test tokens (§1.3c). Mutually exclusive with `url` in practice;
34
+ * when both are given the static set wins and no network call is ever made.
35
+ */
36
+ staticJwks?: Jwks;
29
37
  fetchImpl?: typeof fetch;
30
38
  now?: () => number;
31
39
  ttlMs?: number;
@@ -52,6 +52,23 @@ class JwksCache {
52
52
  * brand-new key fail, and those are a minute old at most.
53
53
  */
54
54
  async get(kid) {
55
+ /**
56
+ * The static path. When a fixed key set was supplied there is nothing to
57
+ * fetch, refetch or throttle: the keys never rotate for the life of the
58
+ * process, so every `get` — hit or `kid` miss — is answered from the set
59
+ * with no outbound request. This is what makes verification hermetic.
60
+ */
61
+ if (this.deps.staticJwks) {
62
+ this.lastOutcome = 'cached';
63
+ return this.deps.staticJwks;
64
+ }
65
+ if (this.deps.url === undefined) {
66
+ // Neither a URL nor a static set: nothing to verify against. Report
67
+ // "no keys" rather than attempting `fetch(undefined)`.
68
+ this.lastOutcome = 'failed';
69
+ return null;
70
+ }
71
+ const url = this.deps.url;
55
72
  const now = this.now;
56
73
  const ttl = this.deps.ttlMs ?? exports.DEFAULT_TTL_MS;
57
74
  const interval = this.deps.refetchIntervalMs ?? exports.REFETCH_INTERVAL_MS;
@@ -72,7 +89,7 @@ class JwksCache {
72
89
  }
73
90
  this.lastAttemptAt = now;
74
91
  try {
75
- const response = await (this.deps.fetchImpl ?? fetch)(this.deps.url, {
92
+ const response = await (this.deps.fetchImpl ?? fetch)(url, {
76
93
  headers: { accept: 'application/json' },
77
94
  });
78
95
  if (!response.ok)
@@ -1 +1 @@
1
- {"version":3,"file":"jwks-cache.js","sourceRoot":"","sources":["../src/jwks-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jwks-cache.js","sourceRoot":"","sources":["../src/jwks-cache.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAkIH,0BAWC;AA3ID,wEAAwE;AAC3D,QAAA,mBAAmB,GAAG,MAAM,CAAC;AAE1C,+EAA+E;AAClE,QAAA,cAAc,GAAG,SAAS,CAAC;AAwBxC,MAAa,SAAS;IAOS;IANrB,MAAM,GAAgB,IAAI,CAAC;IAC3B,SAAS,GAAG,CAAC,CAAC;IACd,aAAa,GAAG,CAAC,CAAC;IAC1B,kEAAkE;IAClE,WAAW,GAAiB,OAAO,CAAC;IAEpC,YAA6B,IAAmB;QAAnB,SAAI,GAAJ,IAAI,CAAe;IAAG,CAAC;IAEpD,IAAY,GAAG;QACb,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC,CAAC;IAEO,GAAG,CAAC,GAAuB;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC/B,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IACzD,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,GAAG,CAAC,GAAY;QACpB;;;;;WAKG;QACH,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;YAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;QAC9B,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAChC,oEAAoE;YACpE,uDAAuD;YACvD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,sBAAc,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,iBAAiB,IAAI,2BAAmB,CAAC;QAEpE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;QAC5D,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEvD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;YAC5B,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED;;;;WAIG;QACH,IAAI,OAAO,IAAI,CAAC,OAAO,IAAI,GAAG,GAAG,IAAI,CAAC,aAAa,GAAG,QAAQ,EAAE,CAAC;YAC/D,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC/B,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC;QAEzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE;gBACzD,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;aACxC,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;YAE5E,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAS,CAAC;YAC7C,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAE7E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC;YACnD,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;YACvE,mDAAmD;YACnD,IAAI,CAAC,WAAW,GAAG,QAAQ,CAAC;YAC5B,OAAO,IAAI,CAAC,MAAM,CAAC;QACrB,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,QAAQ;QACN,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;IAC5E,CAAC;CACF;AAjGD,8BAiGC;AAED,mEAAmE;AACnE,SAAgB,OAAO,CAAC,GAAW;IACjC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CACjE,CAAC;QACtB,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { type KeyLike } from 'jose';
2
+ import type { Jwks } from './jwks-cache';
3
+ import type { SessionClaims } from './verify';
4
+ /**
5
+ * §1.3(c) hermetic test fixtures.
6
+ *
7
+ * A customer's CI must be able to prove its `@atlasauth/backend` verification
8
+ * works — accepts a good session token, rejects a bad one — WITHOUT reaching a
9
+ * live Atlas instance or its JWKS URL. So this module mints tokens with an
10
+ * ephemeral RS256 keypair it generates on the spot and hands back that key's
11
+ * public JWKS. Feed the JWKS to `new AtlasBackend({ jwks, issuer })` and the
12
+ * whole round trip — mint, sign, verify — happens in-process, offline.
13
+ *
14
+ * This is dev/test tooling shaped like Clerk's `@clerk/testing`: it lives in
15
+ * its own module (imported only by tests that want it, never by the hot
16
+ * verification path) and leans on `jose`, which the package already ships.
17
+ */
18
+ /** Options for {@link createTestIssuer}. All optional — the defaults are usable as-is. */
19
+ export interface CreateTestIssuerOptions {
20
+ /** The `iss` the fixture stamps on every token. Defaults to a local test URL. */
21
+ issuer?: string;
22
+ /** The `kid` on the signing key and in the published JWKS. */
23
+ kid?: string;
24
+ /**
25
+ * A clock, in epoch milliseconds, for `iat`/`exp`. Pass the SAME `now` you
26
+ * give `AtlasBackend` to make time deterministic across mint and verify.
27
+ */
28
+ now?: () => number;
29
+ /** Default token lifetime in seconds, matching Atlas's 60 s default. */
30
+ ttlSeconds?: number;
31
+ }
32
+ /** A fixture issuer: an in-memory keypair, its public JWKS, and a token minter. */
33
+ export interface TestIssuer {
34
+ /** The `iss` this fixture stamps — pass it straight to `AtlasBackend({ issuer })`. */
35
+ issuer: string;
36
+ /** The public JSON Web Key Set — pass it to `AtlasBackend({ jwks })` for offline verify. */
37
+ jwks: Jwks;
38
+ /** The `kid` shared by the signing key and the JWKS entry. */
39
+ kid: string;
40
+ /** The private signing key, for tests that need to sign something by hand. */
41
+ privateKey: KeyLike;
42
+ /**
43
+ * Mint a signed session JWT. Defaults produce a token this fixture's JWKS
44
+ * verifies as a first-party session (`token_use:'session'`, valid `iss`,
45
+ * `sub`, `sid`, `azp`, `iat`/`exp`). Any field in `claims` overrides a
46
+ * default — set `iss` to forge a wrong-issuer token, `exp` to forge an
47
+ * expired one, add `org_id`/`org_permissions` to exercise authorization.
48
+ */
49
+ mintSession(claims?: Partial<SessionClaims>): Promise<string>;
50
+ }
51
+ /**
52
+ * Build an offline test issuer. Generates an RS256 keypair, exposes its public
53
+ * JWKS, and returns a `mintSession` that signs tokens with the private half.
54
+ *
55
+ * ```ts
56
+ * const fx = await createTestIssuer();
57
+ * const atlas = new AtlasBackend({ jwks: fx.jwks, issuer: fx.issuer });
58
+ * const r = await atlas.verify(await fx.mintSession({ sub: 'user_x' }));
59
+ * // r.ok === true — no network call was made.
60
+ * ```
61
+ */
62
+ export declare function createTestIssuer(options?: CreateTestIssuerOptions): Promise<TestIssuer>;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTestIssuer = createTestIssuer;
4
+ const jose_1 = require("jose");
5
+ const DEFAULT_ISSUER = 'https://test-instance.fapi.atlas.local';
6
+ const DEFAULT_KID = 'atlas-test-key-1';
7
+ const DEFAULT_TTL_SECONDS = 60;
8
+ /**
9
+ * Build an offline test issuer. Generates an RS256 keypair, exposes its public
10
+ * JWKS, and returns a `mintSession` that signs tokens with the private half.
11
+ *
12
+ * ```ts
13
+ * const fx = await createTestIssuer();
14
+ * const atlas = new AtlasBackend({ jwks: fx.jwks, issuer: fx.issuer });
15
+ * const r = await atlas.verify(await fx.mintSession({ sub: 'user_x' }));
16
+ * // r.ok === true — no network call was made.
17
+ * ```
18
+ */
19
+ async function createTestIssuer(options = {}) {
20
+ const issuer = options.issuer ?? DEFAULT_ISSUER;
21
+ const kid = options.kid ?? DEFAULT_KID;
22
+ const ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;
23
+ const clock = options.now ?? Date.now;
24
+ const { privateKey, publicKey } = await (0, jose_1.generateKeyPair)('RS256');
25
+ // The published key: the public half plus the `kid`/`alg`/`use` a JWKS
26
+ // consumer keys on — the same shape Atlas serves at `/.well-known/jwks.json`.
27
+ const publicJwk = { ...(await (0, jose_1.exportJWK)(publicKey)), kid, alg: 'RS256', use: 'sig' };
28
+ const jwks = { keys: [publicJwk] };
29
+ async function mintSession(claims = {}) {
30
+ const nowSeconds = Math.floor(clock() / 1000);
31
+ // System defaults first, caller overrides last — so `mintSession({ iss })`
32
+ // or `mintSession({ exp })` forges exactly the token a rejection test needs.
33
+ const payload = {
34
+ iss: issuer,
35
+ sub: 'user_test',
36
+ sid: 'sess_test',
37
+ azp: issuer,
38
+ sv: 1,
39
+ mfa: false,
40
+ // The §13.1 marker the SDK's requireSessionToken path accepts. A fixture
41
+ // token is a session token, never an OP access/id token.
42
+ token_use: 'session',
43
+ iat: nowSeconds,
44
+ exp: nowSeconds + ttlSeconds,
45
+ ...claims,
46
+ };
47
+ return new jose_1.SignJWT(payload).setProtectedHeader({ alg: 'RS256', kid }).sign(privateKey);
48
+ }
49
+ return { issuer, jwks, kid, privateKey, mintSession };
50
+ }
51
+ //# sourceMappingURL=testing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":";;AAqEA,4CAqCC;AA1GD,+BAAyE;AAsDzE,MAAM,cAAc,GAAG,wCAAwC,CAAC;AAChE,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B;;;;;;;;;;GAUG;AACI,KAAK,UAAU,gBAAgB,CACpC,UAAmC,EAAE;IAErC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC;IACvC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAEtC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,IAAA,sBAAe,EAAC,OAAO,CAAC,CAAC;IACjE,uEAAuE;IACvE,8EAA8E;IAC9E,MAAM,SAAS,GAAG,EAAE,GAAG,CAAC,MAAM,IAAA,gBAAS,EAAC,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;IACrF,MAAM,IAAI,GAAS,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;IAEzC,KAAK,UAAU,WAAW,CAAC,SAAiC,EAAE;QAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC;QAC9C,2EAA2E;QAC3E,6EAA6E;QAC7E,MAAM,OAAO,GAA4B;YACvC,GAAG,EAAE,MAAM;YACX,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,WAAW;YAChB,GAAG,EAAE,MAAM;YACX,EAAE,EAAE,CAAC;YACL,GAAG,EAAE,KAAK;YACV,yEAAyE;YACzE,yDAAyD;YACzD,SAAS,EAAE,SAAS;YACpB,GAAG,EAAE,UAAU;YACf,GAAG,EAAE,UAAU,GAAG,UAAU;YAC5B,GAAG,MAAM;SACV,CAAC;QAEF,OAAO,IAAI,cAAO,CAAC,OAAO,CAAC,CAAC,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzF,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AACxD,CAAC"}
package/dist/verify.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type ProtectCondition } from '@atlasauth/authz';
2
+ import { type Jwks } from './jwks-cache';
2
3
  export { type AuthzClaims, type ProtectCondition, type ProtectOutcome, type ProtectReason, evaluate, hasFromClaims, protectFromClaims, ForbiddenError, isRoleKey, isPermissionKey, } from '@atlasauth/authz';
3
4
  /**
4
5
  * §7.3 verification by customer backends.
@@ -93,8 +94,21 @@ export type VerifyResult = AuthorizedSession | {
93
94
  reason: 'malformed' | 'invalid' | 'no_keys' | 'unauthorized_party';
94
95
  };
95
96
  export interface AtlasBackendOptions {
96
- /** The instance's JWKS URL. */
97
- jwksUrl: string;
97
+ /**
98
+ * The instance's JWKS URL. Provide exactly one of `jwksUrl` or `jwks`: with a
99
+ * URL, keys are fetched and cached (the production default); with a static
100
+ * `jwks`, verification is fully offline.
101
+ */
102
+ jwksUrl?: string;
103
+ /**
104
+ * A static JSON Web Key Set to verify against, INSTEAD of fetching from a URL.
105
+ * When set, verification makes NO network call — the hermetic path a
106
+ * customer's CI uses to validate Atlas-minted test session JWTs (§1.3c). The
107
+ * `@atlasauth/backend/testing` `createTestIssuer()` helper produces a matching
108
+ * `{ jwks }`. Signature, issuer, `token_use` and `azp` checks are unchanged;
109
+ * only where the keys come from differs. Mutually exclusive with `jwksUrl`.
110
+ */
111
+ jwks?: Jwks;
98
112
  /** Expected `iss`. Required — an unchecked issuer accepts any Atlas instance. */
99
113
  issuer: string;
100
114
  /**
package/dist/verify.js CHANGED
@@ -60,8 +60,17 @@ class AtlasBackend {
60
60
  jwks;
61
61
  constructor(options) {
62
62
  this.options = options;
63
+ // Exactly one key source. Two would be ambiguous (which wins?), and zero
64
+ // leaves nothing to verify against — either is a configuration error worth
65
+ // failing loudly on rather than silently accepting or rejecting every token.
66
+ const hasUrl = typeof options.jwksUrl === 'string' && options.jwksUrl.length > 0;
67
+ const hasStatic = options.jwks !== undefined;
68
+ if (hasUrl === hasStatic) {
69
+ throw new Error('AtlasBackend needs exactly one key source: pass `jwksUrl` (fetch from the instance) OR `jwks` (a static key set for offline verification), not both and not neither.');
70
+ }
63
71
  this.jwks = new jwks_cache_1.JwksCache({
64
72
  url: options.jwksUrl,
73
+ staticJwks: options.jwks,
65
74
  fetchImpl: options.fetchImpl,
66
75
  now: options.now,
67
76
  });
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /** Header names Atlas sends on every delivery (lower-case; match case-insensitively). */
2
+ export declare const ATLAS_WEBHOOK_HEADERS: {
3
+ readonly id: "atlas-id";
4
+ readonly timestamp: "atlas-timestamp";
5
+ readonly signature: "atlas-signature";
6
+ };
7
+ export type WebhookVerifyFailure = 'missing_headers' | 'malformed_signature' | 'stale_timestamp' | 'signature_mismatch';
8
+ export interface WebhookVerifyResult<T = unknown> {
9
+ /** True only when the signature and timestamp both check out. */
10
+ verified: boolean;
11
+ /** Why verification failed, when it did. */
12
+ reason?: WebhookVerifyFailure;
13
+ /** The parsed event envelope `{ id, type, timestamp, instance_id, data }` — present only when `verified`. */
14
+ event?: T;
15
+ }
16
+ type HeadersLike = Headers | Record<string, string | string[] | undefined>;
17
+ export interface VerifyWebhookInput {
18
+ /** The RAW request body as received — a string or Buffer, NOT a parsed object. */
19
+ body: string | Buffer;
20
+ /** The request headers (a plain object, Node `req.headers`, or a Fetch `Headers`). */
21
+ headers: HeadersLike;
22
+ /** The endpoint's signing secret (shown once when the endpoint was created/rotated). */
23
+ secret: string;
24
+ /** Override "now" (tests); defaults to the current time. */
25
+ now?: Date;
26
+ /** Override the ±replay tolerance (defaults to 5 minutes). */
27
+ toleranceMs?: number;
28
+ }
29
+ /**
30
+ * Verify and parse an Atlas webhook. Returns `{ verified, reason?, event? }` —
31
+ * it never throws on a bad signature (a thrown verifier is easy to accidentally
32
+ * swallow). On success, `event` is the parsed envelope.
33
+ *
34
+ * ```ts
35
+ * // Express (raw body):
36
+ * app.post('/webhooks/atlas', express.raw({ type: 'application/json' }), (req, res) => {
37
+ * const { verified, event } = verifyWebhook({ body: req.body, headers: req.headers, secret });
38
+ * if (!verified) return res.sendStatus(400);
39
+ * // handle event.type ...
40
+ * res.sendStatus(200);
41
+ * });
42
+ * ```
43
+ */
44
+ export declare function verifyWebhook<T = unknown>(input: VerifyWebhookInput): WebhookVerifyResult<T>;
45
+ export {};
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ATLAS_WEBHOOK_HEADERS = void 0;
4
+ exports.verifyWebhook = verifyWebhook;
5
+ const node_crypto_1 = require("node:crypto");
6
+ /**
7
+ * §12.2 — verify an inbound Atlas webhook, for the CUSTOMER consuming events.
8
+ *
9
+ * Atlas signs every delivery: `atlas-signature: v1,<base64>` is HMAC-SHA256 over
10
+ * `<id>.<timestamp>.<rawBody>` keyed with the endpoint secret, with `atlas-id`
11
+ * and `atlas-timestamp` (epoch ms) headers. The timestamp is INSIDE the signed
12
+ * material — a header-only timestamp would let an attacker replay a captured
13
+ * body under a fresh timestamp — and a delivery older than 5 minutes is rejected
14
+ * so a captured request cannot be replayed later.
15
+ *
16
+ * The signing logic is identical to the server's (`@atlas/core` `verifyWebhook`),
17
+ * reimplemented here with zero dependencies so an integrator gets a first-party
18
+ * verifier without pulling in Atlas internals. Verify over the RAW request body,
19
+ * BEFORE any JSON parse — re-serializing reorders keys and breaks the MAC.
20
+ */
21
+ const SIGNATURE_VERSION = 'v1';
22
+ const REPLAY_TOLERANCE_MS = 5 * 60_000;
23
+ /** Header names Atlas sends on every delivery (lower-case; match case-insensitively). */
24
+ exports.ATLAS_WEBHOOK_HEADERS = {
25
+ id: 'atlas-id',
26
+ timestamp: 'atlas-timestamp',
27
+ signature: 'atlas-signature',
28
+ };
29
+ /** Read a header case-insensitively from a plain object or a Fetch `Headers`. */
30
+ function readHeader(headers, name) {
31
+ if (typeof headers.get === 'function') {
32
+ return headers.get(name) ?? undefined;
33
+ }
34
+ const bag = headers;
35
+ const direct = bag[name] ?? bag[name.toLowerCase()];
36
+ const v = Array.isArray(direct) ? direct[0] : direct;
37
+ if (v !== undefined)
38
+ return v;
39
+ // Fall back to a case-insensitive scan (Node lower-cases, but be safe).
40
+ const hit = Object.keys(bag).find((k) => k.toLowerCase() === name);
41
+ const found = hit ? bag[hit] : undefined;
42
+ return Array.isArray(found) ? found[0] : found;
43
+ }
44
+ /**
45
+ * Verify and parse an Atlas webhook. Returns `{ verified, reason?, event? }` —
46
+ * it never throws on a bad signature (a thrown verifier is easy to accidentally
47
+ * swallow). On success, `event` is the parsed envelope.
48
+ *
49
+ * ```ts
50
+ * // Express (raw body):
51
+ * app.post('/webhooks/atlas', express.raw({ type: 'application/json' }), (req, res) => {
52
+ * const { verified, event } = verifyWebhook({ body: req.body, headers: req.headers, secret });
53
+ * if (!verified) return res.sendStatus(400);
54
+ * // handle event.type ...
55
+ * res.sendStatus(200);
56
+ * });
57
+ * ```
58
+ */
59
+ function verifyWebhook(input) {
60
+ const raw = typeof input.body === 'string' ? input.body : input.body.toString('utf8');
61
+ const id = readHeader(input.headers, exports.ATLAS_WEBHOOK_HEADERS.id);
62
+ const timestampRaw = readHeader(input.headers, exports.ATLAS_WEBHOOK_HEADERS.timestamp);
63
+ const signature = readHeader(input.headers, exports.ATLAS_WEBHOOK_HEADERS.signature);
64
+ if (!id || !timestampRaw || !signature)
65
+ return { verified: false, reason: 'missing_headers' };
66
+ const [version, provided] = signature.split(',');
67
+ if (version !== SIGNATURE_VERSION || !provided)
68
+ return { verified: false, reason: 'malformed_signature' };
69
+ const timestamp = Number(timestampRaw);
70
+ const now = (input.now ?? new Date()).getTime();
71
+ const tolerance = input.toleranceMs ?? REPLAY_TOLERANCE_MS;
72
+ // Rejected in both directions: a far-future timestamp is as suspicious as a
73
+ // stale one — accepting it would let an attacker mint a long-lived replay.
74
+ if (!Number.isFinite(timestamp) || Math.abs(now - timestamp) > tolerance) {
75
+ return { verified: false, reason: 'stale_timestamp' };
76
+ }
77
+ const expected = (0, node_crypto_1.createHmac)('sha256', input.secret).update(`${id}.${timestamp}.${raw}`).digest('base64');
78
+ const a = Buffer.from(provided);
79
+ const b = Buffer.from(expected);
80
+ if (a.length !== b.length || !(0, node_crypto_1.timingSafeEqual)(a, b))
81
+ return { verified: false, reason: 'signature_mismatch' };
82
+ try {
83
+ return { verified: true, event: JSON.parse(raw) };
84
+ }
85
+ catch {
86
+ // Signature is valid but the body isn't JSON — surface it as verified with no event.
87
+ return { verified: true };
88
+ }
89
+ }
90
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasauth/backend",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "dependencies": {