@lamalibre/create-lamaste 4.4.0 → 4.5.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 (150) hide show
  1. package/package.json +2 -2
  2. package/scripts/lamaste-priv +200 -16
  3. package/src/index.js +1 -0
  4. package/src/lib/backend-cookie.js +65 -0
  5. package/src/lib/ip-panel-vhost.js +208 -0
  6. package/src/lib/service-config.js +5 -3
  7. package/src/tasks/nginx.js +18 -135
  8. package/src/tasks/redeploy.js +39 -1
  9. package/vendor/docs/00-introduction/how-it-works.md +2 -2
  10. package/vendor/docs/00-introduction/quickstart.md +5 -5
  11. package/vendor/docs/00-introduction/what-is-lamaste.md +5 -5
  12. package/vendor/docs/01-concepts/authentication.md +1 -1
  13. package/vendor/docs/01-concepts/authorization.md +66 -48
  14. package/vendor/docs/01-concepts/certificates.md +3 -3
  15. package/vendor/docs/01-concepts/mtls.md +2 -2
  16. package/vendor/docs/01-concepts/security-model.md +70 -33
  17. package/vendor/docs/01-concepts/tickets.md +2 -2
  18. package/vendor/docs/01-concepts/tunneling.md +4 -4
  19. package/vendor/docs/02-guides/agent-setup.md +5 -5
  20. package/vendor/docs/02-guides/certificate-management.md +2 -2
  21. package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
  22. package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
  23. package/vendor/docs/02-guides/installation.md +3 -3
  24. package/vendor/docs/02-guides/managing-users.md +113 -25
  25. package/vendor/docs/02-guides/onboarding.md +2 -2
  26. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
  27. package/vendor/docs/03-architecture/installer-flow.md +2 -2
  28. package/vendor/docs/03-architecture/installer.md +4 -4
  29. package/vendor/docs/03-architecture/management-flow.md +3 -1
  30. package/vendor/docs/03-architecture/nginx-configuration.md +165 -18
  31. package/vendor/docs/03-architecture/overview.md +13 -17
  32. package/vendor/docs/03-architecture/panel-client.md +6 -6
  33. package/vendor/docs/03-architecture/panel-server.md +3 -2
  34. package/vendor/docs/03-architecture/state-management.md +4 -8
  35. package/vendor/docs/03-architecture/system-overview.md +1 -1
  36. package/vendor/docs/04-api-reference/agent-hosted-plugins.md +292 -23
  37. package/vendor/docs/04-api-reference/app-host.md +3 -3
  38. package/vendor/docs/04-api-reference/gatekeeper.md +60 -5
  39. package/vendor/docs/04-api-reference/lifecycle-hooks.md +15 -13
  40. package/vendor/docs/04-api-reference/onboarding.md +1 -1
  41. package/vendor/docs/04-api-reference/registry-and-oidc.md +6 -4
  42. package/vendor/docs/04-api-reference/tunnels.md +67 -29
  43. package/vendor/docs/04-api-reference/users.md +241 -45
  44. package/vendor/docs/05-operations/backup-and-restore.md +35 -26
  45. package/vendor/docs/05-operations/monitoring.md +39 -0
  46. package/vendor/docs/05-operations/uninstalling.md +2 -1
  47. package/vendor/docs/05-operations/upgrades.md +15 -6
  48. package/vendor/docs/06-reference/config-files.md +83 -189
  49. package/vendor/docs/06-reference/glossary.md +3 -3
  50. package/vendor/docs/06-reference/installer-flags.md +13 -13
  51. package/vendor/docs/06-reference/ports-and-services.md +25 -26
  52. package/vendor/docs/06-reference/troubleshooting.md +8 -8
  53. package/vendor/docs/gatekeeper-design.md +10 -8
  54. package/vendor/docs/identity-directory-design.md +48 -14
  55. package/vendor/docs/package.json +1 -1
  56. package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
  57. package/vendor/gatekeeper/dist/index.d.ts +2 -1
  58. package/vendor/gatekeeper/dist/index.d.ts.map +1 -1
  59. package/vendor/gatekeeper/dist/index.js +2 -0
  60. package/vendor/gatekeeper/dist/index.js.map +1 -1
  61. package/vendor/gatekeeper/dist/lib/grants.d.ts +6 -0
  62. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
  63. package/vendor/gatekeeper/dist/lib/grants.js +6 -1
  64. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
  65. package/vendor/gatekeeper/dist/lib/groups.d.ts +5 -0
  66. package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -1
  67. package/vendor/gatekeeper/dist/lib/groups.js +5 -1
  68. package/vendor/gatekeeper/dist/lib/groups.js.map +1 -1
  69. package/vendor/gatekeeper/dist/lib/principals.d.ts +29 -0
  70. package/vendor/gatekeeper/dist/lib/principals.d.ts.map +1 -0
  71. package/vendor/gatekeeper/dist/lib/principals.js +67 -0
  72. package/vendor/gatekeeper/dist/lib/principals.js.map +1 -0
  73. package/vendor/gatekeeper/dist/lib/tunnels.d.ts +13 -0
  74. package/vendor/gatekeeper/dist/lib/tunnels.d.ts.map +1 -0
  75. package/vendor/gatekeeper/dist/lib/tunnels.js +68 -0
  76. package/vendor/gatekeeper/dist/lib/tunnels.js.map +1 -0
  77. package/vendor/gatekeeper/dist/lib/types.d.ts +19 -0
  78. package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -1
  79. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
  80. package/vendor/gatekeeper/dist/server/index.js +22 -48
  81. package/vendor/gatekeeper/dist/server/index.js.map +1 -1
  82. package/vendor/gatekeeper/dist/server/routes/authz.d.ts +15 -1
  83. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
  84. package/vendor/gatekeeper/dist/server/routes/authz.js +250 -103
  85. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
  86. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -1
  87. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +61 -4
  88. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
  89. package/vendor/gatekeeper/dist/server/routes/principals.d.ts +3 -0
  90. package/vendor/gatekeeper/dist/server/routes/principals.d.ts.map +1 -0
  91. package/vendor/gatekeeper/dist/server/routes/principals.js +27 -0
  92. package/vendor/gatekeeper/dist/server/routes/principals.js.map +1 -0
  93. package/vendor/gatekeeper/package.json +2 -2
  94. package/vendor/server/bin/lamaste-server.js +15 -1
  95. package/vendor/server/package.json +2 -2
  96. package/vendor/server/src/commands/plugin-identity.js +335 -0
  97. package/vendor/server/src/commands/plugins.js +99 -11
  98. package/vendor/server/src/commands/registry-credential.js +2 -1
  99. package/vendor/server/src/commands/tunnels.js +102 -2
  100. package/vendor/server/src/commands/uninstall.js +3 -1
  101. package/vendor/server/src/commands/users.js +358 -0
  102. package/vendor/server/src/plugin-approval.js +107 -5
  103. package/vendor/server/src/plugin-identity.js +382 -0
  104. package/vendor/server-ui/dist/assets/index-D-fer5ef.css +1 -0
  105. package/vendor/server-ui/dist/assets/index-DSaDPJaw.js +84 -0
  106. package/vendor/server-ui/dist/index.html +2 -2
  107. package/vendor/serverd/package.json +2 -2
  108. package/vendor/serverd/src/index.js +25 -1
  109. package/vendor/serverd/src/lib/audience.js +576 -0
  110. package/vendor/serverd/src/lib/authelia.js +78 -7
  111. package/vendor/serverd/src/lib/config.js +68 -43
  112. package/vendor/serverd/src/lib/directory.js +1113 -0
  113. package/vendor/serverd/src/lib/entitlements.js +517 -0
  114. package/vendor/serverd/src/lib/gatekeeper-client.js +215 -10
  115. package/vendor/serverd/src/lib/hook-pipelines.js +13 -0
  116. package/vendor/serverd/src/lib/identity-sync.js +905 -0
  117. package/vendor/serverd/src/lib/migrations/state/0013_identity_directory.sql +158 -0
  118. package/vendor/serverd/src/lib/migrations/state/0014_identity_ledger.sql +20 -0
  119. package/vendor/serverd/src/lib/mtls.js +6 -2
  120. package/vendor/serverd/src/lib/nginx.js +279 -48
  121. package/vendor/serverd/src/lib/plugin-hooks.js +98 -45
  122. package/vendor/serverd/src/lib/plugin-hosting.js +33 -5
  123. package/vendor/serverd/src/lib/plugin-lifecycle.js +100 -9
  124. package/vendor/serverd/src/lib/plugin-packages.js +30 -22
  125. package/vendor/serverd/src/lib/plugins.js +94 -15
  126. package/vendor/serverd/src/lib/registry-credential.js +46 -6
  127. package/vendor/serverd/src/lib/request-logging.js +19 -0
  128. package/vendor/serverd/src/lib/retained-data.js +50 -4
  129. package/vendor/serverd/src/lib/state.js +18 -0
  130. package/vendor/serverd/src/lib/tunnel-hooks.js +4 -1
  131. package/vendor/serverd/src/lib/user-access-session.js +21 -11
  132. package/vendor/serverd/src/lib/user-caller.js +67 -0
  133. package/vendor/serverd/src/lib/user-surface.js +733 -0
  134. package/vendor/serverd/src/lib/vhost-reconcile.js +136 -34
  135. package/vendor/serverd/src/middleware/user-access-session.js +9 -0
  136. package/vendor/serverd/src/routes/agent-forwarder.js +4 -2
  137. package/vendor/serverd/src/routes/invite.js +53 -12
  138. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +107 -16
  139. package/vendor/serverd/src/routes/management/identity-directory.js +79 -0
  140. package/vendor/serverd/src/routes/management/invitations.js +78 -68
  141. package/vendor/serverd/src/routes/management/plugin-identity.js +221 -0
  142. package/vendor/serverd/src/routes/management/registry-credential.js +1 -1
  143. package/vendor/serverd/src/routes/management/tunnels.js +98 -2
  144. package/vendor/serverd/src/routes/management/users.js +290 -208
  145. package/vendor/serverd/src/routes/management.js +4 -0
  146. package/vendor/serverd/src/routes/onboarding/provision.js +14 -1
  147. package/vendor/serverd/src/routes/user-access.js +17 -4
  148. package/vendor/serverd/src/routes/user-surface.js +69 -0
  149. package/vendor/server-ui/dist/assets/index-25wo_8av.css +0 -1
  150. package/vendor/server-ui/dist/assets/index-CESyyK8V.js +0 -84
