@cat-factory/server 0.223.0 → 0.224.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 (46) hide show
  1. package/dist/auth/oidc/OidcClient.d.ts +86 -0
  2. package/dist/auth/oidc/OidcClient.d.ts.map +1 -0
  3. package/dist/auth/oidc/OidcClient.js +271 -0
  4. package/dist/auth/oidc/OidcClient.js.map +1 -0
  5. package/dist/auth/oidc/claims.d.ts +97 -0
  6. package/dist/auth/oidc/claims.d.ts.map +1 -0
  7. package/dist/auth/oidc/claims.js +149 -0
  8. package/dist/auth/oidc/claims.js.map +1 -0
  9. package/dist/auth/oidc/discovery.d.ts +51 -0
  10. package/dist/auth/oidc/discovery.d.ts.map +1 -0
  11. package/dist/auth/oidc/discovery.js +165 -0
  12. package/dist/auth/oidc/discovery.js.map +1 -0
  13. package/dist/auth/signing.d.ts +9 -0
  14. package/dist/auth/signing.d.ts.map +1 -1
  15. package/dist/auth/signing.js +9 -0
  16. package/dist/auth/signing.js.map +1 -1
  17. package/dist/config/misconfiguredApp.d.ts.map +1 -1
  18. package/dist/config/misconfiguredApp.js +14 -1
  19. package/dist/config/misconfiguredApp.js.map +1 -1
  20. package/dist/config/problems.js +1 -1
  21. package/dist/config/problems.js.map +1 -1
  22. package/dist/config/sso.d.ts +39 -0
  23. package/dist/config/sso.d.ts.map +1 -0
  24. package/dist/config/sso.js +169 -0
  25. package/dist/config/sso.js.map +1 -0
  26. package/dist/config/types.d.ts +41 -1
  27. package/dist/config/types.d.ts.map +1 -1
  28. package/dist/index.d.ts +7 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +10 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/modules/auth/AuthController.d.ts +0 -18
  33. package/dist/modules/auth/AuthController.d.ts.map +1 -1
  34. package/dist/modules/auth/AuthController.js +18 -150
  35. package/dist/modules/auth/AuthController.js.map +1 -1
  36. package/dist/modules/auth/loginFlow.d.ts +56 -0
  37. package/dist/modules/auth/loginFlow.d.ts.map +1 -0
  38. package/dist/modules/auth/loginFlow.js +162 -0
  39. package/dist/modules/auth/loginFlow.js.map +1 -0
  40. package/dist/modules/auth/ssoRoutes.d.ts +4 -0
  41. package/dist/modules/auth/ssoRoutes.d.ts.map +1 -0
  42. package/dist/modules/auth/ssoRoutes.js +294 -0
  43. package/dist/modules/auth/ssoRoutes.js.map +1 -0
  44. package/dist/modules/localSettings/MothershipConnectController.js +1 -1
  45. package/dist/modules/localSettings/MothershipConnectController.js.map +1 -1
  46. package/package.json +9 -8
