@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
package/dist/index.js
CHANGED
|
@@ -11,7 +11,7 @@ import { config } from "./config.js";
|
|
|
11
11
|
import { db } from "./db/index.js";
|
|
12
12
|
import { initializeContainer } from "./di.js";
|
|
13
13
|
import { getContainer } from "./container.js";
|
|
14
|
-
import { fastifyTrustProxySetting } from "./services/trustedProxies.js";
|
|
14
|
+
import { fastifyTrustProxySetting, isOriginAllowed } from "./services/trustedProxies.js";
|
|
15
15
|
import { redis } from "./services/redis.js";
|
|
16
16
|
import { loadSigningKeys, getPublicJwks } from "./services/tokens.js";
|
|
17
17
|
import { loadWorkflows } from "./services/workflows/engine.js";
|
|
@@ -33,6 +33,7 @@ import appContextPlugin from "./plugins/appContext.js";
|
|
|
33
33
|
import permissionsPlugin from "./plugins/permissions.js";
|
|
34
34
|
import mtlsPlugin from "./plugins/mtls.js";
|
|
35
35
|
import headerSanitization from "./plugins/headerSanitization.js";
|
|
36
|
+
import machinePrincipal from "./plugins/machinePrincipal.js";
|
|
36
37
|
import metricsPlugin from "./plugins/metrics.js";
|
|
37
38
|
import { globalRateLimit } from "./plugins/rateLimit.js";
|
|
38
39
|
import authRoutes from "./routes/auth.js";
|
|
@@ -101,7 +102,7 @@ export async function buildApp() {
|
|
|
101
102
|
info: {
|
|
102
103
|
title: "Hilbras Keystone API",
|
|
103
104
|
description: "Identity platform API for Hilbras products and third-party apps.",
|
|
104
|
-
version: "
|
|
105
|
+
version: "3.0.0",
|
|
105
106
|
},
|
|
106
107
|
servers: [{ url: config.AUTH_API_PUBLIC_URL || `http://localhost:${config.PORT}` }],
|
|
107
108
|
tags: [
|
|
@@ -114,17 +115,21 @@ export async function buildApp() {
|
|
|
114
115
|
await app.register(swaggerUi, {
|
|
115
116
|
routePrefix: "/documentation",
|
|
116
117
|
});
|
|
118
|
+
// Logged once at boot so a misconfiguration is visible before it matters,
|
|
119
|
+
// rather than only when a browser is refused.
|
|
120
|
+
if (config.ALLOWED_ORIGINS.length === 0) {
|
|
121
|
+
app.log.warn(config.NODE_ENV === "production"
|
|
122
|
+
? "ALLOWED_ORIGINS is empty in production: every cross-origin request will be refused. " +
|
|
123
|
+
"Set it to the exact origins that serve your frontend."
|
|
124
|
+
: "ALLOWED_ORIGINS is empty: any localhost origin is allowed in development.");
|
|
125
|
+
}
|
|
117
126
|
await app.register(cors, {
|
|
118
127
|
origin: (origin, cb) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (config.ALLOWED_ORIGINS.
|
|
124
|
-
return cb(null, true);
|
|
125
|
-
// In development, allow any localhost origin so external test projects
|
|
126
|
-
// can connect without pre-registering them in ALLOWED_ORIGINS.
|
|
127
|
-
if (config.NODE_ENV !== "production" && origin?.startsWith("http://localhost:")) {
|
|
128
|
+
// Previously an empty ALLOWED_ORIGINS returned true here, which made an
|
|
129
|
+
// unset variable equivalent to "allow every origin" on a server that sends
|
|
130
|
+
// credentialed cookies. Failing closed is the whole point: an unset variable
|
|
131
|
+
// in production should refuse browsers, not hand them the session.
|
|
132
|
+
if (isOriginAllowed(origin, { allowedOrigins: config.ALLOWED_ORIGINS, nodeEnv: config.NODE_ENV })) {
|
|
128
133
|
return cb(null, true);
|
|
129
134
|
}
|
|
130
135
|
cb(new Error("Origin not allowed"), false);
|
|
@@ -181,6 +186,7 @@ export async function buildApp() {
|
|
|
181
186
|
}));
|
|
182
187
|
await app.register(appContextPlugin);
|
|
183
188
|
await app.register(authPlugin);
|
|
189
|
+
await app.register(machinePrincipal);
|
|
184
190
|
await app.register(permissionsPlugin);
|
|
185
191
|
await app.register(mtlsPlugin);
|
|
186
192
|
await app.register(metricsPlugin);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/plugins/auth.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ declare module "fastify" {
|
|
|
9
9
|
interface FastifyRequest {
|
|
10
10
|
serviceAccount?: typeof serviceAccounts.$inferSelect;
|
|
11
11
|
apiKeyScopes?: string[];
|
|
12
|
+
/** Set when a machine credential authenticated the request. */
|
|
13
|
+
apiKeyId?: string;
|
|
12
14
|
}
|
|
13
15
|
}
|
|
14
16
|
export declare function accessCookieName(clientId?: string): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/plugins/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI7E,OAAO,EAAkB,eAAe,EAAa,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/plugins/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAI7E,OAAO,EAAkB,eAAe,EAAa,MAAM,iBAAiB,CAAC;AAM7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,YAAY,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9E,oBAAoB,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACtF,aAAa,EAAE,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACzG;IAED,UAAU,cAAc;QACtB,cAAc,CAAC,EAAE,OAAO,eAAe,CAAC,YAAY,CAAC;QACrD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,+DAA+D;QAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;CACF;AAKD,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAmBD,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,YAAY,EACnB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAWN;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAIhF;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE9F;8BA6DgD,eAAe"}
|
package/dist/plugins/auth.js
CHANGED
|
@@ -5,6 +5,7 @@ import { db } from "../db/index.js";
|
|
|
5
5
|
import { apiKeys, users, serviceAccounts } from "../db/schema.js";
|
|
6
6
|
import { verifyAccessToken, hashApiKey } from "../services/tokens.js";
|
|
7
7
|
import { emit } from "../services/events/bus.js";
|
|
8
|
+
import { SERVICE_ACCOUNT_DEFAULT_SCOPES, hasScopes } from "../services/scopes.js";
|
|
8
9
|
const DEFAULT_ACCESS_COOKIE = config.COOKIE_NAME;
|
|
9
10
|
const DEFAULT_REFRESH_COOKIE = `${config.COOKIE_NAME}-refresh`;
|
|
10
11
|
export function accessCookieName(clientId) {
|
|
@@ -77,7 +78,7 @@ async function resolveUserFromApiKey(key, request) {
|
|
|
77
78
|
metadata: { keyId: keyRecord.id, scopes: keyRecord.scopes ?? [] },
|
|
78
79
|
},
|
|
79
80
|
});
|
|
80
|
-
return { user, scopes: keyRecord.scopes ?? [] };
|
|
81
|
+
return { user, scopes: keyRecord.scopes ?? [], keyId: keyRecord.id };
|
|
81
82
|
}
|
|
82
83
|
return undefined;
|
|
83
84
|
}
|
|
@@ -135,13 +136,18 @@ export default fp(async function authPlugin(app) {
|
|
|
135
136
|
if (apiKeyUser) {
|
|
136
137
|
request.user = apiKeyUser.user;
|
|
137
138
|
request.apiKeyScopes = apiKeyUser.scopes;
|
|
139
|
+
request.apiKeyId = apiKeyUser.keyId;
|
|
138
140
|
return;
|
|
139
141
|
}
|
|
140
142
|
const serviceAccountResult = await resolveServiceAccountFromApiKey(token);
|
|
141
143
|
if (serviceAccountResult) {
|
|
142
144
|
const { serviceAccount, keyId, scopes } = serviceAccountResult;
|
|
143
145
|
request.serviceAccount = serviceAccount;
|
|
144
|
-
|
|
146
|
+
// An explicit set from the registry, not a wildcard string. Service
|
|
147
|
+
// accounts are granted scopes explicitly and the grant is stored on the
|
|
148
|
+
// key, so revoking it is a data change rather than a code change.
|
|
149
|
+
request.apiKeyScopes = scopes.length > 0 ? scopes : SERVICE_ACCOUNT_DEFAULT_SCOPES;
|
|
150
|
+
request.apiKeyId = keyId;
|
|
145
151
|
await emit({
|
|
146
152
|
type: "api_key_used",
|
|
147
153
|
payload: {
|
|
@@ -180,12 +186,20 @@ export default fp(async function authPlugin(app) {
|
|
|
180
186
|
});
|
|
181
187
|
app.decorate("requireScopes", function requireScopes(...required) {
|
|
182
188
|
return async function scopeCheck(request, reply) {
|
|
183
|
-
//
|
|
184
|
-
|
|
189
|
+
// A session or bearer token carries the authority of a human and is
|
|
190
|
+
// governed by the permission system instead. Only machine credentials are
|
|
191
|
+
// scope-limited.
|
|
192
|
+
if (!request.apiKeyId)
|
|
185
193
|
return;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
// Fail closed. Previously the guard returned early whenever
|
|
195
|
+
// `apiKeyScopes` was absent, which is indistinguishable from "this is a
|
|
196
|
+
// session" — so a key that resolved without a scope list skipped the check
|
|
197
|
+
// entirely. Keying off `apiKeyId` removes the ambiguity.
|
|
198
|
+
if (!hasScopes(request.apiKeyScopes, required)) {
|
|
199
|
+
await request.audit("unauthorized_access", {
|
|
200
|
+
action: "insufficient_api_key_scope",
|
|
201
|
+
requiredScope: required.join(" "),
|
|
202
|
+
});
|
|
189
203
|
return reply.status(403).send({ error: "Insufficient API key scope", required });
|
|
190
204
|
}
|
|
191
205
|
};
|
package/dist/plugins/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/plugins/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAa,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/plugins/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { FastifyInstance } from "fastify";
|
|
2
|
+
declare module "fastify" {
|
|
3
|
+
interface FastifyInstance {
|
|
4
|
+
requireHumanPrincipal: () => (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Reject machine credentials on routes that only make sense for a person.
|
|
9
|
+
*
|
|
10
|
+
* A service account authenticates by presenting an API key, and the auth plugin
|
|
11
|
+
* then synthesizes a `request.user` so existing routes keep working. The
|
|
12
|
+
* synthesized principal has an id of `sa:<uuid>`, which matches no row in
|
|
13
|
+
* `users` and no row in `org_memberships`.
|
|
14
|
+
*
|
|
15
|
+
* That makes most routes fail by accident rather than by decision: a write keyed
|
|
16
|
+
* on `request.user.id` updates zero rows, and an org-permission check finds no
|
|
17
|
+
* membership and returns 403. Correct, but incidental — and it relies on every
|
|
18
|
+
* future route happening to key off the user id. A route that acted on
|
|
19
|
+
* `request.state.org`, or on the service account's own `orgId`, would not be
|
|
20
|
+
* stopped by any of that.
|
|
21
|
+
*
|
|
22
|
+
* So the boundary is stated rather than implied. On the routes this guard is
|
|
23
|
+
* applied to, a machine credential is refused with a 403 that says why, instead
|
|
24
|
+
* of being allowed through to fail somewhere less obvious.
|
|
25
|
+
*/
|
|
26
|
+
declare const _default: (app: FastifyInstance) => Promise<void>;
|
|
27
|
+
export default _default;
|
|
28
|
+
//# sourceMappingURL=machinePrincipal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"machinePrincipal.d.ts","sourceRoot":"","sources":["../../src/plugins/machinePrincipal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAE7E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,qBAAqB,EAAE,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC9F;CACF;AAED;;;;;;;;;;;;;;;;;;GAkBG;8BAC4D,eAAe"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fp from "fastify-plugin";
|
|
2
|
+
/**
|
|
3
|
+
* Reject machine credentials on routes that only make sense for a person.
|
|
4
|
+
*
|
|
5
|
+
* A service account authenticates by presenting an API key, and the auth plugin
|
|
6
|
+
* then synthesizes a `request.user` so existing routes keep working. The
|
|
7
|
+
* synthesized principal has an id of `sa:<uuid>`, which matches no row in
|
|
8
|
+
* `users` and no row in `org_memberships`.
|
|
9
|
+
*
|
|
10
|
+
* That makes most routes fail by accident rather than by decision: a write keyed
|
|
11
|
+
* on `request.user.id` updates zero rows, and an org-permission check finds no
|
|
12
|
+
* membership and returns 403. Correct, but incidental — and it relies on every
|
|
13
|
+
* future route happening to key off the user id. A route that acted on
|
|
14
|
+
* `request.state.org`, or on the service account's own `orgId`, would not be
|
|
15
|
+
* stopped by any of that.
|
|
16
|
+
*
|
|
17
|
+
* So the boundary is stated rather than implied. On the routes this guard is
|
|
18
|
+
* applied to, a machine credential is refused with a 403 that says why, instead
|
|
19
|
+
* of being allowed through to fail somewhere less obvious.
|
|
20
|
+
*/
|
|
21
|
+
export default fp(async function machinePrincipalBoundary(app) {
|
|
22
|
+
/**
|
|
23
|
+
* Refuse the request if a service account authenticated it.
|
|
24
|
+
*
|
|
25
|
+
* Place after `authenticate`, since that is what populates
|
|
26
|
+
* `request.serviceAccount`.
|
|
27
|
+
*/
|
|
28
|
+
app.decorate("requireHumanPrincipal", function requireHumanPrincipal() {
|
|
29
|
+
return async function humanPrincipalCheck(request, reply) {
|
|
30
|
+
if (!request.serviceAccount)
|
|
31
|
+
return;
|
|
32
|
+
await request.audit("unauthorized_access", {
|
|
33
|
+
action: "machine_principal_on_interactive_route",
|
|
34
|
+
serviceAccountId: request.serviceAccount.id,
|
|
35
|
+
method: request.method,
|
|
36
|
+
url: request.url,
|
|
37
|
+
});
|
|
38
|
+
return reply.status(403).send({
|
|
39
|
+
error: "This endpoint is for user sessions only",
|
|
40
|
+
code: "MACHINE_PRINCIPAL_REFUSED",
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=machinePrincipal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"machinePrincipal.js","sourceRoot":"","sources":["../../src/plugins/machinePrincipal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAShC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAe,EAAE,CAAC,KAAK,UAAU,wBAAwB,CAAC,GAAoB;IAC5E;;;;;OAKG;IACH,GAAG,CAAC,QAAQ,CAAC,uBAAuB,EAAE,SAAS,qBAAqB;QAClE,OAAO,KAAK,UAAU,mBAAmB,CAAC,OAAuB,EAAE,KAAmB;YACpF,IAAI,CAAC,OAAO,CAAC,cAAc;gBAAE,OAAO;YACpC,MAAM,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE;gBACzC,MAAM,EAAE,wCAAwC;gBAChD,gBAAgB,EAAE,OAAO,CAAC,cAAc,CAAC,EAAE;gBAC3C,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;YACH,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC5B,KAAK,EAAE,yCAAyC;gBAChD,IAAI,EAAE,2BAA2B;aAClC,CAAC,CAAC;QACL,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
2
2
|
import { clientAddress } from "../services/trustedProxies.js";
|
|
3
3
|
interface RateLimitPluginOptions {
|
|
4
4
|
keyPrefix: string;
|
|
@@ -10,12 +10,21 @@ interface RateLimitPluginOptions {
|
|
|
10
10
|
* one noisy identity provider cannot exhaust the budget of every other tenant.
|
|
11
11
|
*/
|
|
12
12
|
keyFrom?: (request: FastifyRequest) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Hold a local in-process budget while Redis is unavailable.
|
|
15
|
+
*
|
|
16
|
+
* Set this on endpoints where unlimited attempts are dangerous — anything that
|
|
17
|
+
* authenticates. It is weaker than the distributed limiter, because a client
|
|
18
|
+
* gets one budget per instance, but it is bounded, whereas failing open is not.
|
|
19
|
+
*/
|
|
20
|
+
emergencyLocalLimit?: boolean;
|
|
13
21
|
}
|
|
14
22
|
export interface GlobalRateLimitOptions {
|
|
15
23
|
maxRequests?: number;
|
|
16
24
|
windowSeconds?: number;
|
|
17
25
|
keyPrefix?: string;
|
|
18
26
|
}
|
|
27
|
+
/** Kept for callers that only need a yes/no, such as a pre-authentication budget. */
|
|
19
28
|
declare function isAllowed(key: string, maxAttempts: number, windowSeconds: number): Promise<boolean>;
|
|
20
29
|
/**
|
|
21
30
|
* Re-exported so a route that must run before the normal limiter (because it
|
|
@@ -27,10 +36,4 @@ export { clientAddress };
|
|
|
27
36
|
export { isAllowed };
|
|
28
37
|
export declare function rateLimit(options: RateLimitPluginOptions): (request: FastifyRequest, reply: FastifyReply) => Promise<undefined>;
|
|
29
38
|
export declare function globalRateLimit(options?: GlobalRateLimitOptions): (request: FastifyRequest, reply: FastifyReply) => Promise<undefined>;
|
|
30
|
-
export declare function appRateLimit(options: {
|
|
31
|
-
maxAttempts: number;
|
|
32
|
-
windowSeconds: number;
|
|
33
|
-
}): (request: FastifyRequest, reply: FastifyReply) => Promise<undefined>;
|
|
34
|
-
declare const _default: (app: FastifyInstance) => Promise<void>;
|
|
35
|
-
export default _default;
|
|
36
39
|
//# sourceMappingURL=rateLimit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAI9D,UAAU,sBAAsB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,MAAM,CAAC;IAC9C;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqFD,qFAAqF;AACrF,iBAAe,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlG;AAeD;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,+DAA+D;AAC/D,OAAO,EAAE,SAAS,EAAE,CAAC;AAuCrB,wBAAgB,SAAS,CAAC,OAAO,EAAE,sBAAsB,aACb,cAAc,SAAS,YAAY,wBAiB9E;AAED,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,aAKzB,cAAc,SAAS,YAAY,wBAY7E"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
-
import fp from "fastify-plugin";
|
|
3
2
|
import { redis, isRedisReady } from "../services/redis.js";
|
|
4
3
|
import { clientAddress } from "../services/trustedProxies.js";
|
|
4
|
+
import { localRateLimit } from "../services/localRateLimit.js";
|
|
5
|
+
import { emit } from "../services/events/bus.js";
|
|
5
6
|
/**
|
|
6
7
|
* Atomic sliding-window rate limit script.
|
|
7
8
|
*
|
|
@@ -27,23 +28,45 @@ redis.call("zadd", key, now, member)
|
|
|
27
28
|
redis.call("pexpire", key, windowMs)
|
|
28
29
|
return count
|
|
29
30
|
`;
|
|
30
|
-
async function
|
|
31
|
+
async function checkLimit(key, maxAttempts, windowSeconds, useEmergencyLocal) {
|
|
31
32
|
if (!isRedisReady()) {
|
|
32
|
-
//
|
|
33
|
-
|
|
33
|
+
// Redis is the primary control and is unavailable. Failing open removes the
|
|
34
|
+
// control exactly when an attacker would most like it gone, so sensitive
|
|
35
|
+
// endpoints fall back to a bounded in-process budget instead.
|
|
36
|
+
if (!useEmergencyLocal) {
|
|
37
|
+
return { allowed: true, limiter: "none" };
|
|
38
|
+
}
|
|
39
|
+
const result = localRateLimit(key, maxAttempts, windowSeconds);
|
|
40
|
+
return result.allowed
|
|
41
|
+
? { allowed: true, limiter: "local" }
|
|
42
|
+
: { allowed: false, limiter: "local", retryAfterSeconds: result.retryAfterSeconds };
|
|
34
43
|
}
|
|
35
|
-
const now = Date.now();
|
|
36
|
-
const member = `${now}:${cryptoRandom()}`;
|
|
37
44
|
try {
|
|
45
|
+
const now = Date.now();
|
|
46
|
+
const member = `${now}:${cryptoRandom()}`;
|
|
38
47
|
const count = (await redis.eval(slidingWindowLua, 1, key, windowSeconds * 1000, now, member, maxAttempts));
|
|
39
|
-
return
|
|
48
|
+
return {
|
|
49
|
+
allowed: count < maxAttempts,
|
|
50
|
+
limiter: "redis",
|
|
51
|
+
retryAfterSeconds: windowSeconds,
|
|
52
|
+
};
|
|
40
53
|
}
|
|
41
|
-
catch
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
catch {
|
|
55
|
+
// A Redis error mid-request is the same situation as Redis being down.
|
|
56
|
+
if (!useEmergencyLocal) {
|
|
57
|
+
return { allowed: true, limiter: "none" };
|
|
58
|
+
}
|
|
59
|
+
const result = localRateLimit(key, maxAttempts, windowSeconds);
|
|
60
|
+
return result.allowed
|
|
61
|
+
? { allowed: true, limiter: "local" }
|
|
62
|
+
: { allowed: false, limiter: "local", retryAfterSeconds: result.retryAfterSeconds };
|
|
45
63
|
}
|
|
46
64
|
}
|
|
65
|
+
/** Kept for callers that only need a yes/no, such as a pre-authentication budget. */
|
|
66
|
+
async function isAllowed(key, maxAttempts, windowSeconds) {
|
|
67
|
+
const decision = await checkLimit(key, maxAttempts, windowSeconds, false);
|
|
68
|
+
return decision.allowed;
|
|
69
|
+
}
|
|
47
70
|
function cryptoRandom() {
|
|
48
71
|
return crypto.randomBytes(8).toString("hex");
|
|
49
72
|
}
|
|
@@ -63,14 +86,48 @@ function clientIdentifier(request) {
|
|
|
63
86
|
export { clientAddress };
|
|
64
87
|
/** Raw sliding-window check, for the same pre-limiter case. */
|
|
65
88
|
export { isAllowed };
|
|
89
|
+
/**
|
|
90
|
+
* Report a refused request.
|
|
91
|
+
*
|
|
92
|
+
* A rate-limit trip used to leave no trace at all: the request was answered with
|
|
93
|
+
* a 429 and nothing was recorded. An operator therefore could not distinguish
|
|
94
|
+
* ordinary traffic from a sustained brute-force attempt against `login` or
|
|
95
|
+
* `mfa-verify` — the requests that most warrant attention were the only ones
|
|
96
|
+
* invisible in the log.
|
|
97
|
+
*
|
|
98
|
+
* `limiter` is included because "limited in Redis" and "limited in one process
|
|
99
|
+
* because Redis was down" call for different responses, and conflating them would
|
|
100
|
+
* hide a degraded control.
|
|
101
|
+
*/
|
|
102
|
+
async function reportLimited(request, options, decision) {
|
|
103
|
+
try {
|
|
104
|
+
await emit({
|
|
105
|
+
type: "rate_limit_triggered",
|
|
106
|
+
payload: {
|
|
107
|
+
keyPrefix: options.keyPrefix,
|
|
108
|
+
clientAddress: clientIdentifier(request),
|
|
109
|
+
maxAttempts: options.maxAttempts,
|
|
110
|
+
windowSeconds: options.windowSeconds,
|
|
111
|
+
limiter: decision.limiter,
|
|
112
|
+
requestId: request.id,
|
|
113
|
+
method: request.method,
|
|
114
|
+
path: request.url,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// A monitoring failure must not turn a 429 into a 500.
|
|
120
|
+
}
|
|
121
|
+
}
|
|
66
122
|
export function rateLimit(options) {
|
|
67
123
|
return async function preHandler(request, reply) {
|
|
68
124
|
const id = options.keyFrom ? options.keyFrom(request) : clientIdentifier(request);
|
|
69
125
|
const key = `${options.keyPrefix}:${id}:${request.body?.email ?? ""}`;
|
|
70
|
-
const
|
|
71
|
-
if (!allowed) {
|
|
126
|
+
const decision = await checkLimit(key, options.maxAttempts, options.windowSeconds, options.emergencyLocalLimit === true);
|
|
127
|
+
if (!decision.allowed) {
|
|
128
|
+
await reportLimited(request, options, decision);
|
|
72
129
|
return reply
|
|
73
|
-
.header("Retry-After", String(options.windowSeconds))
|
|
130
|
+
.header("Retry-After", String(decision.retryAfterSeconds ?? options.windowSeconds))
|
|
74
131
|
.status(429)
|
|
75
132
|
.send({ error: "Too many attempts. Please try again later." });
|
|
76
133
|
}
|
|
@@ -83,32 +140,14 @@ export function globalRateLimit(options = {}) {
|
|
|
83
140
|
return async function onRequest(request, reply) {
|
|
84
141
|
const id = clientIdentifier(request);
|
|
85
142
|
const key = `${keyPrefix}:${id}`;
|
|
86
|
-
const
|
|
87
|
-
if (!allowed) {
|
|
143
|
+
const decision = await checkLimit(key, maxRequests, windowSeconds, false);
|
|
144
|
+
if (!decision.allowed) {
|
|
145
|
+
await reportLimited(request, { keyPrefix, maxAttempts: maxRequests, windowSeconds }, decision);
|
|
88
146
|
return reply
|
|
89
|
-
.header("Retry-After", String(windowSeconds))
|
|
147
|
+
.header("Retry-After", String(decision.retryAfterSeconds ?? windowSeconds))
|
|
90
148
|
.status(429)
|
|
91
149
|
.send({ error: "Rate limit exceeded. Please slow down." });
|
|
92
150
|
}
|
|
93
151
|
};
|
|
94
152
|
}
|
|
95
|
-
export function appRateLimit(options) {
|
|
96
|
-
return async function preHandler(request, reply) {
|
|
97
|
-
const clientId = request.body?.client_id ?? "anonymous";
|
|
98
|
-
const id = clientIdentifier(request);
|
|
99
|
-
const key = `app:${clientId}:${id}`;
|
|
100
|
-
const allowed = await isAllowed(key, options.maxAttempts, options.windowSeconds);
|
|
101
|
-
if (!allowed) {
|
|
102
|
-
return reply
|
|
103
|
-
.header("Retry-After", String(options.windowSeconds))
|
|
104
|
-
.status(429)
|
|
105
|
-
.send({ error: "Too many attempts for this application. Please try again later." });
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
export default fp(async function rateLimitPlugin(app) {
|
|
110
|
-
app.addHook("onClose", async () => {
|
|
111
|
-
await redis.quit();
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
153
|
//# sourceMappingURL=rateLimit.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../src/plugins/rateLimit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../../src/routes/admin/organizations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAwF/D,wBAA8B,mBAAmB,CAAC,GAAG,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../../../src/routes/admin/organizations.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAwF/D,wBAA8B,mBAAmB,CAAC,GAAG,EAAE,eAAe,iBA6PrE"}
|
|
@@ -83,6 +83,8 @@ export default async function organizationsRoutes(app) {
|
|
|
83
83
|
keyPrefix: "create-org",
|
|
84
84
|
maxAttempts: 5,
|
|
85
85
|
windowSeconds: 3600,
|
|
86
|
+
// A Redis outage must not remove the limit on an endpoint worth brute-forcing.
|
|
87
|
+
emergencyLocalLimit: true,
|
|
86
88
|
}),
|
|
87
89
|
],
|
|
88
90
|
}, async (request, reply) => {
|