@@ -1,6 +1,6 @@
1
1
  import crypto from 'node:crypto';
2
2
  import { request as undiciRequest } from 'undici';
3
- import { RELAY_ASSERTION_HEADER, signRelayAssertion } from '@lamalibre/lamaste';
3
+ import { AUTHELIA_SESSION_COOKIE, RELAY_ASSERTION_HEADER, RELAY_PANEL_AUDIENCE, RELAY_PANEL_PORT, autheliaSessionCookies, isUserSurfaceUrl, signRelayAssertion, } from '@lamalibre/lamaste';
4
4
  import { AUTHELIA_VERIFY_URL, SESSION_CACHE_TTL_MS } from '../../lib/constants.js';
5
5
  import { checkAccess } from '../../lib/authz.js';
6
6
  import { buildAccessRequestPage } from '../../lib/templates.js';
@@ -17,35 +17,35 @@ const AUTHELIA_VERIFY_TIMEOUT_MS = 2_500;
17
17
  * key and trigger collision-based attacks against cache-eviction logic.
18
18
  */
19
19
  const COOKIE_HMAC_KEY = crypto.randomBytes(32);
20
- /**
21
- * Extract the Authelia session cookie value from the full cookie header.
22
- *
23
- * Returns null when the cookie header is missing the `authelia_session=`
24
- * pair. The Authelia session cookie is the only auth signal we accept on
25
- * this path — any other cookie (CSRF tokens, analytics, etc.) carries no
26
- * identity. Falling back to the raw header would let unrelated cookies
27
- * drive the cache key, which would either pollute the cache or — once a
28
- * future refactor caches negative results — let an unauthenticated request
29
- * poison a downstream entry.
30
- */
31
- function extractAutheliaCookie(cookie) {
32
- const match = cookie.match(/(?:^|;\s*)authelia_session=([^;]*)/);
33
- return match?.[1] ?? null;
20
+ function presentedSession(cookieHeader) {
21
+ // Every pair counts towards "more than one", an empty one too: a planted
22
+ // `authelia_session=` beside the real cookie is still a second cookie.
23
+ const values = autheliaSessionCookies(cookieHeader);
24
+ if (values.length > 1)
25
+ return { kind: 'many' };
26
+ const [value] = values;
27
+ return value ? { kind: 'one', value } : { kind: 'none' };
34
28
  }
35
29
  /**
36
- * Derive a session cache key from a cookie string using HMAC-SHA256.
37
- *
38
- * The HMAC key is per-process random — keys are not predictable from cookie
39
- * values alone, which prevents an outsider from probing/seeding the cache.
30
+ * The session cache key of a session cookie on one tunnel host —
31
+ * HMAC-SHA256 under a per-process random key, so keys are not predictable
32
+ * from cookie values, and nobody can probe or seed the cache. Keyed by the
33
+ * host too: Authelia decides per host (a site's or plugin tunnel's rules
34
+ * name users), so a session it accepted for one host proves nothing on
35
+ * another.
40
36
  */
41
- function hashCookie(cookie) {
42
- return crypto.createHmac('sha256', COOKIE_HMAC_KEY).update(cookie).digest('hex');
37
+ function sessionCacheKey(session, host) {
38
+ return crypto
39
+ .createHmac('sha256', COOKIE_HMAC_KEY)
40
+ .update(`${host.toLowerCase()}\n${session}`)
41
+ .digest('hex');
43
42
  }
44
43
  /**
45
- * Forward the request's cookies to Authelia's verify endpoint
46
- * and extract the identity headers from the response.
44
+ * Ask Authelia's verify endpoint about one session cookie for one URL, and
45
+ * take the identity headers from its answer. Authelia is sent that cookie
46
+ * alone (`authelia_session=<value>`), never the browser's others.
47
47
  */
48
- async function validateWithAuthelia(cookie, originalUrl, requestId) {
48
+ async function validateWithAuthelia(session, originalUrl, requestId) {
49
49
  try {
50
50
  // Authelia's `/api/authz/auth-request` needs both the target URL and
51
51
  // method — without `X-Original-Method` it assumes `GET`, which is fine
@@ -54,7 +54,7 @@ async function validateWithAuthelia(cookie, originalUrl, requestId) {
54
54
  const { statusCode, headers } = await undiciRequest(AUTHELIA_VERIFY_URL, {
55
55
  method: 'GET',
56
56
  headers: {
57
- Cookie: cookie,
57
+ Cookie: `${AUTHELIA_SESSION_COOKIE}=${session}`,
58
58
  'X-Original-URL': originalUrl,
59
59
  'X-Original-Method': 'GET',
60
60
  'X-Forwarded-For': '127.0.0.1',
@@ -96,23 +96,47 @@ function findTunnelByFqdn(tunnels, fqdn) {
96
96
  const wanted = fqdn.toLowerCase();
97
97
  return tunnels.find((t) => t.fqdn.toLowerCase() === wanted);
98
98
  }
99
+ /**
100
+ * Why the hostnames a tunnel vhost writes into the subrequest's path,
101
+ * X-Original-URL and Host disagree, or null when they agree.
102
+ */
103
+ function hostnameMismatch(request, fqdn, originalHost) {
104
+ const named = fqdn.toLowerCase();
105
+ const hostHeader = request.headers['host'] ?? '';
106
+ const hostOnly = hostHeader.split(':')[0]?.toLowerCase() ?? '';
107
+ if (originalHost.toLowerCase() === named && hostOnly === named)
108
+ return null;
109
+ return {
110
+ reason: hostOnly ? 'tunnel_name_mismatch' : 'missing_host_header',
111
+ originalHost,
112
+ hostHeader,
113
+ };
114
+ }
99
115
  /** A tunnel hostname as a vhost writes it into the subrequest's path. */
100
116
  const TUNNEL_FQDN_RE = /^[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/;
101
117
  /**
102
- * nginx is the only client of the authorization routes (Gatekeeper binds
103
- * 127.0.0.1) and calls them on every protected request. Per-IP throttling
104
- * would punish legitimate traffic because every caller arrives as
105
- * 127.0.0.1, so the key is one bucket with an effectively-unlimited 10k/min
106
- * ceiling: the rate limit is structurally present (CodeQL
107
- * js/missing-rate-limiting) without breaking the hot path.
118
+ * How many authorization subrequests one client may cause on one tunnel
119
+ * host per minute. nginx asks on every request a protected host serves — a
120
+ * page and its assets, an application's polling — so the bound is
121
+ * generous; what it stops is one client (a script hammering Authelia with
122
+ * made-up session cookies, each an Authelia round trip) starving the
123
+ * others.
108
124
  */
109
- const INTERNAL_RATE_LIMIT = {
110
- rateLimit: {
111
- max: 10_000,
112
- timeWindow: '1 minute',
113
- keyGenerator: () => 'gatekeeper-internal',
114
- },
115
- };
125
+ export const AUTHZ_RATE_LIMIT_PER_CLIENT = 6_000;
126
+ /**
127
+ * The bucket of an authorization subrequest: the client's address and the
128
+ * tunnel host. nginx is the only client of these routes (Gatekeeper binds
129
+ * 127.0.0.1) and sets `X-Forwarded-For` to `$remote_addr` on every
130
+ * subrequest; Gatekeeper trusts that header from 127.0.0.1 only
131
+ * (`trustProxy` in `server/index.ts`), so `request.ip` is the address nginx
132
+ * accepted the browser's connection from — never one the browser named.
133
+ * The host is the tunnel the vhost names in the path (or its `Host`).
134
+ */
135
+ function authzRateLimitKey(request) {
136
+ const fqdn = request.params?.fqdn;
137
+ const host = typeof fqdn === 'string' ? fqdn : (request.headers['host'] ?? '');
138
+ return `${request.ip}|${host.toLowerCase()}`;
139
+ }
116
140
  /**
117
141
  * Parse an X-Original-URL header into its hostname and host components.
118
142
  * Returns null when the value is not a parseable absolute URL.
@@ -129,7 +153,14 @@ function parseOriginalUrl(originalUrl) {
129
153
  // ---------------------------------------------------------------------------
130
154
  // Route plugin
131
155
  // ---------------------------------------------------------------------------
132
- export async function authzRoutes(fastify) {
156
+ export async function authzRoutes(fastify, opts = {}) {
157
+ const authzRateLimit = {
158
+ rateLimit: {
159
+ max: opts.rateLimitPerClient ?? AUTHZ_RATE_LIMIT_PER_CLIENT,
160
+ timeWindow: '1 minute',
161
+ keyGenerator: authzRateLimitKey,
162
+ },
163
+ };
133
164
  /**
134
165
  * GET /authz/tunnel/:fqdn — the nginx auth_request target of a tunnel vhost
135
166
  *
@@ -149,7 +180,33 @@ export async function authzRoutes(fastify) {
149
180
  * On 403, the response body is the full access-request HTML page
150
181
  * (nginx serves this inline on the tunnel's FQDN via error_page 403 =).
151
182
  */
152
- fastify.get('/authz/tunnel/:fqdn', { config: INTERNAL_RATE_LIMIT }, async (request, reply) => authorizeTunnelRequest(fastify, request, reply, request.params.fqdn));
183
+ fastify.get('/authz/tunnel/:fqdn', { config: authzRateLimit }, async (request, reply) => authorizeTunnelRequest(fastify, request, reply, request.params.fqdn));
184
+ /**
185
+ * GET /authz/user-surface/:fqdn — the nginx auth_request target of a
186
+ * plugin's user surface: `/api/<route>/app` and everything under it, on
187
+ * the host of a tunnel bound to the plugin (`userSurface` in
188
+ * tunnels.json). The vhost names the tunnel as for `/authz/tunnel/:fqdn`.
189
+ *
190
+ * Gatekeeper authenticates the session — on a restricted tunnel it checks
191
+ * the user's grant too — and vouches for its user to the panel: a relay
192
+ * assertion for the panel's audience and port, naming the username alone
193
+ * and bound to the method and the raw request target, which must lie on
194
+ * the user surface of a route bound to this tunnel. The panel takes
195
+ * everything else about the user from its own directory.
196
+ *
197
+ * 200 with the assertion (never cacheable, no `Remote-*`), 401 without a
198
+ * session (nginx answers with `/authz/user-surface-unauthenticated`), 403
199
+ * for anything else refused — never the access-request page, never a
200
+ * redirect: the caller is an application's request. 503 while the relay
201
+ * signing key is unusable.
202
+ */
203
+ fastify.get('/authz/user-surface/:fqdn', { config: authzRateLimit }, async (request, reply) => authorizeUserSurfaceRequest(fastify, request, reply, request.params.fqdn));
204
+ /**
205
+ * GET /authz/user-surface-unauthenticated — what a user-surface request
206
+ * without a session is answered with (nginx `error_page 401`): JSON, so
207
+ * the application can tell its user to sign in again; never a redirect.
208
+ */
209
+ fastify.get('/authz/user-surface-unauthenticated', { config: authzRateLimit }, async (_request, reply) => reply.code(401).header('Cache-Control', 'no-store').send({ error: 'unauthenticated' }));
153
210
  /**
154
211
  * GET /authz/check — what tunnel vhosts written before 4.3 call. They name
155
212
  * the tunnel by the client's Host header (`$http_host`), which an
@@ -158,7 +215,7 @@ export async function authzRoutes(fastify) {
158
215
  * such a vhost (it does when it starts) its tunnel is closed, rather than
159
216
  * open to the users of every other tunnel.
160
217
  */
161
- fastify.get('/authz/check', { config: INTERNAL_RATE_LIMIT }, async (request, reply) => {
218
+ fastify.get('/authz/check', { config: authzRateLimit }, async (request, reply) => {
162
219
  request.log.error({
163
220
  requestId: request.id,
164
221
  reason: 'vhost_predates_host_binding',
@@ -171,6 +228,51 @@ export async function authzRoutes(fastify) {
171
228
  .send('This tunnel is unavailable until the relay rewrites its configuration.\n');
172
229
  });
173
230
  }
231
+ /**
232
+ * The Authelia session behind the request's `authelia_session` cookie, or
233
+ * null: none, more than one (refused — see {@link presentedSession}), or
234
+ * Authelia refused it. The session cache — one shared by every route here
235
+ * — is keyed by that cookie's value and the tunnel host, so unrelated
236
+ * cookies (CSRF tokens, analytics) cannot pollute it, and a session Authelia
237
+ * accepted on one host is never taken for another.
238
+ */
239
+ async function authenticatedSession(fastify, request, cookieHeader, originalUrl, hostname) {
240
+ const requestId = request.id;
241
+ const presented = presentedSession(cookieHeader);
242
+ if (presented.kind !== 'one') {
243
+ // Short-circuit before any cache work or the upstream Authelia /verify
244
+ // call: an unauthenticated request costs no Authelia round-trip.
245
+ request.log.info({
246
+ requestId,
247
+ reason: presented.kind === 'none' ? 'missing_authelia_cookie' : 'duplicate_authelia_cookie',
248
+ fqdn: hostname,
249
+ }, 'authz denied');
250
+ return null;
251
+ }
252
+ const cacheKey = sessionCacheKey(presented.value, hostname);
253
+ const sessionCache = fastify.getSessionCache();
254
+ const cached = sessionCache.get(cacheKey);
255
+ if (cached && cached.expiresAt > Date.now())
256
+ return cached;
257
+ if (cached) {
258
+ // Lazy TTL eviction — one stale entry pruned per request.
259
+ sessionCache.delete(cacheKey);
260
+ }
261
+ const validated = await validateWithAuthelia(presented.value, originalUrl, requestId);
262
+ if (!validated) {
263
+ request.log.info({ requestId, reason: 'authelia_rejected', fqdn: hostname }, 'authz denied');
264
+ return null;
265
+ }
266
+ // Opportunistic eviction — drop oldest (insertion-order head) when at cap.
267
+ while (sessionCache.size >= MAX_SESSION_CACHE_ENTRIES) {
268
+ const oldestKey = sessionCache.keys().next().value;
269
+ if (oldestKey === undefined)
270
+ break;
271
+ sessionCache.delete(oldestKey);
272
+ }
273
+ sessionCache.set(cacheKey, validated);
274
+ return validated;
275
+ }
174
276
  /**
175
277
  * Authorize one request on the tunnel named `fqdn` (see the
176
278
  * `/authz/tunnel/:fqdn` route).
@@ -181,7 +283,7 @@ async function authorizeTunnelRequest(fastify, request, reply, fqdn) {
181
283
  request.log.info({ requestId, reason: 'invalid_tunnel_name' }, 'authz denied');
182
284
  return reply.code(401).send();
183
285
  }
184
- const cookie = request.headers['cookie'] ?? '';
286
+ const cookie = request.headers['cookie'];
185
287
  const originalUrl = request.headers['x-original-url'] ?? '';
186
288
  if (!cookie || !originalUrl) {
187
289
  return reply.code(401).send();
@@ -191,20 +293,12 @@ async function authorizeTunnelRequest(fastify, request, reply, fqdn) {
191
293
  request.log.info({ requestId, reason: 'invalid_original_url' }, 'authz denied');
192
294
  return reply.code(401).send();
193
295
  }
194
- // The vhost writes the same hostname into the path, X-Original-URL and
195
- // Host. Disagreement means a request that did not come from a tunnel
196
- // vhost of this version: refuse it before Authelia is asked anything.
197
- const named = fqdn.toLowerCase();
198
- const hostHeader = request.headers['host'] ?? '';
199
- const hostOnly = hostHeader.split(':')[0]?.toLowerCase() ?? '';
200
- if (parsed.hostname.toLowerCase() !== named || hostOnly !== named) {
201
- request.log.info({
202
- requestId,
203
- reason: hostOnly ? 'tunnel_name_mismatch' : 'missing_host_header',
204
- tunnel: fqdn,
205
- originalHost: parsed.hostname,
206
- hostHeader,
207
- }, 'authz denied');
296
+ // Disagreement means a request that did not come from a tunnel vhost of
297
+ // this version: refuse it before Authelia is asked anything.
298
+ const mismatch = hostnameMismatch(request, fqdn, parsed.hostname);
299
+ if (mismatch) {
300
+ const { reason, ...detail } = mismatch;
301
+ request.log.info({ requestId, reason, tunnel: fqdn, ...detail }, 'authz denied');
208
302
  return reply.code(401).send();
209
303
  }
210
304
  const tunnels = fastify.getTunnels();
@@ -213,44 +307,9 @@ async function authorizeTunnelRequest(fastify, request, reply, fqdn) {
213
307
  request.log.info({ requestId, reason: 'unknown_tunnel_fqdn', fqdn }, 'authz denied');
214
308
  return reply.code(401).send();
215
309
  }
216
- // Check session cache (keyed by Authelia session cookie only to prevent
217
- // cache pollution via unrelated cookies like CSRF tokens or analytics).
218
- const autheliaCookie = extractAutheliaCookie(cookie);
219
- if (!autheliaCookie) {
220
- // No authelia_session — short-circuit before any cache work or the
221
- // upstream Authelia /verify call. Without this, an unauthenticated
222
- // request would still cost us an Authelia round-trip.
223
- request.log.info({ requestId, reason: 'missing_authelia_cookie', fqdn: parsed.hostname }, 'authz denied');
310
+ const session = await authenticatedSession(fastify, request, cookie, originalUrl, parsed.hostname);
311
+ if (!session)
224
312
  return reply.code(401).send();
225
- }
226
- const cacheKey = hashCookie(autheliaCookie);
227
- const sessionCache = fastify.getSessionCache();
228
- const cached = sessionCache.get(cacheKey);
229
- const now = Date.now();
230
- let session;
231
- if (cached && cached.expiresAt > now) {
232
- session = cached;
233
- }
234
- else {
235
- if (cached) {
236
- // Lazy TTL eviction — one stale entry pruned per request.
237
- sessionCache.delete(cacheKey);
238
- }
239
- const validated = await validateWithAuthelia(cookie, originalUrl, requestId);
240
- if (!validated) {
241
- request.log.info({ requestId, reason: 'authelia_rejected', fqdn: parsed.hostname }, 'authz denied');
242
- return reply.code(401).send();
243
- }
244
- // Opportunistic eviction — drop oldest (insertion-order head) when at cap.
245
- while (sessionCache.size >= MAX_SESSION_CACHE_ENTRIES) {
246
- const oldestKey = sessionCache.keys().next().value;
247
- if (oldestKey === undefined)
248
- break;
249
- sessionCache.delete(oldestKey);
250
- }
251
- sessionCache.set(cacheKey, validated);
252
- session = validated;
253
- }
254
313
  // Check access mode
255
314
  if (tunnel.accessMode === 'public' || tunnel.accessMode === 'authenticated') {
256
315
  return allow(fastify, request, reply, tunnel, session);
@@ -263,14 +322,13 @@ async function authorizeTunnelRequest(fastify, request, reply, fqdn) {
263
322
  if (result.allowed) {
264
323
  return allow(fastify, request, reply, tunnel, session);
265
324
  }
325
+ // The tunnel and the reason only — never who was refused.
266
326
  request.log.info({
267
327
  requestId,
268
328
  reason: 'no_matching_grant',
269
- username: session.username,
329
+ tunnel: fqdn,
270
330
  resourceType: 'tunnel',
271
331
  resourceId: tunnel.id,
272
- requiredGrant: `tunnel:${tunnel.id}`,
273
- fqdn: parsed.hostname,
274
332
  }, 'authz denied');
275
333
  if (fastify.getSettings().accessLoggingEnabled) {
276
334
  logAccessRequest({
@@ -294,6 +352,101 @@ async function authorizeTunnelRequest(fastify, request, reply, fqdn) {
294
352
  .type('text/html; charset=utf-8')
295
353
  .send(html);
296
354
  }
355
+ /**
356
+ * Authorize one request on the user surface of the tunnel named `fqdn` (see
357
+ * the `/authz/user-surface/:fqdn` route).
358
+ */
359
+ async function authorizeUserSurfaceRequest(fastify, request, reply, fqdn) {
360
+ const requestId = request.id;
361
+ // Single use: nothing of this answer may be cached, a refusal included.
362
+ reply.header('Cache-Control', 'no-store');
363
+ const refuse = (reason, extra = {}) => {
364
+ request.log.info({ requestId, reason, tunnel: fqdn, ...extra }, 'user-surface authz denied');
365
+ return reply.code(403).send();
366
+ };
367
+ if (!TUNNEL_FQDN_RE.test(fqdn))
368
+ return refuse('invalid_tunnel_name');
369
+ const originalUrl = request.headers['x-original-url'];
370
+ const originalMethod = request.headers['x-original-method'];
371
+ if (typeof originalUrl !== 'string' || typeof originalMethod !== 'string') {
372
+ return refuse('missing_original_request');
373
+ }
374
+ const parsed = parseOriginalUrl(originalUrl);
375
+ if (!parsed)
376
+ return refuse('invalid_original_url');
377
+ const mismatch = hostnameMismatch(request, fqdn, parsed.hostname);
378
+ if (mismatch) {
379
+ const { reason, ...detail } = mismatch;
380
+ return refuse(reason, detail);
381
+ }
382
+ const tunnel = findTunnelByFqdn(fastify.getTunnels(), fqdn);
383
+ if (!tunnel)
384
+ return refuse('unknown_tunnel_fqdn');
385
+ if (!tunnel.enabled)
386
+ return refuse('tunnel_disabled');
387
+ if (tunnel.accessMode === 'public' || !tunnel.userSurface)
388
+ return refuse('no_user_surface');
389
+ // The request target exactly as the browser sent it — what follows the
390
+ // hostname the vhost wrote — never re-encoded by a URL parser: the panel
391
+ // receives it unchanged and holds the assertion against it byte for byte.
392
+ const prefix = `https://${fqdn.toLowerCase()}`;
393
+ if (originalUrl.slice(0, prefix.length).toLowerCase() !== prefix) {
394
+ return refuse('invalid_original_url');
395
+ }
396
+ const target = originalUrl.slice(prefix.length);
397
+ const route = tunnel.userSurface.routes.find((r) => isUserSurfaceUrl(target, r));
398
+ if (!route)
399
+ return refuse('not_on_user_surface');
400
+ // Bound, but its plugin is not hosted by the agent carrying this tunnel
401
+ // (moved, revoked, hosted elsewhere): nothing of it is served here.
402
+ if (!tunnel.userSurface.served.includes(route))
403
+ return refuse('not_hosting_agent', { route });
404
+ const session = await authenticatedSession(fastify, request, request.headers['cookie'], originalUrl, parsed.hostname);
405
+ if (!session)
406
+ return reply.code(401).send();
407
+ if (tunnel.accessMode !== 'authenticated') {
408
+ // restricted — the user's grant for the tunnel, as on its other paths
409
+ const result = await checkAccess(session.username, 'tunnel', tunnel.id, {
410
+ adminContact: fastify.getSettings().adminEmail,
411
+ adminName: fastify.getSettings().adminName,
412
+ });
413
+ if (!result.allowed) {
414
+ // The tunnel and the reason only — never who was refused.
415
+ return refuse('no_matching_grant', { resourceType: 'tunnel', resourceId: tunnel.id });
416
+ }
417
+ }
418
+ const key = await currentRelayKey(fastify, request);
419
+ if (!key) {
420
+ request.log.error({ requestId, reason: 'relay_signing_key_unavailable', tunnel: fqdn }, 'user-surface authz failed');
421
+ return reply.code(503).send();
422
+ }
423
+ let assertion;
424
+ try {
425
+ assertion = signRelayAssertion({
426
+ aud: RELAY_PANEL_AUDIENCE,
427
+ port: RELAY_PANEL_PORT,
428
+ caller: { type: 'user', username: session.username },
429
+ method: originalMethod,
430
+ target: { route, path: target },
431
+ }, key);
432
+ }
433
+ catch (err) {
434
+ // A username, method or target an assertion cannot carry.
435
+ return refuse('not_assertable', { detail: err instanceof Error ? err.message : String(err) });
436
+ }
437
+ reply.header(RELAY_ASSERTION_HEADER, assertion);
438
+ return reply.code(200).send();
439
+ }
440
+ /** The relay signing key, or null when there is none or it is unusable (logged). */
441
+ async function currentRelayKey(fastify, request) {
442
+ try {
443
+ return await fastify.getRelaySigner().current();
444
+ }
445
+ catch (err) {
446
+ request.log.error({ err: err instanceof Error ? err.message : String(err) }, 'Relay signing key unusable');
447
+ return null;
448
+ }
449
+ }
297
450
  /**
298
451
  * Answer an allowed request: the Authelia identity headers nginx forwards
299
452
  * to the tunnel backend.
@@ -312,13 +465,7 @@ async function allow(fastify, request, reply, tunnel, session) {
312
465
  return reply.code(200).send();
313
466
  }
314
467
  reply.header('Cache-Control', 'no-store');
315
- let key = null;
316
- try {
317
- key = await fastify.getRelaySigner().current();
318
- }
319
- catch (err) {
320
- request.log.error({ err: err instanceof Error ? err.message : String(err) }, 'Relay signing key unusable');
321
- }
468
+ const key = await currentRelayKey(fastify, request);
322
469
  if (!key) {
323
470
  request.log.error({ requestId: request.id, reason: 'relay_signing_key_unavailable', fqdn: tunnel.fqdn }, 'authz failed');
324
471
  return reply.code(503).send();
@@ -1 +1 @@
1
- {"version":3,"file":"authz.js","sourceRoot":"","sources":["../../../src/server/routes/authz.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authz.js","sourceRoot":"","sources":["../../../src/server/routes/authz.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostic.d.ts","sourceRoot":"","sources":["../../../src/server/routes/diagnostic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAO7E,OAAO,KAAK,EAAsB,kBAAkB,EAAoB,MAAM,oBAAoB,CAAC;AAyLnG,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAgG9E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAEhE"}
1
+ {"version":3,"file":"diagnostic.d.ts","sourceRoot":"","sources":["../../../src/server/routes/diagnostic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAO7E,OAAO,KAAK,EAAsB,kBAAkB,EAAoB,MAAM,oBAAoB,CAAC;AAiNnG,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAyI9E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAEhE"}
@@ -15,6 +15,20 @@ const DEFAULT_RETENTION_DAYS = 90;
15
15
  // JSON-era rotation cadence loosely and is comfortably below any sensible
16
16
  // retention setting.
17
17
  const RETENTION_SWEEP_INTERVAL_MS = 60 * 60 * 1000;
18
+ /**
19
+ * `POST /api/access-log/purge { username, before? }`: the rows of one
20
+ * username, before a time when given. The username travels in the body —
21
+ * a URL is what request logs keep.
22
+ */
23
+ const PurgeBodySchema = z
24
+ .object({
25
+ username: z.string().min(1).max(100),
26
+ before: z
27
+ .string()
28
+ .regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?Z$/, 'before is an ISO 8601 UTC time')
29
+ .optional(),
30
+ })
31
+ .strict();
18
32
  const UpdateSettingsSchema = z.object({
19
33
  adminEmail: z.string().email().max(200).optional(),
20
34
  adminName: z.string().max(200).optional(),
@@ -41,6 +55,11 @@ async function getStmts() {
41
55
  countAll: db.prepare('SELECT COUNT(*) AS n FROM access_request_log'),
42
56
  deleteAll: db.prepare('DELETE FROM access_request_log'),
43
57
  deleteOlderThan: db.prepare('DELETE FROM access_request_log WHERE timestamp < ?'),
58
+ // Erasing a removed user (the panel): their rows only — those logged
59
+ // before they were removed, when the panel says when that was (a later
60
+ // user may have the same username).
61
+ deleteByUsername: db.prepare('DELETE FROM access_request_log WHERE username = ?'),
62
+ deleteByUsernameBefore: db.prepare('DELETE FROM access_request_log WHERE username = ? AND timestamp < ?'),
44
63
  begin: db.prepare('BEGIN IMMEDIATE'),
45
64
  commit: db.prepare('COMMIT'),
46
65
  rollback: db.prepare('ROLLBACK'),
@@ -223,12 +242,50 @@ export async function diagnosticRoutes(fastify) {
223
242
  return reply.code(500).send({ error: err.message });
224
243
  }
225
244
  });
226
- // DELETE /api/access-log — clear access request log
227
- fastify.delete('/access-log', async (_request, reply) => {
245
+ // DELETE /api/access-log — clear the whole access request log (and the
246
+ // entries still queued for it). It takes no query: a purge of one user's
247
+ // rows is POST /api/access-log/purge, and a query an older caller sent to
248
+ // narrow the purge must never clear everything instead. Answers how many
249
+ // rows went (`removed`).
250
+ fastify.delete('/access-log', async (request, reply) => {
251
+ if (Object.keys(request.query ?? {}).length > 0) {
252
+ return reply.code(400).send({
253
+ error: "DELETE clears the whole log and takes no query — purge one user's rows with POST /api/access-log/purge",
254
+ });
255
+ }
256
+ try {
257
+ const s = await getStmts();
258
+ logQueue = [];
259
+ const result = s.deleteAll.run();
260
+ return { ok: true, removed: Number(result.changes) };
261
+ }
262
+ catch (err) {
263
+ return reply.code(500).send({ error: err.message });
264
+ }
265
+ });
266
+ // POST /api/access-log/purge { username, before? } — one user's rows,
267
+ // logged before `before` when given (a later user may hold the username),
268
+ // and the matching entries still queued for the log, so none of them is
269
+ // written after the purge. Answers how many rows went (`removed`).
270
+ fastify.post('/access-log/purge', async (request, reply) => {
271
+ const parsed = PurgeBodySchema.safeParse(request.body ?? {});
272
+ if (!parsed.success) {
273
+ return reply.code(400).send({
274
+ error: 'Invalid body',
275
+ details: parsed.error.issues.map((i) => i.message),
276
+ });
277
+ }
278
+ const { username, before } = parsed.data;
228
279
  try {
229
280
  const s = await getStmts();
230
- s.deleteAll.run();
231
- return { ok: true };
281
+ const matches = (e) => e.username === username && (before === undefined || e.timestamp < before);
282
+ const kept = logQueue.filter((e) => !matches(e));
283
+ const queued = logQueue.length - kept.length;
284
+ logQueue = kept;
285
+ const result = before === undefined
286
+ ? s.deleteByUsername.run(username)
287
+ : s.deleteByUsernameBefore.run(username, before);
288
+ return { ok: true, removed: Number(result.changes) + queued };
232
289
  }
233
290
  catch (err) {
234
291
  return reply.code(500).send({ error: err.message });