@@ -0,0 +1,51 @@
1
+ import type { GroupCacheHandle, Logger, OidcProviderMetadata } from '@cat-factory/kernel';
2
+ import type { SsoDiscoveryDocument } from '@cat-factory/kernel';
3
+ export interface OidcProviderDirectoryDependencies {
4
+ /**
5
+ * The `AppCaches.ssoDiscovery` handle. Optional so the directory stays constructible in a
6
+ * unit test (and on a facade that wires no caches), where it simply fetches every time.
7
+ */
8
+ cache?: GroupCacheHandle<SsoDiscoveryDocument>;
9
+ logger?: Logger;
10
+ /** Injectable for tests; defaults to the runtime `fetch` (available on both facades). */
11
+ fetchImpl?: typeof fetch;
12
+ now?: () => number;
13
+ }
14
+ /**
15
+ * Resolves (and caches) the configured provider's metadata + signing keys.
16
+ *
17
+ * A failure here is an `UnavailableError`, not a validation error: the deployment is configured
18
+ * correctly and the IdP (or the network to it) is not answering, which is an outage an operator
19
+ * fixes rather than an input a user can correct. The `details.reason` distinguishes the causes
20
+ * that need different fixes, per CLAUDE.md's degrade-loudly rule.
21
+ */
22
+ export declare class OidcProviderDirectory {
23
+ private readonly deps;
24
+ private readonly log;
25
+ constructor(deps?: OidcProviderDirectoryDependencies);
26
+ /** The provider behind an issuer URL, from cache when warm. */
27
+ resolve(issuerUrl: string): Promise<SsoDiscoveryDocument>;
28
+ /**
29
+ * Re-resolve after an ID token arrived signed by a `kid` the cached key set does not hold —
30
+ * the key-rotation path. Returns the CACHED document unchanged when the last fetch is too
31
+ * recent to justify another, so the caller's verification fails on the stale keys (a login
32
+ * error the user can retry) rather than every unknown `kid` becoming a fresh IdP request.
33
+ */
34
+ refreshForUnknownKey(issuerUrl: string, current: SsoDiscoveryDocument): Promise<SsoDiscoveryDocument>;
35
+ private fetchDocument;
36
+ private fetchMetadata;
37
+ private fetchJwks;
38
+ private getJson;
39
+ }
40
+ /**
41
+ * Validate a discovery document down to the fields the flow uses.
42
+ *
43
+ * The `issuer` check is the load-bearing one and it is a SECURITY check, not tidiness: the
44
+ * discovered `issuer` becomes both the value every ID token's `iss` is compared against and half
45
+ * of the identity subject, so a document that names an issuer other than the URL it was served
46
+ * from is either a misconfiguration or a redirect onto an attacker's metadata, and admitting it
47
+ * would let that issuer's tokens sign in. Compared with the `/.well-known` suffix and any
48
+ * trailing slash removed, since providers differ on both.
49
+ */
50
+ export declare function readProviderMetadata(body: unknown, issuerUrl: string): OidcProviderMetadata;
51
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/auth/oidc/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AACzF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AA+B/D,MAAM,WAAW,iCAAiC;IAChD;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yFAAyF;IACzF,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,qBAAqB;IAGpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAE5B,YAA6B,IAAI,GAAE,iCAAsC,EAExE;IAED,+DAA+D;IAC/D,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAIxD;IAED;;;;;OAKG;IACG,oBAAoB,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAY/B;YAEa,aAAa;YAMb,aAAa;YAMb,SAAS;YAYT,OAAO;CA4BtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,oBAAoB,CAoC3F"}
@@ -0,0 +1,165 @@
1
+ import { UnavailableError, describeError, noopLogger } from '@cat-factory/kernel';
2
+ // ---------------------------------------------------------------------------
3
+ // Resolving the deployment's enterprise identity provider from its own discovery document.
4
+ //
5
+ // This is the whole reason there is ONE adapter rather than an Okta one and an Entra one: every
6
+ // endpoint the login flow needs is published by the provider at
7
+ // `/.well-known/openid-configuration`, so the code path is identical and the differences are
8
+ // data. Hard-coding endpoints per vendor would also be wrong over time — a provider moves its
9
+ // token endpoint and every deployment pinned to our copy breaks.
10
+ //
11
+ // Two facts shape the caching:
12
+ //
13
+ // - The document changes rarely, and reading it twice per sign-in (authorize, then verify)
14
+ // would put two IdP round-trips in front of every login. So it is cached through the app
15
+ // cache seam (`AppCaches.ssoDiscovery`), never a module-level Map — a scaled Node deployment
16
+ // has to be able to evict it (CLAUDE.md's caching rule).
17
+ // - Providers rotate their signing keys with NO notice and no version to probe. So an ID token
18
+ // whose `kid` is absent from the cached key set is not a failure: it is the signal to refetch
19
+ // ONCE. {@link OidcProviderDirectory.refreshForUnknownKey} is that path, rate-limited by the
20
+ // entry's own `fetchedAt` so a stream of tokens carrying junk `kid`s cannot turn into a
21
+ // request amplifier pointed at the IdP.
22
+ // ---------------------------------------------------------------------------
23
+ /** How long after a fetch a key-rotation refetch is refused (the amplification bound). */
24
+ const KEY_REFRESH_MIN_INTERVAL_MS = 60_000;
25
+ /** Discovery/JWKS fetches are IdP round-trips on a user's critical path — bound them. */
26
+ const FETCH_TIMEOUT_MS = 10_000;
27
+ /**
28
+ * Resolves (and caches) the configured provider's metadata + signing keys.
29
+ *
30
+ * A failure here is an `UnavailableError`, not a validation error: the deployment is configured
31
+ * correctly and the IdP (or the network to it) is not answering, which is an outage an operator
32
+ * fixes rather than an input a user can correct. The `details.reason` distinguishes the causes
33
+ * that need different fixes, per CLAUDE.md's degrade-loudly rule.
34
+ */
35
+ export class OidcProviderDirectory {
36
+ deps;
37
+ log;
38
+ constructor(deps = {}) {
39
+ this.deps = deps;
40
+ this.log = deps.logger ?? noopLogger;
41
+ }
42
+ /** The provider behind an issuer URL, from cache when warm. */
43
+ resolve(issuerUrl) {
44
+ const cache = this.deps.cache;
45
+ if (!cache)
46
+ return this.fetchDocument(issuerUrl);
47
+ return cache.get(issuerUrl, issuerUrl, () => this.fetchDocument(issuerUrl));
48
+ }
49
+ /**
50
+ * Re-resolve after an ID token arrived signed by a `kid` the cached key set does not hold —
51
+ * the key-rotation path. Returns the CACHED document unchanged when the last fetch is too
52
+ * recent to justify another, so the caller's verification fails on the stale keys (a login
53
+ * error the user can retry) rather than every unknown `kid` becoming a fresh IdP request.
54
+ */
55
+ async refreshForUnknownKey(issuerUrl, current) {
56
+ const now = this.deps.now?.() ?? Date.now();
57
+ if (now - current.fetchedAt < KEY_REFRESH_MIN_INTERVAL_MS) {
58
+ this.log.warn('sso.discovery.refresh_throttled', {
59
+ issuerUrl,
60
+ ageMs: now - current.fetchedAt,
61
+ });
62
+ return current;
63
+ }
64
+ await this.deps.cache?.invalidate(issuerUrl, issuerUrl);
65
+ this.log.info('sso.discovery.refreshed_for_key_rotation', { issuerUrl });
66
+ return this.resolve(issuerUrl);
67
+ }
68
+ async fetchDocument(issuerUrl) {
69
+ const metadata = await this.fetchMetadata(issuerUrl);
70
+ const jwks = await this.fetchJwks(metadata.jwksUri);
71
+ return { metadata, jwks, fetchedAt: this.deps.now?.() ?? Date.now() };
72
+ }
73
+ async fetchMetadata(issuerUrl) {
74
+ const url = `${issuerUrl}/.well-known/openid-configuration`;
75
+ const body = await this.getJson(url, 'sso_discovery_unreachable');
76
+ return readProviderMetadata(body, issuerUrl);
77
+ }
78
+ async fetchJwks(jwksUri) {
79
+ const body = await this.getJson(jwksUri, 'sso_jwks_unreachable');
80
+ const keys = body.keys;
81
+ if (!Array.isArray(keys) || keys.length === 0) {
82
+ throw new UnavailableError(`The identity provider's key set at ${jwksUri} contains no keys, so no ID token can be verified.`, 'sso_jwks_invalid');
83
+ }
84
+ return { keys: keys };
85
+ }
86
+ async getJson(url, reason) {
87
+ const doFetch = this.deps.fetchImpl ?? fetch;
88
+ let res;
89
+ try {
90
+ res = await doFetch(url, {
91
+ headers: { accept: 'application/json' },
92
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
93
+ });
94
+ }
95
+ catch (error) {
96
+ // The URL is operator-configured (never user input), so naming it is the diagnostic:
97
+ // "unreachable" without it sends an operator to the wrong system first.
98
+ throw new UnavailableError(`Could not reach the identity provider at ${url}: ${causeText(error)}`, reason);
99
+ }
100
+ if (!res.ok) {
101
+ throw new UnavailableError(`The identity provider answered HTTP ${res.status} for ${url}.`, reason);
102
+ }
103
+ try {
104
+ return await res.json();
105
+ }
106
+ catch {
107
+ throw new UnavailableError(`The identity provider's response at ${url} is not JSON.`, reason);
108
+ }
109
+ }
110
+ }
111
+ /**
112
+ * Validate a discovery document down to the fields the flow uses.
113
+ *
114
+ * The `issuer` check is the load-bearing one and it is a SECURITY check, not tidiness: the
115
+ * discovered `issuer` becomes both the value every ID token's `iss` is compared against and half
116
+ * of the identity subject, so a document that names an issuer other than the URL it was served
117
+ * from is either a misconfiguration or a redirect onto an attacker's metadata, and admitting it
118
+ * would let that issuer's tokens sign in. Compared with the `/.well-known` suffix and any
119
+ * trailing slash removed, since providers differ on both.
120
+ */
121
+ export function readProviderMetadata(body, issuerUrl) {
122
+ const doc = (body ?? {});
123
+ const issuer = str(doc.issuer);
124
+ const authorizationEndpoint = str(doc.authorization_endpoint);
125
+ const tokenEndpoint = str(doc.token_endpoint);
126
+ const jwksUri = str(doc.jwks_uri);
127
+ const missing = [
128
+ issuer ? null : 'issuer',
129
+ authorizationEndpoint ? null : 'authorization_endpoint',
130
+ tokenEndpoint ? null : 'token_endpoint',
131
+ jwksUri ? null : 'jwks_uri',
132
+ ].filter((name) => name !== null);
133
+ if (missing.length > 0) {
134
+ throw new UnavailableError(`The identity provider's discovery document at ${issuerUrl} is missing ${missing.join(', ')}, so it cannot be used for sign-in.`, 'sso_discovery_invalid');
135
+ }
136
+ if (trimIssuer(issuer) !== trimIssuer(issuerUrl)) {
137
+ throw new UnavailableError(`The identity provider's discovery document declares issuer "${issuer}" but was fetched from "${issuerUrl}". ` +
138
+ `Set AUTH_SSO_ISSUER_URL to the issuer the provider itself publishes.`, 'sso_issuer_mismatch');
139
+ }
140
+ const methods = Array.isArray(doc.code_challenge_methods_supported)
141
+ ? doc.code_challenge_methods_supported
142
+ : [];
143
+ return {
144
+ issuer: issuer,
145
+ authorizationEndpoint: authorizationEndpoint,
146
+ tokenEndpoint: tokenEndpoint,
147
+ jwksUri: jwksUri,
148
+ userinfoEndpoint: str(doc.userinfo_endpoint) ?? null,
149
+ supportsPkceS256: methods.includes('S256'),
150
+ };
151
+ }
152
+ function trimIssuer(value) {
153
+ return value
154
+ .trim()
155
+ .replace(/\/\.well-known\/openid-configuration$/i, '')
156
+ .replace(/\/+$/, '');
157
+ }
158
+ /** The scrubbed message of a thrown value, as a string safe to interpolate. */
159
+ function causeText(error) {
160
+ return String(describeError(error).err ?? '');
161
+ }
162
+ function str(value) {
163
+ return typeof value === 'string' && value.trim() !== '' ? value.trim() : null;
164
+ }
165
+ //# sourceMappingURL=discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../src/auth/oidc/discovery.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,15 @@ export declare const TOKEN_AUDIENCE: {
4
4
  readonly session: 'session';
