@hilbras/keystone 2.5.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +423 -0
- package/README.md +85 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -11
- package/dist/index.js.map +1 -1
- package/dist/plugins/auth.d.ts +2 -0
- package/dist/plugins/auth.d.ts.map +1 -1
- package/dist/plugins/auth.js +21 -7
- package/dist/plugins/auth.js.map +1 -1
- package/dist/plugins/machinePrincipal.d.ts +28 -0
- package/dist/plugins/machinePrincipal.d.ts.map +1 -0
- package/dist/plugins/machinePrincipal.js +45 -0
- package/dist/plugins/machinePrincipal.js.map +1 -0
- package/dist/plugins/rateLimit.d.ts +10 -7
- package/dist/plugins/rateLimit.d.ts.map +1 -1
- package/dist/plugins/rateLimit.js +75 -36
- package/dist/plugins/rateLimit.js.map +1 -1
- package/dist/routes/admin/organizations.d.ts.map +1 -1
- package/dist/routes/admin/organizations.js +2 -0
- package/dist/routes/admin/organizations.js.map +1 -1
- package/dist/routes/admin/platform.d.ts.map +1 -1
- package/dist/routes/admin/platform.js +14 -1
- package/dist/routes/admin/platform.js.map +1 -1
- package/dist/routes/apiKeys.d.ts.map +1 -1
- package/dist/routes/apiKeys.js +37 -5
- package/dist/routes/apiKeys.js.map +1 -1
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +104 -3
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/emailVerification.d.ts.map +1 -1
- package/dist/routes/emailVerification.js +2 -0
- package/dist/routes/emailVerification.js.map +1 -1
- package/dist/routes/federation.d.ts.map +1 -1
- package/dist/routes/federation.js +8 -2
- package/dist/routes/federation.js.map +1 -1
- package/dist/routes/magicLinks.d.ts.map +1 -1
- package/dist/routes/magicLinks.js +2 -0
- package/dist/routes/magicLinks.js.map +1 -1
- package/dist/routes/oauth2.d.ts.map +1 -1
- package/dist/routes/oauth2.js +24 -4
- package/dist/routes/oauth2.js.map +1 -1
- package/dist/routes/password.d.ts.map +1 -1
- package/dist/routes/password.js +2 -0
- package/dist/routes/password.js.map +1 -1
- package/dist/routes/profile.js +2 -2
- package/dist/routes/profile.js.map +1 -1
- package/dist/routes/scim.d.ts.map +1 -1
- package/dist/routes/scim.js +2 -0
- package/dist/routes/scim.js.map +1 -1
- package/dist/routes/serviceAccounts.d.ts.map +1 -1
- package/dist/routes/serviceAccounts.js +17 -1
- package/dist/routes/serviceAccounts.js.map +1 -1
- package/dist/routes/sessions.js +3 -3
- package/dist/routes/sessions.js.map +1 -1
- package/dist/routes/smsOtp.d.ts.map +1 -1
- package/dist/routes/smsOtp.js +10 -0
- package/dist/routes/smsOtp.js.map +1 -1
- package/dist/routes/totp.d.ts.map +1 -1
- package/dist/routes/totp.js +38 -6
- package/dist/routes/totp.js.map +1 -1
- package/dist/routes/webauthn.d.ts.map +1 -1
- package/dist/routes/webauthn.js +8 -2
- package/dist/routes/webauthn.js.map +1 -1
- package/dist/services/configuration/profiles.d.ts +26 -0
- package/dist/services/configuration/profiles.d.ts.map +1 -1
- package/dist/services/configuration/profiles.js +80 -1
- package/dist/services/configuration/profiles.js.map +1 -1
- package/dist/services/events/subscribers/auditLog.d.ts.map +1 -1
- package/dist/services/events/subscribers/auditLog.js +38 -3
- package/dist/services/events/subscribers/auditLog.js.map +1 -1
- package/dist/services/events/types.d.ts +3 -1
- package/dist/services/events/types.d.ts.map +1 -1
- package/dist/services/events/validate.d.ts +1 -0
- package/dist/services/events/validate.d.ts.map +1 -1
- package/dist/services/events/validate.js +5 -1
- package/dist/services/events/validate.js.map +1 -1
- package/dist/services/localRateLimit.d.ts +44 -0
- package/dist/services/localRateLimit.d.ts.map +1 -0
- package/dist/services/localRateLimit.js +86 -0
- package/dist/services/localRateLimit.js.map +1 -0
- package/dist/services/refreshTokenState.d.ts +5 -0
- package/dist/services/refreshTokenState.d.ts.map +1 -0
- package/dist/services/refreshTokenState.js +30 -0
- package/dist/services/refreshTokenState.js.map +1 -0
- package/dist/services/scopes.d.ts +113 -0
- package/dist/services/scopes.d.ts.map +1 -0
- package/dist/services/scopes.js +138 -0
- package/dist/services/scopes.js.map +1 -0
- package/dist/services/setup/token.d.ts +12 -0
- package/dist/services/setup/token.d.ts.map +1 -1
- package/dist/services/setup/token.js +27 -3
- package/dist/services/setup/token.js.map +1 -1
- package/dist/services/tokens.d.ts +1 -0
- package/dist/services/tokens.d.ts.map +1 -1
- package/dist/services/tokens.js +1 -1
- package/dist/services/tokens.js.map +1 -1
- package/dist/services/trustedProxies.d.ts +24 -0
- package/dist/services/trustedProxies.d.ts.map +1 -1
- package/dist/services/trustedProxies.js +19 -0
- package/dist/services/trustedProxies.js.map +1 -1
- package/dist/services/webhooks.d.ts +16 -0
- package/dist/services/webhooks.d.ts.map +1 -1
- package/dist/services/webhooks.js +48 -3
- package/dist/services/webhooks.js.map +1 -1
- package/dist/setup-server.js +47 -3
- package/dist/setup-server.js.map +1 -1
- package/docs/API-REVIEW.md +121 -0
- package/docs/API.md +457 -0
- package/docs/ARCHITECTURE.md +142 -0
- package/docs/CONTRIBUTING.md +61 -0
- package/docs/DEPLOYMENT.md +257 -0
- package/docs/INTEGRATION.md +336 -0
- package/docs/LOGIN_FORM_INTEGRATION.md +306 -0
- package/docs/MIGRATION-1.7.md +70 -0
- package/docs/MIGRATION-1.8.md +183 -0
- package/docs/MIGRATION-1.9.md +200 -0
- package/docs/MIGRATION-2.0.md +203 -0
- package/docs/MIGRATION-2.4.md +185 -0
- package/docs/PERFORMANCE.md +155 -0
- package/docs/RBAC.md +100 -0
- package/docs/RE-AUDIT.md +72 -0
- package/docs/README.md +54 -0
- package/docs/RELEASE-1.7.md +53 -0
- package/docs/ROADMAP.md +41 -0
- package/docs/SECURITY.md +143 -0
- package/docs/adrs/001-identity-connectors-as-adapters.md +27 -0
- package/docs/adrs/002-versioned-event-bus.md +30 -0
- package/docs/adrs/003-bullmq-for-background-work.md +20 -0
- package/docs/adrs/004-argon2id-password-hashing.md +19 -0
- package/docs/plans/KEYSTONE_IMPROVEMENT_PLAN.md +334 -0
- package/docs/plans/UI_SIMPLIFICATION_IMPROVEMENT_PLAN.md +271 -0
- package/docs/security/audit.md +82 -0
- package/docs/security/configuration.md +60 -0
- package/docs/security/enterprise-sso.md +193 -0
- package/docs/security/mtls.md +132 -0
- package/docs/security/proxy-security.md +128 -0
- package/docs/security/rate-limiting.md +79 -0
- package/docs/security/registry-exceptions.md +34 -0
- package/docs/security/registry.json +649 -0
- package/docs/security/registry.md +657 -0
- package/docs/security/scopes.md +45 -0
- package/docs/security/supply-chain.md +49 -0
- package/docs/security/trust-boundaries.md +111 -0
- package/package.json +15 -6
|
@@ -87,4 +87,28 @@ export declare function describeUntrustedPeer(address: string): string | null;
|
|
|
87
87
|
export declare function isValidFingerprint(value: string | undefined): value is string;
|
|
88
88
|
/** Canonical fingerprint form used for storage and comparison. */
|
|
89
89
|
export declare function canonicalFingerprint(value: string): string;
|
|
90
|
+
/**
|
|
91
|
+
* CORS origin policy.
|
|
92
|
+
*
|
|
93
|
+
* Extracted so the server and the tests share one implementation. An earlier
|
|
94
|
+
* version of this policy lived inline in `index.ts`, which meant a test could only
|
|
95
|
+
* assert against a *copy* of it — a copy that would have kept passing while the
|
|
96
|
+
* real code was reverted.
|
|
97
|
+
*/
|
|
98
|
+
export interface CorsPolicy {
|
|
99
|
+
allowedOrigins: string[];
|
|
100
|
+
nodeEnv: string;
|
|
101
|
+
/**
|
|
102
|
+
* Origins permitted in addition to the allowlist. The setup server uses this to
|
|
103
|
+
* default to its own loopback addresses; the main server leaves it empty.
|
|
104
|
+
*/
|
|
105
|
+
additionallyAllowed?: string[];
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Whether a request's `Origin` may be used for a credentialed cross-origin call.
|
|
109
|
+
*
|
|
110
|
+
* A request with no `Origin` is not a cross-origin request — it is curl, a
|
|
111
|
+
* server-to-server call, or a same-origin navigation — so it is allowed.
|
|
112
|
+
*/
|
|
113
|
+
export declare function isOriginAllowed(origin: string | undefined, policy: CorsPolicy): boolean;
|
|
90
114
|
//# sourceMappingURL=trustedProxies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trustedProxies.d.ts","sourceRoot":"","sources":["../../src/services/trustedProxies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,YAC3B,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,+BAA+B,CACvB,CAAC;AAKX;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAwBpE;AAeD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAwCpE;AAoBD,yEAAyE;AACzE,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMnE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAE3D;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAEnE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAW7D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAMtE;AAED,+DAA+D;AAC/D,wBAAgB,wBAAwB,IAAI,OAAO,GAAG,MAAM,EAAE,CAG7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAmBhE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASpE;AAKD,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,CAI7E;AAED,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D"}
|
|
1
|
+
{"version":3,"file":"trustedProxies.d.ts","sourceRoot":"","sources":["../../src/services/trustedProxies.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,YAC3B,yBAAyB,EACzB,2BAA2B,EAC3B,sBAAsB,EACtB,+BAA+B,CACvB,CAAC;AAKX;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAwBpE;AAeD,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAwCpE;AAoBD,yEAAyE;AACzE,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMnE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAE3D;AAED,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAEnE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAW7D;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAMtE;AAED,+DAA+D;AAC/D,wBAAgB,wBAAwB,IAAI,OAAO,GAAG,MAAM,EAAE,CAG7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAmBhE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASpE;AAKD,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,CAI7E;AAED,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAQvF"}
|
|
@@ -280,4 +280,23 @@ export function isValidFingerprint(value) {
|
|
|
280
280
|
export function canonicalFingerprint(value) {
|
|
281
281
|
return value.trim().replace(/:/g, "").toLowerCase();
|
|
282
282
|
}
|
|
283
|
+
/**
|
|
284
|
+
* Whether a request's `Origin` may be used for a credentialed cross-origin call.
|
|
285
|
+
*
|
|
286
|
+
* A request with no `Origin` is not a cross-origin request — it is curl, a
|
|
287
|
+
* server-to-server call, or a same-origin navigation — so it is allowed.
|
|
288
|
+
*/
|
|
289
|
+
export function isOriginAllowed(origin, policy) {
|
|
290
|
+
if (!origin)
|
|
291
|
+
return true;
|
|
292
|
+
if (policy.allowedOrigins.includes(origin))
|
|
293
|
+
return true;
|
|
294
|
+
if (policy.additionallyAllowed?.includes(origin))
|
|
295
|
+
return true;
|
|
296
|
+
// Development convenience so an external test project can connect without
|
|
297
|
+
// being registered first. Scoped to localhost, and never active in production.
|
|
298
|
+
if (policy.nodeEnv !== "production" && origin.startsWith("http://localhost:"))
|
|
299
|
+
return true;
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
283
302
|
//# sourceMappingURL=trustedProxies.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trustedProxies.js","sourceRoot":"","sources":["../../src/services/trustedProxies.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"trustedProxies.js","sourceRoot":"","sources":["../../src/services/trustedProxies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAGtC;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,yBAAyB;IACzB,2BAA2B;IAC3B,sBAAsB;IACtB,+BAA+B;CACvB,CAAC;AAEX,0DAA0D;AAC1D,MAAM,iBAAiB,GAAG,CAAC,iBAAiB,EAAE,WAAW,EAAE,WAAW,CAAU,CAAC;AAEjF;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA2B;IAC1D,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7E,uDAAuD;IACvD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,IAAI,KAAK,CAAC,CAAC;QAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAE9C,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,wDAAwD;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5E,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrC,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpD,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG;YAAE,OAAO,IAAI,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,IAAY;IACzD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEpC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,MAAM,KAAK,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAEpE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAE1C,MAAM,YAAY,GAAG,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,YAAY,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5D,IAAI,CAAC,YAAY,IAAI,CAAC,WAAW,EAAE,CAAC;QAClC,yEAAyE;QACzE,mDAAmD;QACnD,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,GAAG;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,IAAI,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClD,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClD,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAC;QACzC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAE5B,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,SAAS,IAAI,CAAC;YAAE,MAAM;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;QAC1D,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACnE,SAAS,IAAI,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,IAAI,YAAY,GAA8C,IAAI,CAAC;AAEnE;;;;GAIG;AACH,SAAS,cAAc;IACrB,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1F,IAAI,YAAY,EAAE,GAAG,KAAK,GAAG;QAAE,OAAO,YAAY,CAAC,OAAO,CAAC;IAC3D,MAAM,OAAO,GAAG,GAAG;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,YAAY,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAChC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,sBAAsB;IACpC,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,cAAc,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAA2B;IACxD,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAuB;IACjD,OAAO,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,OAAuB;IACxD,OAAO,cAAc,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,OAAuB;IACnD,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;QAAE,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;IAE9D,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC/C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACxC,IAAI,KAAK;YAAE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE;QAAE,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACjF,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAuB;IAC3D,IAAI,kBAAkB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,gBAAgB,EAAE,GAAG,iBAAiB,CAAC,EAAE,CAAC;QACjE,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,wBAAwB;IACtC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1F,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,4BAA4B,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,uEAAuE;IACvE,uEAAuE;IACvE,wEAAwE;IACxE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACvD,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QAC7C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,IAAI,iBAAiB,EAAE;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,OAAO,CACL,6EAA6E;QAC7E,4EAA4E;QAC5E,+EAA+E;QAC/E,wFAAwF,CACzF,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAC1C,MAAM,iBAAiB,GAAG,oCAAoC,CAAC;AAE/D,+EAA+E;AAC/E,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAChF,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACtD,CAAC;AAoBD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAA0B,EAAE,MAAkB;IAC5E,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACxD,IAAI,MAAM,CAAC,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9D,0EAA0E;IAC1E,+EAA+E;IAC/E,IAAI,MAAM,CAAC,OAAO,KAAK,YAAY,IAAI,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3F,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import { type WebhookEndpoint } from "../db/schema.js";
|
|
2
2
|
import type { KeystoneEvent } from "./events/types.js";
|
|
3
3
|
export type { WebhookEndpoint };
|
|
4
|
+
/**
|
|
5
|
+
* Read a stored secret, accepting both the encrypted envelope and legacy
|
|
6
|
+
* plaintext.
|
|
7
|
+
*
|
|
8
|
+
* `decryptSecret` cannot be used directly: it throws on anything that is not an
|
|
9
|
+
* encrypted envelope, and the alternative it offers is a legacy *CBC* form, not
|
|
10
|
+
* plaintext. Every webhook secret written before this change is plain, so
|
|
11
|
+
* delegating to it would have thrown on the first delivery for every existing
|
|
12
|
+
* endpoint.
|
|
13
|
+
*
|
|
14
|
+
* So the envelope is detected here and anything else is returned unchanged.
|
|
15
|
+
* A plaintext secret is `whsec_` followed by base64url, which contains neither
|
|
16
|
+
* the `.` of the versioned envelope nor the `:` of the legacy CBC form, so the
|
|
17
|
+
* test is unambiguous.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readWebhookSecret(stored: string): string;
|
|
4
20
|
export declare function listEndpoints(appId?: string): Promise<{
|
|
5
21
|
id: string;
|
|
6
22
|
appId: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/services/webhooks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuC,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/services/webhooks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuC,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAI5F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKvD,YAAY,EAAE,eAAe,EAAE,CAAC;AA0BhC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAsB,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM;;;;;;;;;;KAKjD;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG,OAAO,CAAC,eAAe,GAAG;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAcvD;AAED,wBAAsB,cAAc,CAClC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC;;;;;;;;;;GAQjG;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;GAG9C;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;eAQpD;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,SAAK;;;;;;;;;;;KAOlE;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BvE;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDlE;AAUD,qEAAqE;AACrE,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASxE;AAED,mDAAmD;AACnD,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC"}
|
|
@@ -3,9 +3,53 @@ import { and, desc, eq } from "drizzle-orm";
|
|
|
3
3
|
import { db } from "../db/index.js";
|
|
4
4
|
import { webhookDeliveries, webhookEndpoints } from "../db/schema.js";
|
|
5
5
|
import { signWebhookPayload } from "../lib/webhookSignature.js";
|
|
6
|
+
import { decryptSecret, encryptSecret } from "./totp.js";
|
|
6
7
|
import { queue } from "./queue/index.js";
|
|
7
8
|
const MAX_ATTEMPTS = 5;
|
|
8
9
|
const RETRY_DELAY_MS = 30_000;
|
|
10
|
+
/**
|
|
11
|
+
* Webhook signing secrets are encrypted at rest.
|
|
12
|
+
*
|
|
13
|
+
* Not hashed, which is the more usual answer for a credential, because Keystone
|
|
14
|
+
* *signs* outbound payloads with this secret rather than merely comparing
|
|
15
|
+
* against it. Hashing would make signing impossible; the plaintext has to be
|
|
16
|
+
* recoverable, so recoverable secrets are the ones that must be encrypted.
|
|
17
|
+
*
|
|
18
|
+
* Stored in plaintext, a database dump yielded a working signing key for every
|
|
19
|
+
* endpoint, letting an attacker forge deliveries the receiving service would
|
|
20
|
+
* accept as genuine.
|
|
21
|
+
*
|
|
22
|
+
* Rows written before this change are still plaintext. `decryptSecret` detects
|
|
23
|
+
* the versioned envelope and falls back to returning the value unchanged, so
|
|
24
|
+
* existing endpoints keep verifying without a migration step; re-saving or
|
|
25
|
+
* rotating an endpoint upgrades it.
|
|
26
|
+
*/
|
|
27
|
+
function encryptWebhookSecret(secret) {
|
|
28
|
+
return encryptSecret(secret);
|
|
29
|
+
}
|
|
30
|
+
/** Mirrors the envelope prefix used by `encryptSecret`. */
|
|
31
|
+
const ENCRYPTED_SECRET_PREFIX = "v2";
|
|
32
|
+
/**
|
|
33
|
+
* Read a stored secret, accepting both the encrypted envelope and legacy
|
|
34
|
+
* plaintext.
|
|
35
|
+
*
|
|
36
|
+
* `decryptSecret` cannot be used directly: it throws on anything that is not an
|
|
37
|
+
* encrypted envelope, and the alternative it offers is a legacy *CBC* form, not
|
|
38
|
+
* plaintext. Every webhook secret written before this change is plain, so
|
|
39
|
+
* delegating to it would have thrown on the first delivery for every existing
|
|
40
|
+
* endpoint.
|
|
41
|
+
*
|
|
42
|
+
* So the envelope is detected here and anything else is returned unchanged.
|
|
43
|
+
* A plaintext secret is `whsec_` followed by base64url, which contains neither
|
|
44
|
+
* the `.` of the versioned envelope nor the `:` of the legacy CBC form, so the
|
|
45
|
+
* test is unambiguous.
|
|
46
|
+
*/
|
|
47
|
+
export function readWebhookSecret(stored) {
|
|
48
|
+
if (stored.startsWith(`${ENCRYPTED_SECRET_PREFIX}.`)) {
|
|
49
|
+
return decryptSecret(stored);
|
|
50
|
+
}
|
|
51
|
+
return stored;
|
|
52
|
+
}
|
|
9
53
|
export async function listEndpoints(appId) {
|
|
10
54
|
if (appId) {
|
|
11
55
|
return db.select().from(webhookEndpoints).where(eq(webhookEndpoints.appId, appId)).orderBy(webhookEndpoints.createdAt);
|
|
@@ -21,7 +65,8 @@ export async function createEndpoint(input) {
|
|
|
21
65
|
url: input.url,
|
|
22
66
|
description: input.description ?? null,
|
|
23
67
|
events: input.events ?? [],
|
|
24
|
-
|
|
68
|
+
// Encrypted at rest; the plaintext is returned exactly once, at creation.
|
|
69
|
+
secret: encryptWebhookSecret(secret),
|
|
25
70
|
})
|
|
26
71
|
.returning();
|
|
27
72
|
return { ...endpoint, signingSecret: secret };
|
|
@@ -42,7 +87,7 @@ export async function rotateEndpointSecret(id) {
|
|
|
42
87
|
const secret = `whsec_${crypto.randomBytes(24).toString("base64url")}`;
|
|
43
88
|
const [updated] = await db
|
|
44
89
|
.update(webhookEndpoints)
|
|
45
|
-
.set({ secret, updatedAt: new Date() })
|
|
90
|
+
.set({ secret: encryptWebhookSecret(secret), updatedAt: new Date() })
|
|
46
91
|
.where(eq(webhookEndpoints.id, id))
|
|
47
92
|
.returning();
|
|
48
93
|
return updated ? { endpoint: updated, signingSecret: secret } : undefined;
|
|
@@ -98,7 +143,7 @@ export async function deliverNow(deliveryId) {
|
|
|
98
143
|
method: "POST",
|
|
99
144
|
headers: {
|
|
100
145
|
"Content-Type": "application/json",
|
|
101
|
-
"X-Keystone-Signature": signWebhookPayload(endpoint.secret, delivery.payload),
|
|
146
|
+
"X-Keystone-Signature": signWebhookPayload(readWebhookSecret(endpoint.secret), delivery.payload),
|
|
102
147
|
"X-Keystone-Event": delivery.eventType,
|
|
103
148
|
"X-Keystone-Delivery": delivery.id,
|
|
104
149
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/services/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAwB,MAAM,iBAAiB,CAAC;AAC5F,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,cAAc,GAAG,MAAM,CAAC;AAI9B,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAc;IAChD,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACzH,CAAC;IACD,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAKpC;IACC,MAAM,MAAM,GAAG,SAAS,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;IACvE,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,EAAE;SACxB,MAAM,CAAC,gBAAgB,CAAC;SACxB,MAAM,CAAC;QACN,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI;QAC1B,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;QACtC,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;QAC1B,MAAM;
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/services/webhooks.ts"],"names":[],"mappings":"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"}
|
package/dist/setup-server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { fastifyTrustProxySetting } from "./services/trustedProxies.js";
|
|
2
|
+
import { fastifyTrustProxySetting, isOriginAllowed } from "./services/trustedProxies.js";
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import fastify from "fastify";
|
|
@@ -14,8 +14,24 @@ async function buildSetupApp() {
|
|
|
14
14
|
trustProxy: fastifyTrustProxySetting(),
|
|
15
15
|
genReqId: () => crypto.randomUUID(),
|
|
16
16
|
});
|
|
17
|
+
// The setup server creates the owner account and writes configuration. It
|
|
18
|
+
// previously reflected any origin with credentials, so any page a browser
|
|
19
|
+
// visited could attempt a credentialed request against it. Origins must now be
|
|
20
|
+
// listed explicitly.
|
|
21
|
+
//
|
|
22
|
+
// Empty means no browser origin at all, which is the right default: setup is
|
|
23
|
+
// normally driven from the same machine, and a server-to-server client sends
|
|
24
|
+
// no Origin header.
|
|
25
|
+
const setupOrigins = (config.ALLOWED_ORIGINS.length > 0
|
|
26
|
+
? config.ALLOWED_ORIGINS
|
|
27
|
+
: [`http://localhost:${config.PORT}`, `http://127.0.0.1:${config.PORT}`]).filter((origin) => /^https?:\/\//.test(origin));
|
|
17
28
|
await app.register(cors, {
|
|
18
|
-
origin:
|
|
29
|
+
origin: (origin, cb) => {
|
|
30
|
+
if (isOriginAllowed(origin, { allowedOrigins: config.ALLOWED_ORIGINS, nodeEnv: config.NODE_ENV, additionallyAllowed: setupOrigins })) {
|
|
31
|
+
return cb(null, true);
|
|
32
|
+
}
|
|
33
|
+
cb(new Error("Origin not allowed"), false);
|
|
34
|
+
},
|
|
19
35
|
credentials: true,
|
|
20
36
|
});
|
|
21
37
|
await app.register(setupRoutes, { prefix: "/setup" });
|
|
@@ -45,12 +61,40 @@ async function buildSetupApp() {
|
|
|
45
61
|
});
|
|
46
62
|
return app;
|
|
47
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Interface the setup server binds to.
|
|
66
|
+
*
|
|
67
|
+
* The main server defaults to `0.0.0.0`, which is right for it and wrong for
|
|
68
|
+
* this one: the setup surface creates the owner account and writes
|
|
69
|
+
* configuration, and a full-initialisation credential should not be reachable
|
|
70
|
+
* from the internet because someone copied a default from the main server.
|
|
71
|
+
*
|
|
72
|
+
* Defaults to loopback. Set `KEYSTONE_SETUP_HOST` to a private interface
|
|
73
|
+
* address to serve a trusted network, or to `0.0.0.0` deliberately — which logs
|
|
74
|
+
* a warning, because that is the decision this default exists to make explicit.
|
|
75
|
+
*/
|
|
76
|
+
function setupBindHost() {
|
|
77
|
+
const explicit = process.env.KEYSTONE_SETUP_HOST?.trim();
|
|
78
|
+
if (explicit)
|
|
79
|
+
return explicit;
|
|
80
|
+
if (config.HOST === "0.0.0.0" || config.HOST === "::")
|
|
81
|
+
return "127.0.0.1";
|
|
82
|
+
return config.HOST;
|
|
83
|
+
}
|
|
48
84
|
async function start() {
|
|
49
85
|
generateSetupToken();
|
|
50
86
|
printSetupToken();
|
|
51
87
|
const app = await buildSetupApp();
|
|
88
|
+
const host = setupBindHost();
|
|
89
|
+
if (host === "0.0.0.0" || host === "::") {
|
|
90
|
+
app.log.warn("Setup server is binding to all interfaces. It creates the owner account and writes " +
|
|
91
|
+
"configuration; bind it to loopback or a private interface unless this is intended.");
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
app.log.info(`Setup server bound to ${host}`);
|
|
95
|
+
}
|
|
52
96
|
try {
|
|
53
|
-
await app.listen({ port: config.PORT, host
|
|
97
|
+
await app.listen({ port: config.PORT, host });
|
|
54
98
|
app.log.info(`Hilbras Keystone setup server running on http://${config.HOST}:${config.PORT}`);
|
|
55
99
|
}
|
|
56
100
|
catch (err) {
|
package/dist/setup-server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-server.js","sourceRoot":"","sources":["../src/setup-server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"setup-server.js","sourceRoot":"","sources":["../src/setup-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# API security review
|
|
2
|
+
|
|
3
|
+
Scope: every route registered by the application, checked for the properties the
|
|
4
|
+
plan requires — authentication, authorization, tenant isolation, input validation,
|
|
5
|
+
output filtering, rate limiting, audit logging, error handling, sensitive data
|
|
6
|
+
exposure.
|
|
7
|
+
|
|
8
|
+
Generated by `npm run review:api` (`scripts/review-api-surface.mjs`), which
|
|
9
|
+
enumerates routes from the source and reports what guard each one carries. It
|
|
10
|
+
**reports rather than fails**: a public route legitimately has no authentication
|
|
11
|
+
and a read legitimately has no rate limit, so the judgement about which
|
|
12
|
+
combinations are correct belongs to whoever reads the output. What the script
|
|
13
|
+
removes is the risk of a review that quietly misses a route.
|
|
14
|
+
|
|
15
|
+
## Result
|
|
16
|
+
|
|
17
|
+
| Property | Coverage |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| Routes enumerated | 69 across 19 files |
|
|
20
|
+
| With an authentication guard | 60, plus 12 that authenticate in a plugin hook or are public by design |
|
|
21
|
+
| **With no authentication guard** | **0** |
|
|
22
|
+
| With an explicit authorization guard | 33 |
|
|
23
|
+
| With a rate limit | 17 |
|
|
24
|
+
| In a module that audits | 65 |
|
|
25
|
+
|
|
26
|
+
Every route either authenticates, authenticates through a plugin-scoped
|
|
27
|
+
`onRequest` hook, or is public by design with a stated reason.
|
|
28
|
+
|
|
29
|
+
## The tool was wrong four times before it was right
|
|
30
|
+
|
|
31
|
+
Worth recording, because the corrections are the review.
|
|
32
|
+
|
|
33
|
+
1. **No prefix resolution.** `/login` in `auth.ts` is really `/auth/login`. Every
|
|
34
|
+
such route read as unauthenticated — 59 findings, almost all false. A review
|
|
35
|
+
tool with fifty false positives gets ignored, which makes it worse than none.
|
|
36
|
+
Prefixes are now derived from `index.ts` rather than tabulated, so a route
|
|
37
|
+
added under a new prefix is covered without editing the script.
|
|
38
|
+
2. **`requirePlatformRole` and `requireOwner` were not counted as
|
|
39
|
+
authentication.** They authenticate and then check a role. The tool was
|
|
40
|
+
reporting the owner-only configuration routes as having no authentication
|
|
41
|
+
guard — accusing the most strongly guarded routes in the codebase of being
|
|
42
|
+
open.
|
|
43
|
+
3. **`app.requirePermission` was not counted as authentication**, for the same
|
|
44
|
+
reason. Seven service-account routes were flagged.
|
|
45
|
+
4. **`factorRateLimit(...)` was not matched.** It builds a limiter through a
|
|
46
|
+
local factory, so five TOTP routes were reported as unlimited when every one
|
|
47
|
+
of them is limited.
|
|
48
|
+
|
|
49
|
+
Each was found by reading the output and asking why a route I knew was guarded had
|
|
50
|
+
been flagged. A tool that produces findings nobody reads has failed at its only
|
|
51
|
+
job.
|
|
52
|
+
|
|
53
|
+
## Authorization: 27 routes, all verified
|
|
54
|
+
|
|
55
|
+
| Module | Routes | Why there is no route-level guard |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `scim.ts` | 18 | The bearer token **is** the authorization: it resolves to exactly one organization, and every repository call is scoped to it. Enforced in a plugin-scoped `onRequest` hook. |
|
|
58
|
+
| `workflows.ts` | 5 | Checked in the handler, not a guard — see below. |
|
|
59
|
+
| `serviceAccounts.ts` | 5 | `app.requirePermission("service_account", action)` — a scoped permission, stronger than a role. |
|
|
60
|
+
| `auth.ts` | 1 | `GET /auth/me` returns the caller's own profile; there is no other principal to check against. |
|
|
61
|
+
| `authz.ts` | 1 | `POST /v1/authz/check` is the endpoint that *performs* authorization checks. |
|
|
62
|
+
| `oauth2.ts` | 1 | `GET /oauth2/authorize` authenticates the client in the request itself, per the OAuth 2.0 specification. |
|
|
63
|
+
| `emailVerification.ts` | 1 | `POST /auth/email-verification/send` mails the caller's own address. |
|
|
64
|
+
|
|
65
|
+
### One real weakness: authorization in handlers, not guards
|
|
66
|
+
|
|
67
|
+
`src/routes/workflows.ts` checks organization membership **inside each handler**
|
|
68
|
+
rather than in a `preHandler`, and does so correctly:
|
|
69
|
+
|
|
70
|
+
- a workflow with no `orgId` is global and requires the platform owner role
|
|
71
|
+
- a workflow with an `orgId` requires membership in *that* organization
|
|
72
|
+
|
|
73
|
+
So there is no live vulnerability — this is the Phase 1 fix, working. The problem
|
|
74
|
+
is structural: five routes each re-implement the check, and a sixth added later
|
|
75
|
+
would have no reason to include it. Every other module in the codebase puts this
|
|
76
|
+
in a guard, which is why a new route gets it by default. Here it does not.
|
|
77
|
+
|
|
78
|
+
Consolidating the five handlers behind `requireOrganizationRole` is the obvious
|
|
79
|
+
remedy and is not done here, because a partial migration would be worse than the
|
|
80
|
+
consistent thing the file does now.
|
|
81
|
+
|
|
82
|
+
## Rate limiting: 30 state-changing routes are deliberately unlimited
|
|
83
|
+
|
|
84
|
+
Every endpoint the plan names as sensitive is limited: login, register, password
|
|
85
|
+
reset, magic link, email verification, MFA (enrol, verify, disable, backup, and
|
|
86
|
+
step-up), SMS OTP, OAuth authorize and token, SCIM, and API key creation.
|
|
87
|
+
|
|
88
|
+
The un-limited remainder are authenticated operations where the request already
|
|
89
|
+
carries a valid session: patching a profile, deleting a session, revoking an API
|
|
90
|
+
key, updating configuration, connecting a federation provider, verifying a
|
|
91
|
+
WebAuthn registration. A budget on these bounds a legitimate user rather than an
|
|
92
|
+
attacker, since an attacker without a session never reaches them.
|
|
93
|
+
|
|
94
|
+
Recorded as a decision rather than a gap, so a future reviewer can disagree with
|
|
95
|
+
it rather than rediscover it.
|
|
96
|
+
|
|
97
|
+
## Public by design
|
|
98
|
+
|
|
99
|
+
Eleven routes are reachable without authentication, each with a stated reason in
|
|
100
|
+
the script. The two worth naming:
|
|
101
|
+
|
|
102
|
+
- `POST /auth/email-verification/request` takes an address and mails a link. It is
|
|
103
|
+
limited to 3 per 15 minutes, and answers `200` for unknown *and* already-verified
|
|
104
|
+
addresses, so it neither mails an unregistered address nor reveals which
|
|
105
|
+
addresses have accounts.
|
|
106
|
+
- `POST /auth/forgot-password` and the magic-link equivalents follow the same
|
|
107
|
+
shape: uniform response, limited, no enumeration.
|
|
108
|
+
|
|
109
|
+
## Input validation and error handling
|
|
110
|
+
|
|
111
|
+
Not visible to a route-level script — validation happens at three different layers
|
|
112
|
+
(schema `parse`/`safeParse` in the handler, Fastify schema, domain validation), so
|
|
113
|
+
an automated check here would report either everything or nothing. Audited by
|
|
114
|
+
reading instead: every handler that reads `request.body` parses it with a Zod
|
|
115
|
+
schema before use, and failures return the parsed issues rather than a stack.
|
|
116
|
+
|
|
117
|
+
## Not covered by this review
|
|
118
|
+
|
|
119
|
+
- Runtime behaviour. This reads source; it does not exercise the routes.
|
|
120
|
+
- The 7 route files whose mount prefix is not registered in `index.ts`. They are
|
|
121
|
+
listed by the script when it runs, so the gap is visible rather than silent.
|