@lamalibre/create-lamaste 4.2.0 → 4.3.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 (123) hide show
  1. package/package.json +2 -2
  2. package/scripts/lamaste-priv +205 -2
  3. package/src/index.js +4 -4
  4. package/src/lib/node-version.js +114 -0
  5. package/src/lib/relay-services.js +15 -1
  6. package/src/lib/service-config.js +113 -0
  7. package/src/tasks/gatekeeper.js +8 -3
  8. package/src/tasks/node.js +34 -75
  9. package/src/tasks/redeploy.js +36 -0
  10. package/vendor/docs/00-introduction/how-it-works.md +2 -2
  11. package/vendor/docs/00-introduction/quickstart.md +5 -5
  12. package/vendor/docs/00-introduction/what-is-lamaste.md +5 -5
  13. package/vendor/docs/01-concepts/authentication.md +6 -3
  14. package/vendor/docs/01-concepts/authorization.md +29 -17
  15. package/vendor/docs/01-concepts/certificates.md +3 -3
  16. package/vendor/docs/01-concepts/mtls.md +2 -2
  17. package/vendor/docs/01-concepts/nginx-reverse-proxy.md +8 -3
  18. package/vendor/docs/01-concepts/security-model.md +98 -34
  19. package/vendor/docs/01-concepts/tickets.md +2 -2
  20. package/vendor/docs/01-concepts/tunneling.md +4 -4
  21. package/vendor/docs/02-guides/agent-setup.md +34 -16
  22. package/vendor/docs/02-guides/certificate-management.md +2 -2
  23. package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
  24. package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
  25. package/vendor/docs/02-guides/installation.md +3 -3
  26. package/vendor/docs/02-guides/onboarding.md +2 -2
  27. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
  28. package/vendor/docs/03-architecture/installer-flow.md +2 -2
  29. package/vendor/docs/03-architecture/installer.md +4 -4
  30. package/vendor/docs/03-architecture/management-flow.md +1 -1
  31. package/vendor/docs/03-architecture/nginx-configuration.md +91 -26
  32. package/vendor/docs/03-architecture/overview.md +8 -8
  33. package/vendor/docs/03-architecture/panel-client.md +6 -6
  34. package/vendor/docs/03-architecture/panel-server.md +2 -2
  35. package/vendor/docs/03-architecture/state-management.md +2 -2
  36. package/vendor/docs/03-architecture/system-overview.md +1 -1
  37. package/vendor/docs/04-api-reference/agent-hosted-plugins.md +407 -0
  38. package/vendor/docs/04-api-reference/app-host.md +360 -0
  39. package/vendor/docs/04-api-reference/audit-and-notifications.md +57 -0
  40. package/vendor/docs/04-api-reference/certificates.md +95 -38
  41. package/vendor/docs/04-api-reference/gatekeeper.md +5 -3
  42. package/vendor/docs/04-api-reference/lifecycle-hooks.md +333 -0
  43. package/vendor/docs/04-api-reference/onboarding.md +1 -1
  44. package/vendor/docs/04-api-reference/overview.md +137 -111
  45. package/vendor/docs/04-api-reference/registry-and-oidc.md +7 -3
  46. package/vendor/docs/04-api-reference/tunnels.md +15 -13
  47. package/vendor/docs/05-operations/backup-and-restore.md +1 -1
  48. package/vendor/docs/05-operations/uninstalling.md +1 -1
  49. package/vendor/docs/05-operations/upgrades.md +25 -20
  50. package/vendor/docs/06-reference/config-files.md +190 -97
  51. package/vendor/docs/06-reference/glossary.md +3 -3
  52. package/vendor/docs/06-reference/installer-flags.md +13 -13
  53. package/vendor/docs/06-reference/ports-and-services.md +1 -1
  54. package/vendor/docs/06-reference/troubleshooting.md +33 -8
  55. package/vendor/docs/_index.json +20 -0
  56. package/vendor/docs/gatekeeper-design.md +22 -19
  57. package/vendor/docs/identity-directory-design.md +57 -56
  58. package/vendor/docs/package.json +1 -1
  59. package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
  60. package/vendor/gatekeeper/dist/lib/types.d.ts +12 -0
  61. package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -1
  62. package/vendor/gatekeeper/dist/server/index.d.ts +2 -0
  63. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
  64. package/vendor/gatekeeper/dist/server/index.js +47 -8
  65. package/vendor/gatekeeper/dist/server/index.js.map +1 -1
  66. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
  67. package/vendor/gatekeeper/dist/server/routes/authz.js +233 -141
  68. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
  69. package/vendor/gatekeeper/package.json +4 -3
  70. package/vendor/server/bin/lamaste-server.js +18 -1
  71. package/vendor/server/package.json +2 -2
  72. package/vendor/server/src/commands/audit.js +60 -0
  73. package/vendor/server/src/commands/plugins.js +963 -12
  74. package/vendor/server/src/commands/push-install.js +317 -0
  75. package/vendor/server/src/commands/registry-credential.js +2 -1
  76. package/vendor/server/src/commands/uninstall.js +28 -1
  77. package/vendor/server/src/ndjson.js +4 -2
  78. package/vendor/server/src/panel-api.js +32 -4
  79. package/vendor/server-ui/dist/assets/index-Bc5NCMSv.css +1 -0
  80. package/vendor/server-ui/dist/assets/index-DBp3cmaU.js +84 -0
  81. package/vendor/server-ui/dist/index.html +2 -2
  82. package/vendor/serverd/package.json +2 -2
  83. package/vendor/serverd/src/index.js +56 -4
  84. package/vendor/serverd/src/lib/actor.js +24 -0
  85. package/vendor/serverd/src/lib/agent-jobs.js +330 -0
  86. package/vendor/serverd/src/lib/app-error.js +10 -0
  87. package/vendor/serverd/src/lib/audit.js +145 -0
  88. package/vendor/serverd/src/lib/hook-effects.js +123 -0
  89. package/vendor/serverd/src/lib/hook-pipelines.js +902 -0
  90. package/vendor/serverd/src/lib/migrations/state/0006_plugin_agent.sql +4 -0
  91. package/vendor/serverd/src/lib/migrations/state/0007_audit_and_notifications.sql +29 -0
  92. package/vendor/serverd/src/lib/migrations/state/0008_plugin_hooks.sql +70 -0
  93. package/vendor/serverd/src/lib/migrations/state/0009_plugin_agent_half.sql +53 -0
  94. package/vendor/serverd/src/lib/migrations/state/0010_plugin_routes_and_retained_data.sql +47 -0
  95. package/vendor/serverd/src/lib/migrations/state/0011_agent_job_signature.sql +14 -0
  96. package/vendor/serverd/src/lib/mtls.js +89 -8
  97. package/vendor/serverd/src/lib/nginx.js +298 -44
  98. package/vendor/serverd/src/lib/notifications.js +107 -0
  99. package/vendor/serverd/src/lib/plugin-hooks.js +560 -0
  100. package/vendor/serverd/src/lib/plugin-hosting.js +688 -0
  101. package/vendor/serverd/src/lib/plugin-lifecycle.js +603 -0
  102. package/vendor/serverd/src/lib/plugin-operations.js +295 -0
  103. package/vendor/serverd/src/lib/plugin-packages.js +249 -0
  104. package/vendor/serverd/src/lib/plugins.js +298 -68
  105. package/vendor/serverd/src/lib/push-install.js +88 -2
  106. package/vendor/serverd/src/lib/relay-hooks.js +100 -0
  107. package/vendor/serverd/src/lib/relay-signing.js +43 -0
  108. package/vendor/serverd/src/lib/request-hooks.js +79 -0
  109. package/vendor/serverd/src/lib/retained-data.js +99 -0
  110. package/vendor/serverd/src/lib/trust-proxy.js +34 -0
  111. package/vendor/serverd/src/lib/tunnel-hooks.js +88 -0
  112. package/vendor/serverd/src/lib/vhost-reconcile.js +260 -0
  113. package/vendor/serverd/src/middleware/twofa-session.js +11 -1
  114. package/vendor/serverd/src/routes/agent-forwarder.js +37 -0
  115. package/vendor/serverd/src/routes/management/agent-panel-authz.js +97 -0
  116. package/vendor/serverd/src/routes/management/agents.js +262 -1
  117. package/vendor/serverd/src/routes/management/audit.js +81 -0
  118. package/vendor/serverd/src/routes/management/certs.js +1 -15
  119. package/vendor/serverd/src/routes/management/plugins.js +569 -54
  120. package/vendor/serverd/src/routes/management/tunnels.js +26 -0
  121. package/vendor/serverd/src/routes/management.js +4 -0
  122. package/vendor/server-ui/dist/assets/index-B5Wp8lu-.js +0 -257
  123. package/vendor/server-ui/dist/assets/index-BqWWFlTU.css +0 -1