5
5
  /** OAuth login `state` nonce. */
6
6
  readonly oauthState: 'oauth-state';
7
+ /**
8
+ * Enterprise-SSO round-trip cookie. Deliberately NOT `oauthState`, even though both are one
9
+ * login round-trip's CSRF state: the OAuth value travels in the URL (so any user holds a
10
+ * validly-signed one), while this one is an httpOnly cookie carrying the PKCE `code_verifier`
11
+ * and the OIDC `nonce`. Sharing an audience would let the public value verify as the secret
12
+ * container, leaving the two secrets `undefined` and the flow resting on the provider to
13
+ * refuse a PKCE mismatch. Pinned so it cannot.
14
+ */
15
+ readonly ssoState: 'sso-state';
7
16
  /** Implementation-container → LLM proxy token. */
8
17
  readonly container: 'llm-proxy';
9
18
  /** Single-workspace WebSocket event-stream ticket. */
@@ -1 +1 @@
1
- {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../../src/auth/signing.ts"],"names":[],"mappings":"AA8BA,yEAAyE;AACzE,eAAO,MAAM,cAAc;IACzB,gDAAgD;aAChD,OAAO,EAAE,SAAS;IAClB,iCAAiC;aACjC,UAAU,EAAE,aAAa;IACzB,kDAAkD;aAClD,SAAS,EAAE,WAAW;IACtB,sDAAsD;aACtD,QAAQ,EAAE,IAAI;IACd;;;;OAIG;aACH,OAAO,EAAE,SAAS;CACV,CAAA;AAEV,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAA;AAEhF,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAA;IACV,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,qEAAqE;AACrE,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,0DAA0D;IAC1D,GAAG,EAAE,OAAO,cAAc,CAAC,OAAO,CAAA;IAClC,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,OAAO,cAAc,CAAC,OAAO,CAAA;IAClC,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAA;IACd,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,sDAAsD;IACtD,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC/B,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAA;CACZ;AAwBD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAOpD;AACD,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,6FAA6F;IAC7F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IAEjE,YAA6B,MAAM,EAAE,MAAM,EAAI;IAEzC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3C;IAED;;;;;;;;OAQG;IACG,MAAM,CAAC,CAAC,SAAS,MAAM,EAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,aAAa,CAAA;KAAE,GAC7B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CA8BnB;YAEa,GAAG;IAKjB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM;IAUd,mFAAmF;IACnF,OAAO,CAAC,aAAa;IAUrB;;;;OAIG;YACW,iBAAiB;CAoBhC"}
1
+ {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../../src/auth/signing.ts"],"names":[],"mappings":"AA8BA,yEAAyE;AACzE,eAAO,MAAM,cAAc;IACzB,gDAAgD;aAChD,OAAO,EAAE,SAAS;IAClB,iCAAiC;aACjC,UAAU,EAAE,aAAa;IACzB;;;;;;;OAOG;aACH,QAAQ,EAAE,WAAW;IACrB,kDAAkD;aAClD,SAAS,EAAE,WAAW;IACtB,sDAAsD;aACtD,QAAQ,EAAE,IAAI;IACd;;;;OAIG;aACH,OAAO,EAAE,SAAS;CACV,CAAA;AAEV,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAA;AAEhF,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAA;IACV,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,qEAAqE;AACrE,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,0DAA0D;IAC1D,GAAG,EAAE,OAAO,cAAc,CAAC,OAAO,CAAA;IAClC,GAAG,EAAE,MAAM,CAAA;CACZ;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,OAAO,cAAc,CAAC,OAAO,CAAA;IAClC,sFAAsF;IACtF,MAAM,EAAE,MAAM,CAAA;IACd,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,sDAAsD;IACtD,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC/B,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAA;CACZ;AAwBD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAOpD;AACD,qBAAa,UAAU;IAIT,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,6FAA6F;IAC7F,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwC;IAEjE,YAA6B,MAAM,EAAE,MAAM,EAAI;IAEzC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3C;IAED;;;;;;;;OAQG;IACG,MAAM,CAAC,CAAC,SAAS,MAAM,EAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAChC,IAAI,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,aAAa,CAAA;KAAE,GAC7B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CA8BnB;YAEa,GAAG;IAKjB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM;IAUd,mFAAmF;IACnF,OAAO,CAAC,aAAa;IAUrB;;;;OAIG;YACW,iBAAiB;CAoBhC"}
@@ -32,6 +32,15 @@ export const TOKEN_AUDIENCE = {
32
32
  session: 'session',
33
33
  /** OAuth login `state` nonce. */
34
34
  oauthState: 'oauth-state',
35
+ /**
36
+ * Enterprise-SSO round-trip cookie. Deliberately NOT `oauthState`, even though both are one
37
+ * login round-trip's CSRF state: the OAuth value travels in the URL (so any user holds a
38
+ * validly-signed one), while this one is an httpOnly cookie carrying the PKCE `code_verifier`
39
+ * and the OIDC `nonce`. Sharing an audience would let the public value verify as the secret
40
+ * container, leaving the two secrets `undefined` and the flow resting on the provider to
41
+ * refuse a PKCE mismatch. Pinned so it cannot.
42
+ */
43
+ ssoState: 'sso-state',
35
44
  /** Implementation-container → LLM proxy token. */
36
45
  container: 'llm-proxy',
37
46
  /** Single-workspace WebSocket event-stream ticket. */
@@ -1 +1 @@
1
- {"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/auth/signing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/auth/signing.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"misconfiguredApp.d.ts","sourceRoot":"","sources":["../../src/config/misconfiguredApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AA2B5C;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,QAAQ,CAsBhG;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAsB9E"}
1
+ {"version":3,"file":"misconfiguredApp.d.ts","sourceRoot":"","sources":["../../src/config/misconfiguredApp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAChF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAwC5C;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,QAAQ,CAsBhG;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAsB9E"}
@@ -23,7 +23,20 @@ import { mountRequestLogging } from '../http/requestLogging.js';
23
23
  // and remedies), so the SPA on a separate dev origin can always read it, regardless of whether the
24
24
  // (failed) config load ever resolved CORS_ALLOWED_ORIGINS / ENVIRONMENT.
25
25
  // ---------------------------------------------------------------------------
26
- const AUTH_DISABLED_PROVIDERS = { github: false, password: false, google: false };
26
+ /**
27
+ * Every login provider reported OFF, for the fallback `/auth/config`.
28
+ *
29
+ * Typed against the contract's own providers shape rather than left as an inferred literal: this
30
+ * response is hand-built with `Response.json` (the fallback app has no contract-typed route
31
+ * layer), so nothing else would notice a provider added to the vocabulary and missing here — the
32
+ * SPA would simply read `undefined` for it and render whatever that coerces to.
33
+ */
34
+ const AUTH_DISABLED_PROVIDERS = {
35
+ github: false,
36
+ password: false,
37
+ google: false,
38
+ sso: false,
39
+ };
27
40
  /**
28
41
  * Build the Response for one request against the fallback backend, keyed off the URL pathname.
29
42
  * Pure (no CORS, no framework) so the Worker can reuse it INSIDE its already-CORS'd request
@@ -1 +1 @@
1
- {"version":3,"file":"misconfiguredApp.js","sourceRoot":"","sources":["../../src/config/misconfiguredApp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAE/D,8EAA8E;AAC9E,yCAAyC;AACzC,EAAE;AACF,+FAA+F;AAC/F,+FAA+F;AAC/F,kGAAkG;AAClG,+EAA+E;AAC/E,2DAA2D;AAC3D,EAAE;AACF,8FAA8F;AAC9F,iGAAiG;AACjG,wBAAwB;AACxB,+FAA+F;AAC/F,kGAAkG;AAClG,qCAAqC;AACrC,gGAAgG;AAChG,EAAE;AACF,iGAAiG;AACjG,mGAAmG;AACnG,yEAAyE;AACzE,8EAA8E;AAE9E,MAAM,uBAAuB,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAEjF;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB,EAAE,QAAyB;IACpF,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChC,OAAO,QAAQ,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,uBAAuB;YAClC,aAAa,EAAE,EAAE,QAAQ,EAAE;SAC5B,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAClB;QACE,KAAK,EAAE;YACL,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EACL,oGAAoG;YACtG,QAAQ;SACT;KACF,EACD,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAyB;IAC9D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAC9B,6FAA6F;IAC7F,2FAA2F;IAC3F,8FAA8F;IAC9F,yFAAyF;IACzF,gDAAgD;IAChD,mBAAmB,CAAC,GAAG,CAAC,CAAA;IACxB,GAAG,CAAC,GAAG,CACL,GAAG,EACH,IAAI,CAAC;QACH,6FAA6F;QAC7F,6FAA6F;QAC7F,yEAAyE;QACzE,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,GAAG;QACjC,YAAY,EAAE,CAAC,GAAG,oBAAoB,CAAC;QACvC,wFAAwF;QACxF,aAAa,EAAE,CAAC,GAAG,oBAAoB,CAAC;KACzC,CAAC,CACH,CAAA;IACD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;IACrE,OAAO,GAAG,CAAA;AACZ,CAAC"}
1
+ {"version":3,"file":"misconfiguredApp.js","sourceRoot":"","sources":["../../src/config/misconfiguredApp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAE/D,8EAA8E;AAC9E,yCAAyC;AACzC,EAAE;AACF,+FAA+F;AAC/F,+FAA+F;AAC/F,kGAAkG;AAClG,+EAA+E;AAC/E,2DAA2D;AAC3D,EAAE;AACF,8FAA8F;AAC9F,iGAAiG;AACjG,wBAAwB;AACxB,+FAA+F;AAC/F,kGAAkG;AAClG,qCAAqC;AACrC,gGAAgG;AAChG,EAAE;AACF,iGAAiG;AACjG,mGAAmG;AACnG,yEAAyE;AACzE,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,uBAAuB,GAAqC;IAChE,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,KAAK;IACf,MAAM,EAAE,KAAK;IACb,GAAG,EAAE,KAAK;CACX,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB,EAAE,QAAyB;IACpF,IAAI,QAAQ,KAAK,cAAc,EAAE,CAAC;QAChC,OAAO,QAAQ,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,uBAAuB;YAClC,aAAa,EAAE,EAAE,QAAQ,EAAE;SAC5B,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAClB;QACE,KAAK,EAAE;YACL,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EACL,oGAAoG;YACtG,QAAQ;SACT;KACF,EACD,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAAyB;IAC9D,MAAM,GAAG,GAAG,IAAI,IAAI,EAAU,CAAA;IAC9B,6FAA6F;IAC7F,2FAA2F;IAC3F,8FAA8F;IAC9F,yFAAyF;IACzF,gDAAgD;IAChD,mBAAmB,CAAC,GAAG,CAAC,CAAA;IACxB,GAAG,CAAC,GAAG,CACL,GAAG,EACH,IAAI,CAAC;QACH,6FAA6F;QAC7F,6FAA6F;QAC7F,yEAAyE;QACzE,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,GAAG;QACjC,YAAY,EAAE,CAAC,GAAG,oBAAoB,CAAC;QACvC,wFAAwF;QACxF,aAAa,EAAE,CAAC,GAAG,oBAAoB,CAAC;KACzC,CAAC,CACH,CAAA;IACD,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;IACrE,OAAO,GAAG,CAAA;AACZ,CAAC"}
@@ -99,7 +99,7 @@ export const ENV_HELP = {
99
99
  },
100
100
  AUTH_PROVIDER: {
101
101
  summary: 'A remote deployment has no anonymous tier, so at least one login provider must be configured or every protected route fails closed.',
102
- remedy: 'Enable one of: GitHub OAuth (GITHUB_OAUTH_CLIENT_ID + GITHUB_OAUTH_CLIENT_SECRET), Google OAuth (GOOGLE_OAUTH_CLIENT_ID + GOOGLE_OAUTH_CLIENT_SECRET), or password login (AUTH_PASSWORD_ENABLED=true) — each alongside a 32+ character AUTH_SESSION_SECRET. For local dev or tests, set AUTH_DEV_OPEN=true in a non-production ENVIRONMENT instead.',
102
+ remedy: 'Enable one of: enterprise SSO (AUTH_SSO_ISSUER_URL + AUTH_SSO_CLIENT_ID + AUTH_SSO_CLIENT_SECRET — one generic OIDC adapter serving Okta, Entra ID, Auth0, Keycloak, PingFederate and the like), GitHub OAuth (GITHUB_OAUTH_CLIENT_ID + GITHUB_OAUTH_CLIENT_SECRET), Google OAuth (GOOGLE_OAUTH_CLIENT_ID + GOOGLE_OAUTH_CLIENT_SECRET), or password login (AUTH_PASSWORD_ENABLED=true) — each alongside a 32+ character AUTH_SESSION_SECRET. For local dev or tests, set AUTH_DEV_OPEN=true in a non-production ENVIRONMENT instead.',
103
103
  docsUrl: DOCS.envVars(ENV_VARS_ANCHORS.authentication),
104
104
  },
105
105
  DB: {
@@ -1 +1 @@
1
- {"version":3,"file":"problems.js","sourceRoot":"","sources":["../../src/config/problems.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"problems.js","sourceRoot":"","sources":["../../src/config/problems.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { SsoConfig } from './types.js';
2
+ /** The environment slice this resolver reads. Both `Env` (Worker) and `process.env` satisfy it. */
3
+ export interface SsoEnv {
4
+ AUTH_SSO_ISSUER_URL?: string;
5
+ AUTH_SSO_CLIENT_ID?: string;
6
+ AUTH_SSO_CLIENT_SECRET?: string;
7
+ AUTH_SSO_LABEL?: string;
8
+ AUTH_SSO_SCOPES?: string;
9
+ AUTH_SSO_REDIRECT_URL?: string;
10
+ AUTH_SSO_ALLOWED_EMAIL_DOMAINS?: string;
11
+ AUTH_SSO_GROUPS_CLAIM?: string;
12
+ AUTH_SSO_REQUIRED_GROUPS?: string;
13
+ }
14
+ /**
15
+ * Resolve the deployment's enterprise-SSO config, or `undefined` when none of its variables are
16
+ * set (the overwhelmingly common case: SSO is opt-in).
17
+ *
18
+ * Throws a `ConfigValidationError` — which both facades render as the misconfiguration
19
+ * screen — for the four states that must never boot into a running deployment:
20
+ *
21
+ * 1. **Partially configured.** Any one of issuer / client id / client secret present without
22
+ * the others. Disabling quietly would leave an operator who believes SSO is live on the
23
+ * consumer logins they adopted SSO to replace.
24
+ * 2. **An unusable issuer URL.** Not parseable, or plain `http` on a non-loopback host, which
25
+ * would carry the authorization code and ID token in clear.
26
+ * 3. **A session secret too weak to sign the session SSO mints.** SSO establishes identity; the
27
+ * session it produces is the same HMAC bearer every other login mints, so a brute-forceable
28
+ * secret makes the IdP's guarantees irrelevant. (Same refusal the GitHub pair already gets,
29
+ * with no `AUTH_DEV_OPEN` escape — see 4.)
30
+ * 4. **`AUTH_DEV_OPEN` alongside SSO.** Dev-open serves every protected route anonymously. A
31
+ * deployment that configured SSO to pass a security review must not have a variable
32
+ * combination that opens the API, and an operator cannot be relied on to notice they set
33
+ * both — so the pair is refused rather than resolved to one of them winning.
34
+ */
35
+ export declare function resolveSsoConfig(env: SsoEnv, opts: {
36
+ strongSessionSecret: boolean;
37
+ devOpen: boolean;
38
+ }): SsoConfig | undefined;
39
+ //# sourceMappingURL=sso.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.d.ts","sourceRoot":"","sources":["../../src/config/sso.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAsB3C,mGAAmG;AACnG,MAAM,WAAW,MAAM;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,8BAA8B,CAAC,EAAE,MAAM,CAAA;IACvC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,wBAAwB,CAAC,EAAE,MAAM,CAAA;CAClC;AAyDD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,mBAAmB,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACvD,SAAS,GAAG,SAAS,CA0BvB"}
@@ -0,0 +1,169 @@
1
+ import { DOCS, ENV_VARS_ANCHORS } from './docs.js';
2
+ import { configProblem } from './problems.js';
3
+ /** Scopes every request carries whether or not the operator listed them. */
4
+ const REQUIRED_SCOPE = 'openid';
5
+ const DEFAULT_SCOPES = 'openid profile email';
6
+ const DEFAULT_LABEL = 'Single sign-on';
7
+ /** The claim most IdPs release group memberships under (Okta, Keycloak, Entra ID). */
8
+ const DEFAULT_GROUPS_CLAIM = 'groups';
9
+ const SSO_DOC_URL = DOCS.envVars(ENV_VARS_ANCHORS.authentication);
10
+ function csv(raw) {
11
+ return (raw ?? '')
12
+ .split(',')
13
+ .map((entry) => entry.trim())
14
+ .filter(Boolean);
15
+ }
16
+ /**
17
+ * Whether an issuer URL is safe to send a browser (and a client secret) to: `https`, or `http`
18
+ * on a loopback host so a Keycloak/Dex container on a developer's own machine is usable.
19
+ *
20
+ * Refused rather than warned about, because the failure mode of a plain-`http` issuer on a real
21
+ * network is the authorization code and the ID token crossing it in clear.
22
+ */
23
+ function isAcceptableIssuerUrl(url) {
24
+ if (url.protocol === 'https:')
25
+ return true;
26
+ if (url.protocol !== 'http:')
27
+ return false;
28
+ const host = url.hostname.toLowerCase().replace(/^\[|\]$/g, '');
29
+ return host === 'localhost' || host === '::1' || /^127\.\d+\.\d+\.\d+$/.test(host);
30
+ }
31
+ /**
32
+ * Normalise the configured issuer URL: trim, drop a trailing slash, and accept the two
33
+ * spellings operators paste interchangeably — the issuer itself
34
+ * (`https://acme.okta.com/oauth2/default`) or the full discovery URL
35
+ * (`…/.well-known/openid-configuration`). Both resolve to the same document, and refusing one
36
+ * of them would be a config puzzle with no diagnostic value.
37
+ */
38
+ function normalizeIssuerUrl(raw) {
39
+ const trimmed = raw.trim().replace(/\/+$/, '');
40
+ return trimmed.replace(/\/\.well-known\/openid-configuration$/i, '');
41
+ }
42
+ /**
43
+ * Requested scopes, with `openid` guaranteed present. An operator who overrides
44
+ * `AUTH_SSO_SCOPES` to name the claims their IdP needs (`openid email groups`) must not be able
45
+ * to accidentally drop the one scope that makes the response an OIDC response at all — without
46
+ * it there is no ID token to verify and the flow degrades to bare OAuth.
47
+ */
48
+ function resolveScopes(raw) {
49
+ const requested = (raw ?? '').trim();
50
+ if (!requested)
51
+ return DEFAULT_SCOPES;
52
+ const scopes = requested.split(/\s+/).filter(Boolean);
53
+ return scopes.includes(REQUIRED_SCOPE) ? scopes.join(' ') : [REQUIRED_SCOPE, ...scopes].join(' ');
54
+ }
55
+ /**
56
+ * Resolve the deployment's enterprise-SSO config, or `undefined` when none of its variables are
57
+ * set (the overwhelmingly common case: SSO is opt-in).
58
+ *
59
+ * Throws a `ConfigValidationError` — which both facades render as the misconfiguration
60
+ * screen — for the four states that must never boot into a running deployment:
61
+ *
62
+ * 1. **Partially configured.** Any one of issuer / client id / client secret present without
63
+ * the others. Disabling quietly would leave an operator who believes SSO is live on the
64
+ * consumer logins they adopted SSO to replace.
65
+ * 2. **An unusable issuer URL.** Not parseable, or plain `http` on a non-loopback host, which
66
+ * would carry the authorization code and ID token in clear.
67
+ * 3. **A session secret too weak to sign the session SSO mints.** SSO establishes identity; the
68
+ * session it produces is the same HMAC bearer every other login mints, so a brute-forceable
69
+ * secret makes the IdP's guarantees irrelevant. (Same refusal the GitHub pair already gets,
70
+ * with no `AUTH_DEV_OPEN` escape — see 4.)
71
+ * 4. **`AUTH_DEV_OPEN` alongside SSO.** Dev-open serves every protected route anonymously. A
72
+ * deployment that configured SSO to pass a security review must not have a variable
73
+ * combination that opens the API, and an operator cannot be relied on to notice they set
74
+ * both — so the pair is refused rather than resolved to one of them winning.
75
+ */
76
+ export function resolveSsoConfig(env, opts) {
77
+ const rawIssuer = env.AUTH_SSO_ISSUER_URL?.trim() ?? '';
78
+ const clientId = env.AUTH_SSO_CLIENT_ID?.trim() ?? '';
79
+ const clientSecret = env.AUTH_SSO_CLIENT_SECRET?.trim() ?? '';
80
+ if (!rawIssuer && !clientId && !clientSecret)
81
+ return undefined;
82
+ assertComplete({ rawIssuer, clientId, clientSecret });
83
+ const issuerUrl = normalizeIssuerUrl(rawIssuer);
84
+ assertUsableIssuer(issuerUrl);
85
+ assertSessionIntegrity(opts);
86
+ const groupsClaim = (env.AUTH_SSO_GROUPS_CLAIM ?? DEFAULT_GROUPS_CLAIM).trim();
87
+ const requiredGroups = csv(env.AUTH_SSO_REQUIRED_GROUPS).map((group) => group.toLowerCase());
88
+ assertGroupGateEvaluable({ groupsClaim, requiredGroups });
89
+ return {
90
+ issuerUrl,
91
+ clientId,
92
+ clientSecret,
93
+ label: env.AUTH_SSO_LABEL?.trim() || DEFAULT_LABEL,
94
+ scopes: resolveScopes(env.AUTH_SSO_SCOPES),
95
+ redirectUrl: env.AUTH_SSO_REDIRECT_URL?.trim() || '',
96
+ allowedEmailDomains: csv(env.AUTH_SSO_ALLOWED_EMAIL_DOMAINS).map((d) => d.toLowerCase()),
97
+ groupsClaim,
98
+ requiredGroups,
99
+ };
100
+ }
101
+ function assertComplete(parts) {
102
+ const missing = [
103
+ parts.rawIssuer ? null : 'AUTH_SSO_ISSUER_URL',
104
+ parts.clientId ? null : 'AUTH_SSO_CLIENT_ID',
105
+ parts.clientSecret ? null : 'AUTH_SSO_CLIENT_SECRET',
106
+ ].filter((name) => name !== null);
107
+ if (missing.length === 0)
108
+ return;
109
+ throw configProblem({
110
+ key: missing[0],
111
+ summary: 'Enterprise SSO is partially configured: some of its variables are set, so a sign-in button was intended, but the rest are missing.',
112
+ remedy: `Set ${missing.join(', ')} as well (all three of AUTH_SSO_ISSUER_URL, AUTH_SSO_CLIENT_ID ` +
113
+ `and AUTH_SSO_CLIENT_SECRET are required), or unset the ones that ARE set to run without SSO. ` +
114
+ `The issuer URL is your provider's own — e.g. https://acme.okta.com/oauth2/default, ` +
115
+ `https://login.microsoftonline.com/<tenant>/v2.0, or your Keycloak realm URL.`,
116
+ docsUrl: SSO_DOC_URL,
117
+ });
118
+ }
119
+ function assertUsableIssuer(issuerUrl) {
120
+ let parsed;
121
+ try {
122
+ parsed = new URL(issuerUrl);
123
+ }
124
+ catch {
125
+ throw configProblem({
126
+ key: 'AUTH_SSO_ISSUER_URL',
127
+ summary: 'The enterprise SSO issuer URL is not a URL, so no discovery document can be read.',
128
+ remedy: "Set AUTH_SSO_ISSUER_URL to your provider's absolute issuer URL, e.g. `https://acme.okta.com/oauth2/default`. The `/.well-known/openid-configuration` suffix is optional — it is appended when absent.",
129
+ docsUrl: SSO_DOC_URL,
130
+ });
131
+ }
132
+ if (isAcceptableIssuerUrl(parsed))
133
+ return;
134
+ throw configProblem({
135
+ key: 'AUTH_SSO_ISSUER_URL',
136
+ summary: 'The enterprise SSO issuer URL is not https, so the authorization code and the ID token would cross the network in clear.',
137
+ remedy: 'Use the https issuer URL your provider publishes. Plain http is accepted only for a loopback host (localhost / 127.0.0.0/8 / ::1), for a provider running on your own machine.',
138
+ docsUrl: SSO_DOC_URL,
139
+ });
140
+ }
141
+ function assertSessionIntegrity(opts) {
142
+ if (opts.devOpen) {
143
+ throw configProblem({
144
+ key: 'AUTH_DEV_OPEN',
145
+ summary: 'AUTH_DEV_OPEN (or TESTING_NO_AUTH) serves every protected route anonymously, which cancels the access control enterprise SSO was configured to enforce.',
146
+ remedy: 'Unset AUTH_DEV_OPEN and TESTING_NO_AUTH on any deployment that configures AUTH_SSO_ISSUER_URL. To run the API open for local development or a test suite, unset the AUTH_SSO_* variables instead — the two are refused together rather than one silently winning.',
147
+ docsUrl: SSO_DOC_URL,
148
+ });
149
+ }
150
+ if (opts.strongSessionSecret)
151
+ return;
152
+ throw configProblem({
153
+ key: 'AUTH_SESSION_SECRET',
154
+ summary: 'Enterprise SSO is configured but the session secret is missing or too short. SSO establishes WHO signs in; the session it mints is the same HMAC bearer token every other login mints, so a brute-forceable secret lets a session be forged regardless of what the identity provider enforced.',
155
+ remedy: 'Set AUTH_SESSION_SECRET to a random string of at least 32 characters (`openssl rand -hex 32`), stable across restarts.',
156
+ docsUrl: SSO_DOC_URL,
157
+ });
158
+ }
159
+ function assertGroupGateEvaluable(parts) {
160
+ if (parts.requiredGroups.length === 0 || parts.groupsClaim !== '')
161
+ return;
162
+ throw configProblem({
163
+ key: 'AUTH_SSO_GROUPS_CLAIM',
164
+ summary: "AUTH_SSO_REQUIRED_GROUPS names the directory groups allowed to sign in, but AUTH_SSO_GROUPS_CLAIM is empty, so there is no claim to read a user's groups from and the gate could never be evaluated.",
165
+ remedy: "Set AUTH_SSO_GROUPS_CLAIM to the claim your provider releases group memberships under (`groups` for Okta / Keycloak / Entra ID, `entitlement` or `isMemberOf` for a Shibboleth OP), or clear AUTH_SSO_REQUIRED_GROUPS to let the provider's own app assignment be the whole allowlist.",
166
+ docsUrl: SSO_DOC_URL,
167
+ });
168
+ }
169
+ //# sourceMappingURL=sso.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sso.js","sourceRoot":"","sources":["../../src/config/sso.ts"],"names":[],"mappings":"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"}