@lamalibre/create-lamaste 4.6.0 → 4.7.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 (149) hide show
  1. package/package.json +2 -2
  2. package/scripts/bundle-vendor.js +20 -3
  3. package/scripts/lamaste-priv +22 -3
  4. package/scripts/pin-release.js +98 -0
  5. package/src/index.js +8 -1
  6. package/src/lib/env.js +19 -0
  7. package/src/lib/service-config.js +7 -0
  8. package/src/tasks/redeploy.js +8 -0
  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 +6 -2
  13. package/vendor/docs/01-concepts/authorization.md +4 -0
  14. package/vendor/docs/01-concepts/certificates.md +3 -3
  15. package/vendor/docs/01-concepts/dns-and-domains.md +9 -0
  16. package/vendor/docs/01-concepts/mtls.md +2 -2
  17. package/vendor/docs/01-concepts/security-model.md +28 -3
  18. package/vendor/docs/01-concepts/tickets.md +2 -2
  19. package/vendor/docs/01-concepts/tunneling.md +4 -4
  20. package/vendor/docs/02-guides/agent-setup.md +5 -5
  21. package/vendor/docs/02-guides/certificate-management.md +2 -2
  22. package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
  23. package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
  24. package/vendor/docs/02-guides/installation.md +3 -3
  25. package/vendor/docs/02-guides/managing-users.md +5 -11
  26. package/vendor/docs/02-guides/onboarding.md +2 -2
  27. package/vendor/docs/02-guides/second-domain.md +82 -0
  28. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
  29. package/vendor/docs/03-architecture/installer-flow.md +2 -2
  30. package/vendor/docs/03-architecture/installer.md +4 -4
  31. package/vendor/docs/03-architecture/management-flow.md +1 -1
  32. package/vendor/docs/03-architecture/nginx-configuration.md +15 -5
  33. package/vendor/docs/03-architecture/overview.md +5 -5
  34. package/vendor/docs/03-architecture/panel-client.md +6 -6
  35. package/vendor/docs/03-architecture/panel-server.md +2 -2
  36. package/vendor/docs/03-architecture/state-management.md +3 -3
  37. package/vendor/docs/03-architecture/system-overview.md +1 -1
  38. package/vendor/docs/04-api-reference/agent-hosted-plugins.md +17 -13
  39. package/vendor/docs/04-api-reference/app-host.md +3 -3
  40. package/vendor/docs/04-api-reference/domains.md +192 -0
  41. package/vendor/docs/04-api-reference/gatekeeper.md +35 -7
  42. package/vendor/docs/04-api-reference/lifecycle-hooks.md +4 -4
  43. package/vendor/docs/04-api-reference/onboarding.md +1 -1
  44. package/vendor/docs/04-api-reference/overview.md +9 -0
  45. package/vendor/docs/04-api-reference/registry-and-oidc.md +26 -13
  46. package/vendor/docs/04-api-reference/sites.md +5 -0
  47. package/vendor/docs/04-api-reference/tunnels.md +15 -10
  48. package/vendor/docs/04-api-reference/users.md +41 -29
  49. package/vendor/docs/05-operations/backup-and-restore.md +1 -1
  50. package/vendor/docs/05-operations/uninstalling.md +1 -1
  51. package/vendor/docs/05-operations/upgrades.md +6 -6
  52. package/vendor/docs/06-reference/config-files.md +1 -1
  53. package/vendor/docs/06-reference/glossary.md +3 -3
  54. package/vendor/docs/06-reference/installer-flags.md +13 -13
  55. package/vendor/docs/06-reference/ports-and-services.md +1 -1
  56. package/vendor/docs/06-reference/troubleshooting.md +8 -8
  57. package/vendor/docs/_index.json +105 -19
  58. package/vendor/docs/external-members-design.md +816 -0
  59. package/vendor/docs/gatekeeper-design.md +8 -8
  60. package/vendor/docs/identity-directory-design.md +3 -3
  61. package/vendor/docs/multi-domain-relay-design.md +836 -0
  62. package/vendor/docs/package.json +1 -1
  63. package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
  64. package/vendor/gatekeeper/dist/cli/index.js +0 -0
  65. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
  66. package/vendor/gatekeeper/dist/lib/grants.js +20 -13
  67. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
  68. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0004_unconsume_access_grants.sql +8 -0
  69. package/vendor/gatekeeper/dist/lib/secret.d.ts +6 -0
  70. package/vendor/gatekeeper/dist/lib/secret.d.ts.map +1 -0
  71. package/vendor/gatekeeper/dist/lib/secret.js +12 -0
  72. package/vendor/gatekeeper/dist/lib/secret.js.map +1 -0
  73. package/vendor/gatekeeper/dist/lib/templates.d.ts +20 -0
  74. package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -1
  75. package/vendor/gatekeeper/dist/lib/templates.js +80 -14
  76. package/vendor/gatekeeper/dist/lib/templates.js.map +1 -1
  77. package/vendor/gatekeeper/dist/server/index.d.ts +5 -1
  78. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
  79. package/vendor/gatekeeper/dist/server/index.js +28 -2
  80. package/vendor/gatekeeper/dist/server/index.js.map +1 -1
  81. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
  82. package/vendor/gatekeeper/dist/server/routes/authz.js +225 -36
  83. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
  84. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -1
  85. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +5 -2
  86. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
  87. package/vendor/gatekeeper/package.json +2 -2
  88. package/vendor/server/bin/lamaste-server.js +7 -0
  89. package/vendor/server/package.json +2 -2
  90. package/vendor/server/src/commands/domains.js +214 -0
  91. package/vendor/server/src/commands/plugin-identity.js +2 -16
  92. package/vendor/server/src/commands/plugins.js +112 -8
  93. package/vendor/server/src/commands/registry-credential.js +10 -3
  94. package/vendor/server/src/commands/sites.js +3 -0
  95. package/vendor/server/src/commands/status.js +19 -0
  96. package/vendor/server/src/commands/tunnels.js +4 -1
  97. package/vendor/server/src/commands/users.js +8 -19
  98. package/vendor/server/src/domains.js +92 -0
  99. package/vendor/server/src/fail.js +21 -0
  100. package/vendor/server/src/oidc-client-grants.js +63 -0
  101. package/vendor/server/src/panel-api.js +15 -0
  102. package/vendor/server-ui/dist/assets/index-B8Tv_ocF.js +84 -0
  103. package/vendor/server-ui/dist/assets/{index-BZwQ_aQc.css → index-Cb-ADsbB.css} +1 -1
  104. package/vendor/server-ui/dist/index.html +2 -2
  105. package/vendor/serverd/package.json +2 -2
  106. package/vendor/serverd/src/index.js +42 -16
  107. package/vendor/serverd/src/lib/app-error.js +24 -0
  108. package/vendor/serverd/src/lib/audience.js +12 -3
  109. package/vendor/serverd/src/lib/authelia.js +341 -35
  110. package/vendor/serverd/src/lib/directory.js +67 -52
  111. package/vendor/serverd/src/lib/domains.js +1792 -0
  112. package/vendor/serverd/src/lib/gatekeeper-client.js +20 -4
  113. package/vendor/serverd/src/lib/identity-sync.js +35 -0
  114. package/vendor/serverd/src/lib/migrations/state/0016_domains.sql +53 -0
  115. package/vendor/serverd/src/lib/migrations/state/0017_membership_kind.sql +15 -0
  116. package/vendor/serverd/src/lib/migrations/state/0018_domain_group_keys.sql +23 -0
  117. package/vendor/serverd/src/lib/nginx.js +318 -140
  118. package/vendor/serverd/src/lib/owned-groups.js +326 -0
  119. package/vendor/serverd/src/lib/plugin-domain.js +86 -0
  120. package/vendor/serverd/src/lib/plugin-lifecycle.js +1 -0
  121. package/vendor/serverd/src/lib/plugin-oidc.js +144 -42
  122. package/vendor/serverd/src/lib/plugins.js +45 -5
  123. package/vendor/serverd/src/lib/registry-credential.js +39 -6
  124. package/vendor/serverd/src/lib/services.js +9 -1
  125. package/vendor/serverd/src/lib/state.js +11 -0
  126. package/vendor/serverd/src/lib/tunnel-deps.js +2 -4
  127. package/vendor/serverd/src/lib/user-surface.js +29 -4
  128. package/vendor/serverd/src/lib/users-lock.js +23 -0
  129. package/vendor/serverd/src/lib/vhost-reconcile.js +149 -41
  130. package/vendor/serverd/src/lib/web-surface.js +49 -32
  131. package/vendor/serverd/src/middleware/user-access-session.js +11 -4
  132. package/vendor/serverd/src/routes/invite.js +15 -5
  133. package/vendor/serverd/src/routes/management/domains.js +154 -0
  134. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +44 -8
  135. package/vendor/serverd/src/routes/management/identity.js +21 -7
  136. package/vendor/serverd/src/routes/management/invitations.js +33 -4
  137. package/vendor/serverd/src/routes/management/plugins.js +4 -2
  138. package/vendor/serverd/src/routes/management/registry-credential.js +86 -57
  139. package/vendor/serverd/src/routes/management/sites.js +50 -11
  140. package/vendor/serverd/src/routes/management/tunnels.js +29 -5
  141. package/vendor/serverd/src/routes/management/users.js +184 -64
  142. package/vendor/serverd/src/routes/management.js +2 -0
  143. package/vendor/serverd/src/routes/onboarding/dns.js +3 -17
  144. package/vendor/serverd/src/routes/onboarding/provision.js +22 -13
  145. package/vendor/serverd/src/routes/user-access.js +13 -1
  146. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +0 -7
  147. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +0 -14
  148. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +0 -9
  149. package/vendor/server-ui/dist/assets/index-BvEfCZYS.js +0 -84