@@ -153,6 +153,18 @@ export interface TunnelInfo {
153
153
  readonly fqdn: string;
154
154
  readonly accessMode: AccessMode;
155
155
  readonly enabled: boolean;
156
+ /**
157
+ * Set on a plugin tunnel (`type: 'plugin'` with an owning agent): the
158
+ * request goes to that agent's lamaste-agentd, which accepts the user only
159
+ * with a relay assertion Gatekeeper signs (see authz.ts).
160
+ */
161
+ readonly plugin?: PluginTunnelTarget | undefined;
162
+ }
163
+ /** Where a plugin tunnel's requests go: the agent, its daemon's port, the plugin route. */
164
+ export interface PluginTunnelTarget {
165
+ readonly agentLabel: string;
166
+ readonly port: number;
167
+ readonly route: string;
156
168
  }
157
169
  /**
158
170
  * Cached Authelia session data.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import '../boot.js';
2
2
  import Fastify from 'fastify';
3
+ import type { RelaySigner } from '@lamalibre/lamaste';
3
4
  import type { TunnelInfo, GatekeeperSettings, AutheliaSession } from '../lib/types.js';
4
5
  export declare function createServer(): Promise<ReturnType<typeof Fastify>>;
5
6
  declare module 'fastify' {
@@ -8,6 +9,7 @@ declare module 'fastify' {
8
9
  getSettings(): GatekeeperSettings;
9
10
  getSessionCache(): Map<string, AutheliaSession>;
10
11
  getCacheVersion(): number;
12
+ getRelaySigner(): RelaySigner;
11
13
  bustCache(): void;
12
14
  updateSettings(s: GatekeeperSettings): void;
13
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,CAAC;AAEpB,OAAO,OAAO,MAAM,SAAS,CAAC;AAc9B,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAoHvF,wBAAsB,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CA6IxE;AAkCD,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,UAAU,IAAI,UAAU,EAAE,CAAC;QAC3B,WAAW,IAAI,kBAAkB,CAAC;QAClC,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QAChD,eAAe,IAAI,MAAM,CAAC;QAC1B,SAAS,IAAI,IAAI,CAAC;QAClB,cAAc,CAAC,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;KAC7C;CACF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,CAAC;AAEpB,OAAO,OAAO,MAAM,SAAS,CAAC;AAW9B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAStD,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EAClB,eAAe,EAChB,MAAM,iBAAiB,CAAC;AA4JzB,wBAAsB,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC,CAkJxE;AAkCD,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,UAAU,IAAI,UAAU,EAAE,CAAC;QAC3B,WAAW,IAAI,kBAAkB,CAAC;QAClC,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QAChD,eAAe,IAAI,MAAM,CAAC;QAC1B,cAAc,IAAI,WAAW,CAAC;QAC9B,SAAS,IAAI,IAAI,CAAC;QAClB,cAAc,CAAC,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;KAC7C;CACF"}
@@ -5,7 +5,7 @@ import rateLimit from '@fastify/rate-limit';
5
5
  import { watch } from 'node:fs';
6
6
  import { readFile } from 'node:fs/promises';
7
7
  import path from 'node:path';
8
- import { atomicWriteJSON } from '@lamalibre/lamaste';
8
+ import { atomicWriteJSON, AGENT_LABEL_REGEX, createRelaySigner, RELAY_SIGNING_KEY_FILE, } from '@lamalibre/lamaste';
9
9
  import { DEFAULT_DATA_DIR, GROUPS_FILE, GRANTS_FILE, SETTINGS_FILE, GATEKEEPER_PORT, SESSION_CACHE_TTL_MS, } from '../lib/constants.js';
10
10
  import { registerCacheInvalidator } from '../lib/cache-bust.js';
11
11
  import { authzRoutes } from './routes/authz.js';
@@ -16,6 +16,14 @@ import { accessRequestRoutes } from './routes/access-request.js';
16
16
  const dataDir = process.env.LAMALIBRE_LAMASTE_DATA_DIR ?? DEFAULT_DATA_DIR;
17
17
  const tunnelsPath = path.join(dataDir, 'tunnels.json');
18
18
  const settingsPath = path.join(dataDir, SETTINGS_FILE);
19
+ /**
20
+ * The relay's assertion signing key, created by the panel (never here). A
21
+ * plugin tunnel's user is vouched for to the agent with it; the file is
22
+ * re-read when it changes.
23
+ */
24
+ const relaySigner = createRelaySigner(path.join(dataDir, RELAY_SIGNING_KEY_FILE), {
25
+ create: false,
26
+ });
19
27
  // ---------------------------------------------------------------------------
