@atlasauth/backend 0.1.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.
Files changed (157) hide show
  1. package/dist/client/actions.d.ts +86 -0
  2. package/dist/client/actions.js +40 -0
  3. package/dist/client/actions.js.map +1 -0
  4. package/dist/client/actor-tokens.d.ts +28 -0
  5. package/dist/client/actor-tokens.js +15 -0
  6. package/dist/client/actor-tokens.js.map +1 -0
  7. package/dist/client/api-keys.d.ts +77 -0
  8. package/dist/client/api-keys.js +31 -0
  9. package/dist/client/api-keys.js.map +1 -0
  10. package/dist/client/attack-protection.d.ts +41 -0
  11. package/dist/client/attack-protection.js +14 -0
  12. package/dist/client/attack-protection.js.map +1 -0
  13. package/dist/client/audit-logs.d.ts +20 -0
  14. package/dist/client/audit-logs.js +11 -0
  15. package/dist/client/audit-logs.js.map +1 -0
  16. package/dist/client/billing-plans.d.ts +81 -0
  17. package/dist/client/billing-plans.js +27 -0
  18. package/dist/client/billing-plans.js.map +1 -0
  19. package/dist/client/bot-signals.d.ts +88 -0
  20. package/dist/client/bot-signals.js +24 -0
  21. package/dist/client/bot-signals.js.map +1 -0
  22. package/dist/client/branding.d.ts +140 -0
  23. package/dist/client/branding.js +19 -0
  24. package/dist/client/branding.js.map +1 -0
  25. package/dist/client/data-subject-requests.d.ts +40 -0
  26. package/dist/client/data-subject-requests.js +32 -0
  27. package/dist/client/data-subject-requests.js.map +1 -0
  28. package/dist/client/domains.d.ts +45 -0
  29. package/dist/client/domains.js +21 -0
  30. package/dist/client/domains.js.map +1 -0
  31. package/dist/client/email-templates.d.ts +51 -0
  32. package/dist/client/email-templates.js +24 -0
  33. package/dist/client/email-templates.js.map +1 -0
  34. package/dist/client/error.d.ts +31 -0
  35. package/dist/client/error.js +28 -0
  36. package/dist/client/error.js.map +1 -0
  37. package/dist/client/fga.d.ts +191 -0
  38. package/dist/client/fga.js +91 -0
  39. package/dist/client/fga.js.map +1 -0
  40. package/dist/client/import-export.d.ts +88 -0
  41. package/dist/client/import-export.js +28 -0
  42. package/dist/client/import-export.js.map +1 -0
  43. package/dist/client/index.d.ts +796 -0
  44. package/dist/client/index.js +174 -0
  45. package/dist/client/index.js.map +1 -0
  46. package/dist/client/instance-security.d.ts +79 -0
  47. package/dist/client/instance-security.js +44 -0
  48. package/dist/client/instance-security.js.map +1 -0
  49. package/dist/client/instance.d.ts +34 -0
  50. package/dist/client/instance.js +14 -0
  51. package/dist/client/instance.js.map +1 -0
  52. package/dist/client/invitations.d.ts +21 -0
  53. package/dist/client/invitations.js +18 -0
  54. package/dist/client/invitations.js.map +1 -0
  55. package/dist/client/jwt-templates.d.ts +26 -0
  56. package/dist/client/jwt-templates.js +26 -0
  57. package/dist/client/jwt-templates.js.map +1 -0
  58. package/dist/client/localizations.d.ts +43 -0
  59. package/dist/client/localizations.js +24 -0
  60. package/dist/client/localizations.js.map +1 -0
  61. package/dist/client/log-streams.d.ts +66 -0
  62. package/dist/client/log-streams.js +28 -0
  63. package/dist/client/log-streams.js.map +1 -0
  64. package/dist/client/lti-platforms.d.ts +49 -0
  65. package/dist/client/lti-platforms.js +24 -0
  66. package/dist/client/lti-platforms.js.map +1 -0
  67. package/dist/client/managed-waf.d.ts +100 -0
  68. package/dist/client/managed-waf.js +33 -0
  69. package/dist/client/managed-waf.js.map +1 -0
  70. package/dist/client/messaging.d.ts +56 -0
  71. package/dist/client/messaging.js +30 -0
  72. package/dist/client/messaging.js.map +1 -0
  73. package/dist/client/network-acls.d.ts +50 -0
  74. package/dist/client/network-acls.js +29 -0
  75. package/dist/client/network-acls.js.map +1 -0
  76. package/dist/client/oauth-clients.d.ts +75 -0
  77. package/dist/client/oauth-clients.js +45 -0
  78. package/dist/client/oauth-clients.js.map +1 -0
  79. package/dist/client/oauth-providers.d.ts +109 -0
  80. package/dist/client/oauth-providers.js +48 -0
  81. package/dist/client/oauth-providers.js.map +1 -0
  82. package/dist/client/organizations.d.ts +211 -0
  83. package/dist/client/organizations.js +136 -0
  84. package/dist/client/organizations.js.map +1 -0
  85. package/dist/client/paginate.d.ts +16 -0
  86. package/dist/client/paginate.js +35 -0
  87. package/dist/client/paginate.js.map +1 -0
  88. package/dist/client/radius-clients.d.ts +52 -0
  89. package/dist/client/radius-clients.js +24 -0
  90. package/dist/client/radius-clients.js.map +1 -0
  91. package/dist/client/rate-limit.d.ts +37 -0
  92. package/dist/client/rate-limit.js +20 -0
  93. package/dist/client/rate-limit.js.map +1 -0
  94. package/dist/client/request.d.ts +52 -0
  95. package/dist/client/request.js +102 -0
  96. package/dist/client/request.js.map +1 -0
  97. package/dist/client/resource-servers.d.ts +44 -0
  98. package/dist/client/resource-servers.js +24 -0
  99. package/dist/client/resource-servers.js.map +1 -0
  100. package/dist/client/restrictions.d.ts +39 -0
  101. package/dist/client/restrictions.js +29 -0
  102. package/dist/client/restrictions.js.map +1 -0
  103. package/dist/client/risk-based-mfa.d.ts +51 -0
  104. package/dist/client/risk-based-mfa.js +20 -0
  105. package/dist/client/risk-based-mfa.js.map +1 -0
  106. package/dist/client/roles.d.ts +84 -0
  107. package/dist/client/roles.js +57 -0
  108. package/dist/client/roles.js.map +1 -0
  109. package/dist/client/scim-provisioning.d.ts +94 -0
  110. package/dist/client/scim-provisioning.js +49 -0
  111. package/dist/client/scim-provisioning.js.map +1 -0
  112. package/dist/client/scim-tokens.d.ts +34 -0
  113. package/dist/client/scim-tokens.js +18 -0
  114. package/dist/client/scim-tokens.js.map +1 -0
  115. package/dist/client/sessions.d.ts +58 -0
  116. package/dist/client/sessions.js +26 -0
  117. package/dist/client/sessions.js.map +1 -0
  118. package/dist/client/sign-in-tokens.d.ts +18 -0
  119. package/dist/client/sign-in-tokens.js +11 -0
  120. package/dist/client/sign-in-tokens.js.map +1 -0
  121. package/dist/client/sms-templates.d.ts +46 -0
  122. package/dist/client/sms-templates.js +30 -0
  123. package/dist/client/sms-templates.js.map +1 -0
  124. package/dist/client/sso-connections.d.ts +76 -0
  125. package/dist/client/sso-connections.js +28 -0
  126. package/dist/client/sso-connections.js.map +1 -0
  127. package/dist/client/sso-onboarding.d.ts +76 -0
  128. package/dist/client/sso-onboarding.js +42 -0
  129. package/dist/client/sso-onboarding.js.map +1 -0
  130. package/dist/client/tokens.d.ts +37 -0
  131. package/dist/client/tokens.js +11 -0
  132. package/dist/client/tokens.js.map +1 -0
  133. package/dist/client/types.d.ts +41 -0
  134. package/dist/client/types.js +10 -0
  135. package/dist/client/types.js.map +1 -0
  136. package/dist/client/users.d.ts +204 -0
  137. package/dist/client/users.js +135 -0
  138. package/dist/client/users.js.map +1 -0
  139. package/dist/client/waitlist.d.ts +31 -0
  140. package/dist/client/waitlist.js +16 -0
  141. package/dist/client/waitlist.js.map +1 -0
  142. package/dist/client/webhooks.d.ts +50 -0
  143. package/dist/client/webhooks.js +24 -0
  144. package/dist/client/webhooks.js.map +1 -0
  145. package/dist/handshake.d.ts +76 -0
  146. package/dist/handshake.js +96 -0
  147. package/dist/handshake.js.map +1 -0
  148. package/dist/index.d.ts +6 -0
  149. package/dist/index.js +26 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/jwks-cache.d.ts +62 -0
  152. package/dist/jwks-cache.js +114 -0
  153. package/dist/jwks-cache.js.map +1 -0
  154. package/dist/verify.d.ts +162 -0
  155. package/dist/verify.js +226 -0
  156. package/dist/verify.js.map +1 -0
  157. package/package.json +26 -0
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.createAtlasClient = void 0;
18
+ // §7.3 token verification — the original surface, unchanged.
19
+ __exportStar(require("./jwks-cache"), exports);
20
+ __exportStar(require("./verify"), exports);
21
+ __exportStar(require("./handshake"), exports);
22
+ // The typed management client for the secret-key Backend API.
23
+ var client_1 = require("./client");
24
+ Object.defineProperty(exports, "createAtlasClient", { enumerable: true, get: function () { return client_1.createAtlasClient; } });
25
+ __exportStar(require("./client"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * §7.3: "JWKS cached in-process with kid-miss refetch (max 1/min) so key
3
+ * rotation needs no deploys."
4
+ *
5
+ * The rate limit on the refetch is the security property, not a politeness.
6
+ * Without it, an attacker sends tokens carrying random `kid` values and every
7
+ * one forces an outbound request to the customer's JWKS endpoint — turning any
8
+ * unauthenticated caller into a traffic amplifier aimed at Atlas, from inside
9
+ * the customer's own infrastructure. The cache's job is as much to refuse to
10
+ * fetch as it is to fetch.
11
+ *
12
+ * The other half of the requirement is that rotation needs no deploy. A key
13
+ * that rotated an hour ago must be picked up automatically, which is exactly
14
+ * what the kid-miss path does — but only for a kid the cache has genuinely not
15
+ * seen, and only once a minute.
16
+ */
17
+ /** §7.3: at most one refetch per minute, however many misses arrive. */
18
+ export declare const REFETCH_INTERVAL_MS = 60000;
19
+ /** §7.3 serves `Cache-Control: max-age=3600`; honoured rather than ignored. */
20
+ export declare const DEFAULT_TTL_MS = 3600000;
21
+ export interface Jwks {
22
+ keys: Array<{
23
+ kid?: string;
24
+ [claim: string]: unknown;
25
+ }>;
26
+ }
27
+ export interface JwksCacheDeps {
28
+ url: string;
29
+ fetchImpl?: typeof fetch;
30
+ now?: () => number;
31
+ ttlMs?: number;
32
+ refetchIntervalMs?: number;
33
+ }
34
+ export type FetchOutcome = 'fresh' | 'cached' | 'refetched' | 'throttled' | 'failed';
35
+ export declare class JwksCache {
36
+ private readonly deps;
37
+ private cached;
38
+ private fetchedAt;
39
+ private lastAttemptAt;
40
+ /** Exposed so a caller can assert the rate limit actually bit. */
41
+ lastOutcome: FetchOutcome;
42
+ constructor(deps: JwksCacheDeps);
43
+ private get now();
44
+ private has;
45
+ /**
46
+ * The JWKS to verify against, refetching if this `kid` is unknown.
47
+ *
48
+ * Returns whatever is cached when a refetch is throttled or fails. That is
49
+ * deliberate: a stale JWKS still verifies every token signed by a key it
50
+ * contains, so degrading to "the keys I already had" keeps the overwhelming
51
+ * majority of requests working through a JWKS outage. Only tokens signed by a
52
+ * brand-new key fail, and those are a minute old at most.
53
+ */
54
+ get(kid?: string): Promise<Jwks | null>;
55
+ /** Test and diagnostic surface — never used for a security decision. */
56
+ snapshot(): {
57
+ keys: number;
58
+ fetchedAt: number;
59
+ };
60
+ }
61
+ /** Read the `kid` from a JWT header without verifying anything. */
62
+ export declare function readKid(jwt: string): string | undefined;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ /**
3
+ * §7.3: "JWKS cached in-process with kid-miss refetch (max 1/min) so key
4
+ * rotation needs no deploys."
5
+ *
6
+ * The rate limit on the refetch is the security property, not a politeness.
7
+ * Without it, an attacker sends tokens carrying random `kid` values and every
8
+ * one forces an outbound request to the customer's JWKS endpoint — turning any
9
+ * unauthenticated caller into a traffic amplifier aimed at Atlas, from inside
10
+ * the customer's own infrastructure. The cache's job is as much to refuse to
11
+ * fetch as it is to fetch.
12
+ *
13
+ * The other half of the requirement is that rotation needs no deploy. A key
14
+ * that rotated an hour ago must be picked up automatically, which is exactly
15
+ * what the kid-miss path does — but only for a kid the cache has genuinely not
16
+ * seen, and only once a minute.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.JwksCache = exports.DEFAULT_TTL_MS = exports.REFETCH_INTERVAL_MS = void 0;
20
+ exports.readKid = readKid;
21
+ /** §7.3: at most one refetch per minute, however many misses arrive. */
22
+ exports.REFETCH_INTERVAL_MS = 60_000;
23
+ /** §7.3 serves `Cache-Control: max-age=3600`; honoured rather than ignored. */
24
+ exports.DEFAULT_TTL_MS = 3_600_000;
25
+ class JwksCache {
26
+ deps;
27
+ cached = null;
28
+ fetchedAt = 0;
29
+ lastAttemptAt = 0;
30
+ /** Exposed so a caller can assert the rate limit actually bit. */
31
+ lastOutcome = 'fresh';
32
+ constructor(deps) {
33
+ this.deps = deps;
34
+ }
35
+ get now() {
36
+ return (this.deps.now ?? Date.now)();
37
+ }
38
+ has(kid) {
39
+ if (!this.cached)
40
+ return false;
41
+ if (!kid)
42
+ return this.cached.keys.length > 0;
43
+ return this.cached.keys.some((key) => key.kid === kid);
44
+ }
45
+ /**
46
+ * The JWKS to verify against, refetching if this `kid` is unknown.
47
+ *
48
+ * Returns whatever is cached when a refetch is throttled or fails. That is
49
+ * deliberate: a stale JWKS still verifies every token signed by a key it
50
+ * contains, so degrading to "the keys I already had" keeps the overwhelming
51
+ * majority of requests working through a JWKS outage. Only tokens signed by a
52
+ * brand-new key fail, and those are a minute old at most.
53
+ */
54
+ async get(kid) {
55
+ const now = this.now;
56
+ const ttl = this.deps.ttlMs ?? exports.DEFAULT_TTL_MS;
57
+ const interval = this.deps.refetchIntervalMs ?? exports.REFETCH_INTERVAL_MS;
58
+ const expired = !this.cached || now - this.fetchedAt >= ttl;
59
+ const kidMiss = Boolean(this.cached) && !this.has(kid);
60
+ if (!expired && !kidMiss) {
61
+ this.lastOutcome = 'cached';
62
+ return this.cached;
63
+ }
64
+ /**
65
+ * The throttle. An attacker sending random kids must not be able to make
66
+ * this process hammer the JWKS endpoint — so a miss inside the window is
67
+ * answered from cache, and the token simply fails to verify.
68
+ */
69
+ if (kidMiss && !expired && now - this.lastAttemptAt < interval) {
70
+ this.lastOutcome = 'throttled';
71
+ return this.cached;
72
+ }
73
+ this.lastAttemptAt = now;
74
+ try {
75
+ const response = await (this.deps.fetchImpl ?? fetch)(this.deps.url, {
76
+ headers: { accept: 'application/json' },
77
+ });
78
+ if (!response.ok)
79
+ throw new Error(`JWKS fetch failed (${response.status})`);
80
+ const body = (await response.json());
81
+ if (!body || !Array.isArray(body.keys))
82
+ throw new Error('JWKS is malformed');
83
+ this.cached = body;
84
+ this.fetchedAt = now;
85
+ this.lastOutcome = kidMiss ? 'refetched' : 'fresh';
86
+ return this.cached;
87
+ }
88
+ catch {
89
+ // Keep serving what we have. A JWKS outage should degrade to "new keys
90
+ // do not work yet", not "nobody can authenticate".
91
+ this.lastOutcome = 'failed';
92
+ return this.cached;
93
+ }
94
+ }
95
+ /** Test and diagnostic surface — never used for a security decision. */
96
+ snapshot() {
97
+ return { keys: this.cached?.keys.length ?? 0, fetchedAt: this.fetchedAt };
98
+ }
99
+ }
100
+ exports.JwksCache = JwksCache;
101
+ /** Read the `kid` from a JWT header without verifying anything. */
102
+ function readKid(jwt) {
103
+ const [header] = jwt.split('.');
104
+ if (!header)
105
+ return undefined;
106
+ try {
107
+ const decoded = JSON.parse(Buffer.from(header.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString('utf8'));
108
+ return typeof decoded.kid === 'string' ? decoded.kid : undefined;
109
+ }
110
+ catch {
111
+ return undefined;
112
+ }
113
+ }
114
+ //# sourceMappingURL=jwks-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwks-cache.js","sourceRoot":"","sources":["../src/jwks-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ import { type ProtectCondition } from '@atlasauth/authz';
2
+ export { type AuthzClaims, type ProtectCondition, type ProtectOutcome, type ProtectReason, evaluate, hasFromClaims, protectFromClaims, ForbiddenError, isRoleKey, isPermissionKey, } from '@atlasauth/authz';
3
+ /**
4
+ * §7.3 verification by customer backends.
5
+ *
6
+ * "verifies signature, exp/nbf with 5 s clock-skew tolerance, iss, and
7
+ * optionally azp against an allowlist."
8
+ *
9
+ * The design constraint that matters is what this does NOT do: it never calls
10
+ * Atlas on the hot path. A customer's API handling ten thousand requests a
11
+ * second cannot make ten thousand outbound calls to verify them, and a verifier
12
+ * that did would make Atlas's availability the customer's availability. So the
13
+ * default path is local, against cached JWKS, and the revocation window is
14
+ * bounded instead by the 60-second token lifetime.
15
+ *
16
+ * `verifyOnline` exists for the cases where 60 seconds is too long, and is
17
+ * documented as the slow path so nobody reaches for it by default.
18
+ */
19
+ /** §7.3: five seconds either side, matching the server's minting tolerance. */
20
+ export declare const CLOCK_SKEW_SECONDS = 5;
21
+ export interface SessionClaims {
22
+ iss: string;
23
+ sub: string;
24
+ sid: string;
25
+ exp: number;
26
+ nbf?: number;
27
+ iat?: number;
28
+ azp?: string;
29
+ sv?: number;
30
+ mfa?: boolean;
31
+ org_id?: string;
32
+ org_slug?: string;
33
+ org_role?: string;
34
+ org_permissions?: string[];
35
+ /** §billing entitlement — active plan slug; gate with `has({ plan })`. */
36
+ pla?: string;
37
+ /** §billing entitlement — granted feature keys; gate with `has({ feature })`. */
38
+ fea?: string[];
39
+ /**
40
+ * §impersonation — RFC 8693 actor claim. Present ONLY on an impersonation
41
+ * session (the dashboard "impersonate" action, or a redeemed actor token); its
42
+ * `sub` is the operator acting AS this user. Absent on an ordinary session.
43
+ * Informational, never an authorization input — the operator's privilege was
44
+ * proven when the token was minted — so read it to render the mandatory
45
+ * "viewing as X" banner and to tag audit entries as impersonated, not to
46
+ * grant access.
47
+ */
48
+ act?: {
49
+ sub: string;
50
+ };
51
+ /**
52
+ * §migration R3 — the subject's primary verified email. Present ONLY when the
53
+ * instance opted in (`session.includeEmailClaim`); absent otherwise. Lets an
54
+ * integrator provision a first-login user from the token alone, with no
55
+ * `GET /v1/users/:sub` round-trip. It is a snapshot at mint time, not a live
56
+ * lookup — treat it as identity, not as an always-current address.
57
+ */
58
+ email?: string;
59
+ /**
60
+ * §migration R3 — the subject's `external_id`, when set (e.g. a SCIM
61
+ * `externalId` or an id carried over from a migration). Present only alongside
62
+ * `email` under the same opt-in, and only when the user carries one.
63
+ */
64
+ external_id?: string;
65
+ [claim: string]: unknown;
66
+ }
67
+ /**
68
+ * A verified session, carrying the ergonomic authorization helpers bound to its
69
+ * claims — the server-side equivalent of Clerk's `auth()`. `has()` answers a
70
+ * condition; `protect()` asserts one, throwing `ForbiddenError` (which the app
71
+ * maps to 401/403). Both delegate to the shared `@atlasauth/authz` primitive, so a
72
+ * check reads identically here, in the React `<Protect>`, and in Next.js.
73
+ */
74
+ export interface AuthorizedSession {
75
+ ok: true;
76
+ claims: SessionClaims;
77
+ /**
78
+ * The impersonator when this is an impersonation session — the RFC 8693 `act`
79
+ * claim (`{ sub }`), else null. The server-side parallel of Clerk's
80
+ * `auth().actor`: branch on it to render the mandatory "viewing as X" banner
81
+ * and to tag audit entries, without reaching into `claims` untyped.
82
+ */
83
+ actor: {
84
+ sub: string;
85
+ } | null;
86
+ /** True when the claims satisfy the condition (empty condition = "signed in"). */
87
+ has(condition?: ProtectCondition): boolean;
88
+ /** Assert the condition; returns the claims on success, throws ForbiddenError otherwise. */
89
+ protect(condition?: ProtectCondition): SessionClaims;
90
+ }
91
+ export type VerifyResult = AuthorizedSession | {
92
+ ok: false;
93
+ reason: 'malformed' | 'invalid' | 'no_keys' | 'unauthorized_party';
94
+ };
95
+ export interface AtlasBackendOptions {
96
+ /** The instance's JWKS URL. */
97
+ jwksUrl: string;
98
+ /** Expected `iss`. Required — an unchecked issuer accepts any Atlas instance. */
99
+ issuer: string;
100
+ /**
101
+ * §7.3 optional azp allowlist. When set, a token minted for a different
102
+ * origin is refused, which is what stops a token issued to one of the
103
+ * customer's apps being replayed against another.
104
+ */
105
+ authorizedParties?: readonly string[];
106
+ secretKey?: string;
107
+ bapiBaseUrl?: string;
108
+ fetchImpl?: typeof fetch;
109
+ now?: () => number;
110
+ }
111
+ export declare class AtlasBackend {
112
+ private readonly options;
113
+ private readonly jwks;
114
+ constructor(options: AtlasBackendOptions);
115
+ /**
116
+ * Verify locally. No network call unless the `kid` is unknown, and at most
117
+ * one of those a minute.
118
+ */
119
+ verify(token: string): Promise<VerifyResult>;
120
+ /**
121
+ * §7.3 the documented slow path: ask Atlas whether the session is still live.
122
+ *
123
+ * Costs a round trip on every call, so it is for the handful of operations
124
+ * where a 60-second revocation window is genuinely unacceptable — deleting an
125
+ * account, moving money. Using it everywhere makes Atlas's availability the
126
+ * customer's availability, which is the thing local verification exists to
127
+ * avoid.
128
+ */
129
+ verifyOnline(token: string): Promise<VerifyResult>;
130
+ /**
131
+ * Verify whatever a request carries.
132
+ *
133
+ * §7.5: `__session` is readable by script for Authorization-header mode, so
134
+ * both carriers are legitimate. The header wins, because a caller that set it
135
+ * deliberately should not be overridden by a stale cookie.
136
+ */
137
+ authenticateRequest(request: {
138
+ headers: {
139
+ get(name: string): string | null;
140
+ } | Record<string, string | undefined>;
141
+ }): Promise<VerifyResult>;
142
+ }
143
+ /**
144
+ * §8.2 permission check, for gating a customer's own routes.
145
+ *
146
+ * Reads `org_permissions` off the token rather than calling Atlas, which is the
147
+ * whole point of putting them in the claims — and it means a permission change
148
+ * takes effect within one token lifetime, the same bound as revocation.
149
+ */
150
+ export declare function hasPermission(claims: SessionClaims, permission: string): boolean;
151
+ export declare function hasRole(claims: SessionClaims, role: string): boolean;
152
+ /**
153
+ * The full-condition check for a bare claims object — the standalone twin of the
154
+ * bound `result.has()`, for code that already holds claims (e.g. from a JWT it
155
+ * decoded itself). Supports permission / role / anyPermission / allPermissions.
156
+ */
157
+ export declare function has(claims: SessionClaims, condition?: ProtectCondition): boolean;
158
+ /**
159
+ * Assert a condition against a bare claims object, throwing `ForbiddenError`
160
+ * when unmet. The standalone twin of the bound `result.protect()`.
161
+ */
162
+ export declare function protect(claims: SessionClaims, condition?: ProtectCondition): SessionClaims;
package/dist/verify.js ADDED
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AtlasBackend = exports.CLOCK_SKEW_SECONDS = exports.isPermissionKey = exports.isRoleKey = exports.ForbiddenError = exports.protectFromClaims = exports.hasFromClaims = exports.evaluate = void 0;
4
+ exports.hasPermission = hasPermission;
5
+ exports.hasRole = hasRole;
6
+ exports.has = has;
7
+ exports.protect = protect;
8
+ const jose_1 = require("jose");
9
+ const authz_1 = require("@atlasauth/authz");
10
+ const jwks_cache_1 = require("./jwks-cache");
11
+ // Re-export the shared authorization primitive so a backend customer imports
12
+ // `has`, `protect`, `ProtectCondition`, etc. from `@atlasauth/backend` directly —
13
+ // the same contract `@atlasauth/react` and `@atlasauth/nextjs` evaluate.
14
+ var authz_2 = require("@atlasauth/authz");
15
+ Object.defineProperty(exports, "evaluate", { enumerable: true, get: function () { return authz_2.evaluate; } });
16
+ Object.defineProperty(exports, "hasFromClaims", { enumerable: true, get: function () { return authz_2.hasFromClaims; } });
17
+ Object.defineProperty(exports, "protectFromClaims", { enumerable: true, get: function () { return authz_2.protectFromClaims; } });
18
+ Object.defineProperty(exports, "ForbiddenError", { enumerable: true, get: function () { return authz_2.ForbiddenError; } });
19
+ Object.defineProperty(exports, "isRoleKey", { enumerable: true, get: function () { return authz_2.isRoleKey; } });
20
+ Object.defineProperty(exports, "isPermissionKey", { enumerable: true, get: function () { return authz_2.isPermissionKey; } });
21
+ /**
22
+ * §7.3 verification by customer backends.
23
+ *
24
+ * "verifies signature, exp/nbf with 5 s clock-skew tolerance, iss, and
25
+ * optionally azp against an allowlist."
26
+ *
27
+ * The design constraint that matters is what this does NOT do: it never calls
28
+ * Atlas on the hot path. A customer's API handling ten thousand requests a
29
+ * second cannot make ten thousand outbound calls to verify them, and a verifier
30
+ * that did would make Atlas's availability the customer's availability. So the
31
+ * default path is local, against cached JWKS, and the revocation window is
32
+ * bounded instead by the 60-second token lifetime.
33
+ *
34
+ * `verifyOnline` exists for the cases where 60 seconds is too long, and is
35
+ * documented as the slow path so nobody reaches for it by default.
36
+ */
37
+ /** §7.3: five seconds either side, matching the server's minting tolerance. */
38
+ exports.CLOCK_SKEW_SECONDS = 5;
39
+ /** Build the success result with `has`/`protect` bound to the verified claims. */
40
+ function authorized(claims) {
41
+ return {
42
+ ok: true,
43
+ claims,
44
+ // Normalize to a typed `{ sub }` or null — never leak a malformed `act`
45
+ // (e.g. `act` present but `sub` missing) through as a truthy actor.
46
+ actor: claims.act && typeof claims.act.sub === 'string' && claims.act.sub
47
+ ? { sub: claims.act.sub }
48
+ : null,
49
+ has: (condition = {}) => (0, authz_1.hasFromClaims)(claims, condition),
50
+ protect: (condition = {}) => {
51
+ const outcome = (0, authz_1.evaluate)(claims, condition);
52
+ if (!outcome.allowed)
53
+ throw new authz_1.ForbiddenError(outcome.reason, condition);
54
+ return claims;
55
+ },
56
+ };
57
+ }
58
+ class AtlasBackend {
59
+ options;
60
+ jwks;
61
+ constructor(options) {
62
+ this.options = options;
63
+ this.jwks = new jwks_cache_1.JwksCache({
64
+ url: options.jwksUrl,
65
+ fetchImpl: options.fetchImpl,
66
+ now: options.now,
67
+ });
68
+ }
69
+ /**
70
+ * Verify locally. No network call unless the `kid` is unknown, and at most
71
+ * one of those a minute.
72
+ */
73
+ async verify(token) {
74
+ if (!token || token.split('.').length !== 3)
75
+ return { ok: false, reason: 'malformed' };
76
+ const keys = await this.jwks.get((0, jwks_cache_1.readKid)(token));
77
+ if (!keys || keys.keys.length === 0)
78
+ return { ok: false, reason: 'no_keys' };
79
+ let claims;
80
+ try {
81
+ const { payload } = await (0, jose_1.jwtVerify)(token, (0, jose_1.createLocalJWKSet)(keys), {
82
+ // Pinned. Without this, a token whose header says `alg: none` — or any
83
+ // algorithm the key material can be coerced into — verifies.
84
+ algorithms: ['RS256'],
85
+ issuer: this.options.issuer,
86
+ clockTolerance: exports.CLOCK_SKEW_SECONDS,
87
+ currentDate: this.options.now ? new Date(this.options.now()) : undefined,
88
+ });
89
+ claims = payload;
90
+ }
91
+ catch {
92
+ /**
93
+ * One reason for every failure. Telling a caller whether the signature,
94
+ * the issuer or the expiry was wrong helps someone refining a forged
95
+ * token far more than it helps a developer debug a real one.
96
+ */
97
+ return { ok: false, reason: 'invalid' };
98
+ }
99
+ /**
100
+ * §13.1 token-confusion guard. An OP access token (`token_use:'access_token'`)
101
+ * and an id_token (carries `aud`) are signed with the SAME per-instance RS256
102
+ * key, issuer and `typ:'JWT'` header as a first-party session JWT. Reject any
103
+ * token carrying an OP marker so a "Sign in with Atlas" RP cannot replay one
104
+ * as a customer session. An ABSENT `token_use`/`aud` is a valid session
105
+ * (backward-compat for tokens minted before the `token_use:'session'` marker),
106
+ * so this never mass-invalidates a live fleet.
107
+ */
108
+ const tokenUse = claims.token_use;
109
+ if ((tokenUse !== undefined && tokenUse !== 'session') || claims.aud !== undefined) {
110
+ return { ok: false, reason: 'invalid' };
111
+ }
112
+ if (this.options.authorizedParties?.length) {
113
+ if (!claims.azp || !this.options.authorizedParties.includes(claims.azp)) {
114
+ return { ok: false, reason: 'unauthorized_party' };
115
+ }
116
+ }
117
+ // The single success-construction point — verifyOnline and
118
+ // authenticateRequest both return this result, so the bound has()/protect()
119
+ // ride along every verification path.
120
+ return authorized(claims);
121
+ }
122
+ /**
123
+ * §7.3 the documented slow path: ask Atlas whether the session is still live.
124
+ *
125
+ * Costs a round trip on every call, so it is for the handful of operations
126
+ * where a 60-second revocation window is genuinely unacceptable — deleting an
127
+ * account, moving money. Using it everywhere makes Atlas's availability the
128
+ * customer's availability, which is the thing local verification exists to
129
+ * avoid.
130
+ */
131
+ async verifyOnline(token) {
132
+ const local = await this.verify(token);
133
+ if (!local.ok)
134
+ return local;
135
+ if (!this.options.secretKey || !this.options.bapiBaseUrl) {
136
+ throw new Error('verifyOnline needs secretKey and bapiBaseUrl. Without them it would silently fall back to local verification, which is the opposite of what the caller asked for.');
137
+ }
138
+ try {
139
+ const response = await (this.options.fetchImpl ?? fetch)(`${this.options.bapiBaseUrl}/v1/tokens/verify`, {
140
+ method: 'POST',
141
+ headers: {
142
+ authorization: `Bearer ${this.options.secretKey}`,
143
+ 'content-type': 'application/json',
144
+ },
145
+ body: JSON.stringify({ token }),
146
+ });
147
+ if (!response.ok)
148
+ return { ok: false, reason: 'invalid' };
149
+ const body = (await response.json());
150
+ return body.verified ? local : { ok: false, reason: 'invalid' };
151
+ }
152
+ catch {
153
+ /**
154
+ * Fails CLOSED. The caller reached for verifyOnline precisely because a
155
+ * stale answer was unacceptable, so returning the local result on an
156
+ * outage would give them the thing they explicitly refused.
157
+ */
158
+ return { ok: false, reason: 'invalid' };
159
+ }
160
+ }
161
+ /**
162
+ * Verify whatever a request carries.
163
+ *
164
+ * §7.5: `__session` is readable by script for Authorization-header mode, so
165
+ * both carriers are legitimate. The header wins, because a caller that set it
166
+ * deliberately should not be overridden by a stale cookie.
167
+ */
168
+ async authenticateRequest(request) {
169
+ const header = readHeader(request.headers, 'authorization');
170
+ const cookie = readHeader(request.headers, 'cookie');
171
+ const bearer = header?.startsWith('Bearer ') ? header.slice(7) : undefined;
172
+ const fromCookie = cookie ? readCookie(cookie, '__session') : undefined;
173
+ const token = bearer ?? fromCookie;
174
+ if (!token)
175
+ return { ok: false, reason: 'malformed' };
176
+ return this.verify(token);
177
+ }
178
+ }
179
+ exports.AtlasBackend = AtlasBackend;
180
+ function readHeader(headers, name) {
181
+ if (typeof headers.get === 'function') {
182
+ return headers.get(name) ?? undefined;
183
+ }
184
+ const record = headers;
185
+ return record[name] ?? record[name.toLowerCase()];
186
+ }
187
+ function readCookie(header, name) {
188
+ for (const part of header.split(';')) {
189
+ const [key, ...rest] = part.trim().split('=');
190
+ if (key === name)
191
+ return rest.join('=');
192
+ }
193
+ return undefined;
194
+ }
195
+ /**
196
+ * §8.2 permission check, for gating a customer's own routes.
197
+ *
198
+ * Reads `org_permissions` off the token rather than calling Atlas, which is the
199
+ * whole point of putting them in the claims — and it means a permission change
200
+ * takes effect within one token lifetime, the same bound as revocation.
201
+ */
202
+ function hasPermission(claims, permission) {
203
+ return (0, authz_1.hasFromClaims)(claims, { permission });
204
+ }
205
+ function hasRole(claims, role) {
206
+ return (0, authz_1.hasFromClaims)(claims, { role });
207
+ }
208
+ /**
209
+ * The full-condition check for a bare claims object — the standalone twin of the
210
+ * bound `result.has()`, for code that already holds claims (e.g. from a JWT it
211
+ * decoded itself). Supports permission / role / anyPermission / allPermissions.
212
+ */
213
+ function has(claims, condition = {}) {
214
+ return (0, authz_1.hasFromClaims)(claims, condition);
215
+ }
216
+ /**
217
+ * Assert a condition against a bare claims object, throwing `ForbiddenError`
218
+ * when unmet. The standalone twin of the bound `result.protect()`.
219
+ */
220
+ function protect(claims, condition = {}) {
221
+ const outcome = (0, authz_1.evaluate)(claims, condition);
222
+ if (!outcome.allowed)
223
+ throw new authz_1.ForbiddenError(outcome.reason, condition);
224
+ return claims;
225
+ }
226
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@atlasauth/backend",
3
+ "version": "0.1.0",
4
+ "main": "./dist/index.js",
5
+ "types": "./dist/index.d.ts",
6
+ "dependencies": {
7
+ "jose": "^5.9.6",
8
+ "@atlasauth/authz": "0.1.0"
9
+ },
10
+ "devDependencies": {
11
+ "typescript": "^5.6.3",
12
+ "vitest": "^2.1.4"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.build.json",
23
+ "typecheck": "tsc -p tsconfig.json --noEmit",
24
+ "test": "vitest run"
25
+ }
26
+ }