@@ -12,6 +12,7 @@ import { migrateChiselCredentialsIfNeeded } from '../../lib/chisel-users.js';
12
12
  import { loadAgentRegistry } from '../../lib/mtls.js';
13
13
  import { setChiselRunningPinnedRelease } from '../../lib/chisel-runtime.js';
14
14
  import { changeUsers } from '../../lib/directory.js';
15
+ import { ensurePrimaryDomain, syncDomainAccess } from '../../lib/domains.js';
15
16
 
16
17
  // Module-level state for provisioning
17
18
  const emitter = new EventEmitter();
@@ -115,24 +116,16 @@ async function runProvisioning(log) {
115
116
  'Authelia is not installed. Run `npx @lamalibre/create-lamaste` on the server to repair the installation.',
116
117
  );
117
118
  }
118
- emitProgress('install-authelia', 'running', 'Writing configuration...');
119
-
120
- const secrets = {
121
- jwtSecret: crypto.randomBytes(32).toString('hex'),
122
- sessionSecret: crypto.randomBytes(32).toString('hex'),
123
- storageEncryptionKey: crypto.randomBytes(32).toString('hex'),
124
- };
125
- await authelia.writeAutheliaConfig(domain, secrets);
126
-
127
119
  emitProgress('install-authelia', 'running', 'Creating admin user...');