20
28
  // In-memory caches (refreshed by file watch + TTL)
21
29
  // ---------------------------------------------------------------------------
@@ -30,17 +38,43 @@ let cacheVersion = 0;
30
38
  // ---------------------------------------------------------------------------
31
39
  // File loaders
32
40
  // ---------------------------------------------------------------------------
41
+ /**
42
+ * The agent-side target of a plugin tunnel, or undefined. Only a well-formed
43
+ * one is returned: its fields end up in a signed assertion.
44
+ */
45
+ function pluginTunnelTarget(t) {
46
+ const { type, agentLabel, port, pluginRoute } = t;
47
+ if (type !== 'plugin' ||
48
+ typeof agentLabel !== 'string' ||
49
+ !AGENT_LABEL_REGEX.test(agentLabel) ||
50
+ typeof port !== 'number' ||
51
+ !Number.isInteger(port) ||
52
+ port < 1 ||
53
+ port > 65535 ||
54
+ typeof pluginRoute !== 'string' ||
55
+ !/^[a-z0-9][a-z0-9-]{0,63}$/.test(pluginRoute)) {
56
+ return undefined;
57
+ }
58
+ return { agentLabel, port, route: pluginRoute };
59
+ }
33
60
  async function loadTunnels() {
34
61
  try {
35
62
  const raw = await readFile(tunnelsPath, 'utf-8');
36
63
  const parsed = JSON.parse(raw);
37
64
  if (!Array.isArray(parsed))
38
65
  return [];
39
- return parsed.map((t) => ({
40
- id: String(t.id ?? ''),
41
- fqdn: String(t.fqdn ?? ''),
42
- accessMode: t.accessMode ?? 'restricted',
43
- enabled: t.enabled !== false,
66
+ return (parsed
67
+ // An internal plugin tunnel has no hostname: nothing to authorize.
68
+ .filter((t) => t.exposure !== 'internal' && t.fqdn)
69
+ .map((t) => {
70
+ const plugin = pluginTunnelTarget(t);
71
+ return {
72
+ id: String(t.id ?? ''),
73
+ fqdn: String(t.fqdn ?? ''),
74
+ accessMode: t.accessMode ?? 'restricted',
75
+ enabled: t.enabled !== false,
76
+ ...(plugin ? { plugin } : {}),
77
+ };
44
78
  }));
45
79
  }
46
80
  catch {
@@ -112,7 +146,11 @@ function watchFile(filePath, reload, logger) {
112
146
  export async function createServer() {
113
147
  const server = Fastify({
114
148
  logger: true,
115
- trustProxy: 1,
149
+ // Forwarding headers are honoured only from loopback: the gatekeeper
150
+ // listens on 127.0.0.1 and its callers (nginx, the panel proxy) are
151
+ // local. Trust by address, not hop count — a hop count cannot tell a
152
+ // proxy from a direct client spoofing X-Forwarded-*.
153
+ trustProxy: '127.0.0.1',
116
154
  });
117
155
  // Global rate limit. The gatekeeper binds to 127.0.0.1 and is reached
118
156
  // exclusively by nginx auth_request and the panel proxy — both are
@@ -120,7 +158,7 @@ export async function createServer() {
120
158
  // per-IP limiter would collapse them into a single bucket and either
121
159
  // be useless or punish legitimate nginx traffic. We collapse the key
122
160
  // explicitly to one shared bucket and set a high ceiling; the hot
123
- // /authz/check route then overrides this with its own ceiling that
161
+ // authorization routes then override this with their own ceiling that
124
162
  // makes the "nginx-only" assumption explicit.
125
163
  await server.register(rateLimit, {
126
164
  max: 1000,
@@ -135,6 +173,7 @@ export async function createServer() {
135
173
  server.decorate('getSettings', () => settingsCache);
136
174
  server.decorate('getSessionCache', () => sessionCache);
137
175
  server.decorate('getCacheVersion', () => cacheVersion);
176
+ server.decorate('getRelaySigner', () => relaySigner);
138
177
  const bustCache = () => {
139
178
  cacheVersion++;
140
179
  sessionCache.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"authz.d.ts","sourceRoot":"","sources":["../../../src/server/routes/authz.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAkI7E,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA4LzE"}
1
+ {"version":3,"file":"authz.d.ts","sourceRoot":"","sources":["../../../src/server/routes/authz.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AA0J7E,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDzE"}
@@ -1,5 +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
4
  import { AUTHELIA_VERIFY_URL, SESSION_CACHE_TTL_MS } from '../../lib/constants.js';
4
5
  import { checkAccess } from '../../lib/authz.js';
5
6
  import { buildAccessRequestPage } from '../../lib/templates.js';
@@ -88,11 +89,30 @@ function getHeader(headers, name) {
88
89
  return val;
89
90
  }
90
91
  /**
91
- * Look up a tunnel by its FQDN from the in-memory cache.
92
+ * Look up a tunnel by its FQDN from the in-memory cache. Hostnames compare
93
+ * case-insensitively.
92
94
  */
93
95
  function findTunnelByFqdn(tunnels, fqdn) {
94
- return tunnels.find((t) => t.fqdn === fqdn);
96
+ const wanted = fqdn.toLowerCase();
97
+ return tunnels.find((t) => t.fqdn.toLowerCase() === wanted);
95
98
  }
99
+ /** A tunnel hostname as a vhost writes it into the subrequest's path. */
100
+ 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
+ /**
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.
108
+ */
109
+ const INTERNAL_RATE_LIMIT = {
110
+ rateLimit: {
111
+ max: 10_000,
112
+ timeWindow: '1 minute',
113
+ keyGenerator: () => 'gatekeeper-internal',
114
+ },
115
+ };
96
116
  /**
97
117
  * Parse an X-Original-URL header into its hostname and host components.
98
118
  * Returns null when the value is not a parseable absolute URL.
@@ -111,160 +131,232 @@ function parseOriginalUrl(originalUrl) {
111
131
  // ---------------------------------------------------------------------------
112
132
  export async function authzRoutes(fastify) {
113
133
  /**
114
- * GET /authz/check — nginx auth_request target
134
+ * GET /authz/tunnel/:fqdn — the nginx auth_request target of a tunnel vhost
135
+ *
136
+ * The vhost names its tunnel in the path, written into its configuration
137
+ * (`proxy_pass http://127.0.0.1:9294/authz/tunnel/<fqdn>;`), as the
138
+ * agent-panel vhost names its agent: nothing in the request can choose
139
+ * another tunnel. X-Original-URL — the URL Authelia is asked about, with
140
+ * the request's path and query — and Host carry the same hostname and must
141
+ * agree with it.
115
142
  *
116
143
  * Flow:
117
- * 1. Read Cookie and X-Original-URL from nginx
118
- * 2. Validate Authelia session (cached in memory)
119
- * 3. Look up tunnel by hostname
120
- * 4. Check access mode and grants
121
- * 5. Return 200 (allowed), 401 (not authenticated), or 403 (not authorized)
144
+ * 1. Check the tunnel named, X-Original-URL and Host agree
145
+ * 2. Validate the Authelia session (cached in memory)
146
+ * 3. Check access mode and grants
147
+ * 4. Return 200 (allowed), 401 (not authenticated), or 403 (not authorized)
122
148
  *
123
149
  * On 403, the response body is the full access-request HTML page
124
150
  * (nginx serves this inline on the tunnel's FQDN via error_page 403 =).
125
151
  */
126
- fastify.get('/authz/check', {
127
- // nginx is the only client (the gatekeeper binds 127.0.0.1) and
128
- // it expects one call per cache miss on every protected request.
129
- // Per-IP throttling here would punish legitimate traffic because
130
- // every caller arrives as 127.0.0.1. We collapse the key to a
131
- // single bucket and raise the ceiling to an effectively-unlimited
132
- // 10k/min so the rate-limit is structurally present (CodeQL
133
- // js/missing-rate-limiting) without breaking the hot path.
134
- config: {
135
- rateLimit: {
136
- max: 10_000,
137
- timeWindow: '1 minute',
138
- keyGenerator: () => 'gatekeeper-internal',
139
- },
140
- },
141
- }, async (request, reply) => {
142
- const requestId = request.id;
143
- const cookie = request.headers['cookie'] ?? '';
144
- const originalUrl = request.headers['x-original-url'] ?? '';
145
- if (!cookie || !originalUrl) {
146
- return reply.code(401).send();
147
- }
148
- // Parse and validate X-Original-URL before any other work.
149
- // Defense-in-depth: the 127.0.0.1 bind + nginx auth_request boundary is
150
- // the primary guarantee that this header is trustworthy; host matching
151
- // ensures a misconfigured proxy chain cannot forge tunnel identity.
152
- const parsed = parseOriginalUrl(originalUrl);
153
- if (!parsed) {
154
- request.log.info({ requestId, reason: 'invalid_original_url' }, 'authz denied');
155
- return reply.code(401).send();
156
- }
157
- // Host header check: when nginx forwards the parent request's Host to the
158
- // subrequest (default behavior for auth_request), the hostname portion
159
- // must match the hostname parsed from X-Original-URL. Port differences
160
- // are ignored — nginx often normalizes them. An absent Host header skips
161
- // the check (some proxies strip it from internal subrequests).
162
- const hostHeader = request.headers['host'] ?? '';
163
- if (hostHeader) {
164
- const hostOnly = hostHeader.split(':')[0]?.toLowerCase() ?? '';
165
- if (hostOnly && hostOnly !== parsed.hostname.toLowerCase()) {
166
- request.log.info({
167
- requestId,
168
- reason: 'host_header_mismatch',
169
- originalHost: parsed.hostname,
170
- hostHeader,
171
- }, 'authz denied');
172
- return reply.code(401).send();
173
- }
174
- }
175
- const tunnels = fastify.getTunnels();
176
- const tunnel = findTunnelByFqdn(tunnels, parsed.hostname);
177
- if (!tunnel) {
178
- request.log.info({ requestId, reason: 'unknown_tunnel_fqdn', fqdn: parsed.hostname }, 'authz denied');
179
- return reply.code(401).send();
152
+ fastify.get('/authz/tunnel/:fqdn', { config: INTERNAL_RATE_LIMIT }, async (request, reply) => authorizeTunnelRequest(fastify, request, reply, request.params.fqdn));
153
+ /**
154
+ * GET /authz/check — what tunnel vhosts written before 4.3 call. They name
155
+ * the tunnel by the client's Host header (`$http_host`), which an
156
+ * absolute-form request line can point at another tunnel than the one
157
+ * nginx serves, so their requests are refused: until the panel rewrites
158
+ * such a vhost (it does when it starts) its tunnel is closed, rather than
159
+ * open to the users of every other tunnel.
160
+ */
161
+ fastify.get('/authz/check', { config: INTERNAL_RATE_LIMIT }, async (request, reply) => {
162
+ request.log.error({
163
+ requestId: request.id,
164
+ reason: 'vhost_predates_host_binding',
165
+ hostHeader: request.headers['host'],
166
+ }, 'authz refused: this tunnel vhost names its tunnel by the client Host header; restart lamalibre-lamaste-serverd to rewrite it');
167
+ return reply
168
+ .code(403)
169
+ .header('Cache-Control', 'no-store')
170
+ .type('text/plain; charset=utf-8')
171
+ .send('This tunnel is unavailable until the relay rewrites its configuration.\n');
172
+ });
173
+ }
174
+ /**
175
+ * Authorize one request on the tunnel named `fqdn` (see the
176
+ * `/authz/tunnel/:fqdn` route).
177
+ */
178
+ async function authorizeTunnelRequest(fastify, request, reply, fqdn) {
179
+ const requestId = request.id;
180
+ if (!TUNNEL_FQDN_RE.test(fqdn)) {
181
+ request.log.info({ requestId, reason: 'invalid_tunnel_name' }, 'authz denied');
182
+ return reply.code(401).send();
183
+ }
184
+ const cookie = request.headers['cookie'] ?? '';
185
+ const originalUrl = request.headers['x-original-url'] ?? '';
186
+ if (!cookie || !originalUrl) {
187
+ return reply.code(401).send();
188
+ }
189
+ const parsed = parseOriginalUrl(originalUrl);
190
+ if (!parsed) {
191
+ request.log.info({ requestId, reason: 'invalid_original_url' }, 'authz denied');
192
+ return reply.code(401).send();
193
+ }
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');
208
+ return reply.code(401).send();
209
+ }
210
+ const tunnels = fastify.getTunnels();
211
+ const tunnel = findTunnelByFqdn(tunnels, fqdn);
212
+ if (!tunnel) {
213
+ request.log.info({ requestId, reason: 'unknown_tunnel_fqdn', fqdn }, 'authz denied');
214
+ return reply.code(401).send();
215
+ }
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');
224
+ 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);
180
238
  }
181
- // Check session cache (keyed by Authelia session cookie only to prevent
182
- // cache pollution via unrelated cookies like CSRF tokens or analytics).
183
- const autheliaCookie = extractAutheliaCookie(cookie);
184
- if (!autheliaCookie) {
185
- // No authelia_session — short-circuit before any cache work or the
186
- // upstream Authelia /verify call. Without this, an unauthenticated
187
- // request would still cost us an Authelia round-trip.
188
- request.log.info({ requestId, reason: 'missing_authelia_cookie', fqdn: parsed.hostname }, 'authz denied');
239
+ const validated = await validateWithAuthelia(cookie, originalUrl, requestId);
240
+ if (!validated) {
241
+ request.log.info({ requestId, reason: 'authelia_rejected', fqdn: parsed.hostname }, 'authz denied');
189
242
  return reply.code(401).send();
190
243
  }
191
- const cacheKey = hashCookie(autheliaCookie);
192
- const sessionCache = fastify.getSessionCache();
193
- const cached = sessionCache.get(cacheKey);
194
- const now = Date.now();
195
- let session;
196
- if (cached && cached.expiresAt > now) {
197
- session = cached;
198
- }
199
- else {
200
- if (cached) {
201
- // Lazy TTL eviction — one stale entry pruned per request.
202
- sessionCache.delete(cacheKey);
203
- }
204
- const validated = await validateWithAuthelia(cookie, originalUrl, requestId);
205
- if (!validated) {
206
- request.log.info({ requestId, reason: 'authelia_rejected', fqdn: parsed.hostname }, 'authz denied');
207
- return reply.code(401).send();
208
- }
209
- // Opportunistic eviction — drop oldest (insertion-order head) when at cap.
210
- while (sessionCache.size >= MAX_SESSION_CACHE_ENTRIES) {
211
- const oldestKey = sessionCache.keys().next().value;
212
- if (oldestKey === undefined)
213
- break;
214
- sessionCache.delete(oldestKey);
215
- }
216
- sessionCache.set(cacheKey, validated);
217
- session = validated;
218
- }
219
- // Check access mode
220
- if (tunnel.accessMode === 'public' || tunnel.accessMode === 'authenticated') {
221
- setAutheliaHeaders(reply, session);
222
- reply.header('Cache-Control', `public, max-age=${AUTHZ_SUCCESS_MAX_AGE_SECONDS}`);
223
- reply.header('X-Gatekeeper-Cache-Version', String(fastify.getCacheVersion()));
224
- return reply.code(200).send();
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);
225
250
  }
226
- // restricted — check grants
227
- const result = await checkAccess(session.username, 'tunnel', tunnel.id, {
228
- adminContact: fastify.getSettings().adminEmail,
229
- adminName: fastify.getSettings().adminName,
230
- });
231
- if (result.allowed) {
232
- setAutheliaHeaders(reply, session);
233
- reply.header('Cache-Control', `public, max-age=${AUTHZ_SUCCESS_MAX_AGE_SECONDS}`);
234
- reply.header('X-Gatekeeper-Cache-Version', String(fastify.getCacheVersion()));
235
- return reply.code(200).send();
236
- }
237
- request.log.info({
238
- requestId,
239
- reason: 'no_matching_grant',
251
+ sessionCache.set(cacheKey, validated);
252
+ session = validated;
253
+ }
254
+ // Check access mode
255
+ if (tunnel.accessMode === 'public' || tunnel.accessMode === 'authenticated') {
256
+ return allow(fastify, request, reply, tunnel, session);
257
+ }
258
+ // restricted — check grants
259
+ const result = await checkAccess(session.username, 'tunnel', tunnel.id, {
260
+ adminContact: fastify.getSettings().adminEmail,
261
+ adminName: fastify.getSettings().adminName,
262
+ });
263
+ if (result.allowed) {
264
+ return allow(fastify, request, reply, tunnel, session);
265
+ }
266
+ request.log.info({
267
+ requestId,
268
+ reason: 'no_matching_grant',
269
+ username: session.username,
270
+ resourceType: 'tunnel',
271
+ resourceId: tunnel.id,
272
+ requiredGrant: `tunnel:${tunnel.id}`,
273
+ fqdn: parsed.hostname,
274
+ }, 'authz denied');
275
+ if (fastify.getSettings().accessLoggingEnabled) {
276
+ logAccessRequest({
277
+ timestamp: new Date().toISOString(),
240
278
  username: session.username,
241
279
  resourceType: 'tunnel',
242
280
  resourceId: tunnel.id,
243
- requiredGrant: `tunnel:${tunnel.id}`,
244
- fqdn: parsed.hostname,
245
- }, 'authz denied');
246
- if (fastify.getSettings().accessLoggingEnabled) {
247
- logAccessRequest({
248
- timestamp: new Date().toISOString(),
249
- username: session.username,
250
- resourceType: 'tunnel',
251
- resourceId: tunnel.id,
252
- resourceFqdn: parsed.hostname,
253
- });
254
- }
255
- // Access denied — return inline HTML page as 403 body.
256
- // Cache-Control: no-store so nginx never caches the denial; the matching
257
- // proxy_cache_valid 403 0 in the snippet is the authoritative setting.
258
- const html = buildAccessRequestPage(session.username, parsed.hostname, {
259
- adminContact: fastify.getSettings().adminEmail,
260
- adminName: fastify.getSettings().adminName,
281
+ resourceFqdn: parsed.hostname,
261
282
  });
262
- return reply
263
- .code(403)
264
- .header('Cache-Control', 'no-store')
265
- .type('text/html; charset=utf-8')
266
- .send(html);
283
+ }
284
+ // Access denied — return inline HTML page as 403 body.
285
+ // Cache-Control: no-store so nginx never caches the denial; the matching
286
+ // proxy_cache_valid 403 0 in the snippet is the authoritative setting.
287
+ const html = buildAccessRequestPage(session.username, parsed.hostname, {
288
+ adminContact: fastify.getSettings().adminEmail,
289
+ adminName: fastify.getSettings().adminName,
267
290
  });
291
+ return reply
292
+ .code(403)
293
+ .header('Cache-Control', 'no-store')
294
+ .type('text/html; charset=utf-8')
295
+ .send(html);
296
+ }
297
+ /**
298
+ * Answer an allowed request: the Authelia identity headers nginx forwards
299
+ * to the tunnel backend.
300
+ *
301
+ * A plugin tunnel's backend is the agent's lamaste-agentd, which takes the
302
+ * user only from a relay assertion — anything that reaches its loopback port
303
+ * could write `Remote-User`. Sign one for this request: the agent, its
304
+ * daemon's port, the plugin route, the method, a nonce. It is single use,
305
+ * so the answer must never be cached.
306
+ */
307
+ async function allow(fastify, request, reply, tunnel, session) {
308
+ reply.header('X-Gatekeeper-Cache-Version', String(fastify.getCacheVersion()));
309
+ if (!tunnel.plugin) {
310
+ setAutheliaHeaders(reply, session);
311
+ reply.header('Cache-Control', `public, max-age=${AUTHZ_SUCCESS_MAX_AGE_SECONDS}`);
312
+ return reply.code(200).send();
313
+ }
314
+ 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
+ }
322
+ if (!key) {
323
+ request.log.error({ requestId: request.id, reason: 'relay_signing_key_unavailable', fqdn: tunnel.fqdn }, 'authz failed');
324
+ return reply.code(503).send();
325
+ }
326
+ const originalMethod = request.headers['x-original-method'];
327
+ let assertion;
328
+ try {
329
+ assertion = signRelayAssertion({
330
+ aud: tunnel.plugin.agentLabel,
331
+ port: tunnel.plugin.port,
332
+ caller: {
333
+ type: 'user',
334
+ username: session.username,
335
+ groups: session.groups
336
+ .split(',')
337
+ .map((g) => g.trim())
338
+ .filter((g) => g.length > 0),
339
+ name: session.displayName,
340
+ email: session.email,
341
+ },
342
+ method: typeof originalMethod === 'string' ? originalMethod : 'GET',
343
+ target: { route: tunnel.plugin.route },
344
+ }, key);
345
+ }
346
+ catch (err) {
347
+ // An identity an assertion cannot carry (a username outside
348
+ // [A-Za-z0-9_.-], control characters, ...) — the agent would refuse it.
349
+ request.log.info({
350
+ requestId: request.id,
351
+ reason: 'identity_not_assertable',
352
+ detail: err instanceof Error ? err.message : String(err),
353
+ fqdn: tunnel.fqdn,
354
+ }, 'authz denied');
355
+ return reply.code(403).send();
356
+ }
357
+ setAutheliaHeaders(reply, session);
358
+ reply.header(RELAY_ASSERTION_HEADER, assertion);
359
+ return reply.code(200).send();
268
360
  }
269
361
  /**
270
362
  * Set Authelia identity headers on the response so nginx can