128
120
  adminPassword = crypto.randomBytes(16).toString('base64url');
129
121
  // Through the users lock, and into the user directory — which reconciles
130
- // with users.yml from here on. Authelia starts next, so no restart.
122
+ // with users.yml from here on. The domain is rendered below, once it
123
+ // exists.
131
124
  const created = await changeUsers(() => authelia.createUser('admin', adminPassword), {
132
125
  actor: 'lamaste',
133
126
  logger: log,
134
127
  creates: ['admin'],
135
- restartAuthelia: false,
128
+ renderDomains: false,
136
129
  // Authelia's storage does not exist before its first start.
137
130
  autheliaStorage: false,
138
131
  });
@@ -140,6 +133,21 @@ async function runProvisioning(log) {
140
133
  log.warn({ step: warning.step }, warning.message);
141
134
  }
142
135
 
136
+ // The primary domain with the administrator as its member — rendered
137
+ // into users.yml's groups and Gatekeeper's projection before Authelia
138
+ // first starts, so its first configuration already admits them (the
139
+ // configuration it is rendered from is the one written here: nothing to
140
+ // restart). The panel renders every later change.
141
+ emitProgress('install-authelia', 'running', 'Writing configuration...');
142
+ await ensurePrimaryDomain({ logger: log });
143
+ const secrets = {
144
+ jwtSecret: crypto.randomBytes(32).toString('hex'),
145
+ sessionSecret: crypto.randomBytes(32).toString('hex'),
146
+ storageEncryptionKey: crypto.randomBytes(32).toString('hex'),
147
+ };
148
+ await authelia.writeAutheliaConfig(domain, secrets);
149
+ await syncDomainAccess({ logger: log });
150
+
143
151
  emitProgress('install-authelia', 'running', 'Starting Authelia service...');
144
152
  await authelia.startAuthelia();
145
153
  emitProgress('install-authelia', 'done', 'Authelia configured and running');
@@ -156,7 +164,7 @@ async function runProvisioning(log) {
156
164
  await nginx.writePanelVhost(domain);
157
165
 
158
166
  emitProgress('configure-nginx', 'running', 'Writing auth vhost...');
159
- await nginx.writeAuthVhost(domain);
167
+ await nginx.writeAuthVhost(domain, { primary: true });
160
168
 
161
169
  emitProgress('configure-nginx', 'running', 'Writing tunnel vhost...');
162
170
  await nginx.writeTunnelVhost(domain);
@@ -166,7 +174,6 @@ async function runProvisioning(log) {
166
174
 
167
175
  emitProgress('configure-nginx', 'running', 'Enabling sites...');
168
176
  await nginx.enableSite('lamalibre-lamaste-panel-domain');
169
- await nginx.enableSite('lamalibre-lamaste-auth');
170
177
  await nginx.enableSite('lamalibre-lamaste-tunnel');
171
178
 
172
179
  emitProgress('configure-nginx', 'running', 'Testing nginx configuration...');
@@ -217,6 +224,8 @@ async function runProvisioning(log) {
217
224
  // Step 6: Finalize
218
225
  emitProgress('finalize', 'running', 'Updating configuration...');
219
226
  await updateConfig({ onboarding: { status: 'COMPLETED' } });
227
+ // Gatekeeper's projection of the domain (Authelia holds it already).
228
+ await syncDomainAccess({ logger: log });
220
229
 
221
230
  const result = {
222
231
  adminUsername: 'admin',
@@ -4,6 +4,7 @@ import { getConfig } from '../lib/config.js';
4
4
  import { ensureSessionSecret } from '../lib/session.js';
5
5
  import { createUserSession } from '../lib/user-access-session.js';
6
6
  import { findDirectoryUser, reconcileDirectory } from '../lib/directory.js';
7
+ import { isPrimaryMember } from '../lib/domains.js';
7
8
  import {
8
9
  createGrant,
9
10
  listGrants,
@@ -166,6 +167,17 @@ export async function userAccessPublicRoutes(fastify, _opts) {
166
167
  if (!username) {
167
168
  return reply.code(401).send({ error: 'Authentication required' });
168
169
  }
170
+ // Authelia admits external members on the portal too (its rule for
171
+ // `auth.<domain>`); desktop user access is for members of the primary
172
+ // domain only.
173
+ let holder = await findDirectoryUser(username);
174
+ if (!holder) {
175
+ await reconcileDirectory({ actor: 'lamaste', logger: request.log });
176
+ holder = await findDirectoryUser(username);
177
+ }
178
+ if (!holder || holder.status !== 'active' || !(await isPrimaryMember(holder.userId))) {
179
+ return reply.code(403).send({ error: 'Desktop access is for members of this domain' });
180
+ }
169
181
 
170
182
  let query;
171
183
  try {
@@ -245,7 +257,7 @@ export async function userAccessPublicRoutes(fastify, _opts) {
245
257
  await reconcileDirectory({ actor: 'lamaste', logger: request.log });
246
258
  user = await findDirectoryUser(username);
247
259
  }
248
- if (!user || user.status !== 'active') {
260
+ if (!user || user.status !== 'active' || !(await isPrimaryMember(user.userId))) {
249
261
  throw Object.assign(new Error('Invalid or expired token'), { statusCode: 401 });
250
262
  }
251
263
  const sessionSecret = await ensureSessionSecret();
@@ -1,7 +0,0 @@
1
- CREATE TABLE groups (
2
- name TEXT PRIMARY KEY,
3
- description TEXT NOT NULL DEFAULT '',
4
- members TEXT NOT NULL DEFAULT '[]', -- JSON array of usernames
5
- created_at TEXT NOT NULL,
6
- created_by TEXT NOT NULL DEFAULT 'admin'
7
- );
@@ -1,14 +0,0 @@
1
- CREATE TABLE access_grants (
2
- grant_id TEXT PRIMARY KEY, -- UUID
3
- principal_type TEXT NOT NULL, -- 'user' | 'group'
4
- principal_id TEXT NOT NULL,
5
- resource_type TEXT NOT NULL, -- 'tunnel' | 'plugin' | extensible
6
- resource_id TEXT NOT NULL,
7
- context TEXT NOT NULL DEFAULT '{}', -- JSON object
8
- used INTEGER NOT NULL DEFAULT 0,
9
- created_at TEXT NOT NULL,
10
- used_at TEXT
11
- );
12
- CREATE INDEX idx_grants_principal ON access_grants(principal_type, principal_id);
13
- CREATE INDEX idx_grants_resource ON access_grants(resource_type, resource_id);
14
- CREATE INDEX idx_grants_used_used_at ON access_grants(used, used_at);
@@ -1,9 +0,0 @@
1
- CREATE TABLE access_request_log (
2
- id INTEGER PRIMARY KEY AUTOINCREMENT,
3
- timestamp TEXT NOT NULL,
4
- username TEXT NOT NULL,
5
- resource_type TEXT NOT NULL,
6
- resource_id TEXT NOT NULL,
7
- resource_fqdn TEXT NOT NULL
8
- );
9
- CREATE INDEX idx_access_log_timestamp ON access_request_log(timestamp);