@lamalibre/create-lamaste 4.4.1 → 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 (149) 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 +291 -22
  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 +14 -12
  40. package/vendor/docs/04-api-reference/onboarding.md +1 -1
  41. package/vendor/docs/04-api-reference/registry-and-oidc.md +3 -3
  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 +82 -188
  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/plugins.js +59 -4
  125. package/vendor/serverd/src/lib/registry-credential.js +9 -6
  126. package/vendor/serverd/src/lib/request-logging.js +19 -0
  127. package/vendor/serverd/src/lib/retained-data.js +50 -4
  128. package/vendor/serverd/src/lib/state.js +18 -0
  129. package/vendor/serverd/src/lib/tunnel-hooks.js +4 -1
  130. package/vendor/serverd/src/lib/user-access-session.js +21 -11
  131. package/vendor/serverd/src/lib/user-caller.js +67 -0
  132. package/vendor/serverd/src/lib/user-surface.js +733 -0
  133. package/vendor/serverd/src/lib/vhost-reconcile.js +136 -34
  134. package/vendor/serverd/src/middleware/user-access-session.js +9 -0
  135. package/vendor/serverd/src/routes/agent-forwarder.js +4 -2
  136. package/vendor/serverd/src/routes/invite.js +53 -12
  137. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +107 -16
  138. package/vendor/serverd/src/routes/management/identity-directory.js +79 -0
  139. package/vendor/serverd/src/routes/management/invitations.js +78 -68
  140. package/vendor/serverd/src/routes/management/plugin-identity.js +221 -0
  141. package/vendor/serverd/src/routes/management/registry-credential.js +1 -1
  142. package/vendor/serverd/src/routes/management/tunnels.js +98 -2
  143. package/vendor/serverd/src/routes/management/users.js +290 -208
  144. package/vendor/serverd/src/routes/management.js +4 -0
  145. package/vendor/serverd/src/routes/onboarding/provision.js +14 -1
  146. package/vendor/serverd/src/routes/user-access.js +17 -4
  147. package/vendor/serverd/src/routes/user-surface.js +69 -0
  148. package/vendor/server-ui/dist/assets/index-25wo_8av.css +0 -1
  149. package/vendor/server-ui/dist/assets/index-roDHz3dM.js +0 -84
@@ -0,0 +1,158 @@
1
+ -- The user directory and each plugin's audience (4.5, slice 6).
2
+ --
3
+ -- Authelia's users.yml stays its credential file; this directory gives every
4
+ -- user a stable id the panel tells plugins about, and keeps what the panel
5
+ -- last knew of a user after the user is gone (lib/directory.js). The panel
6
+ -- never writes users.yml from here: it reconciles this directory against the
7
+ -- file after its own writes, at start and every minute — read only.
8
+
9
+ -- This directory's identity: a UUID v4 made once, when the store is created.
10
+ -- A store that is replaced (a fresh state.db) has another id, which tells an
11
+ -- agent half that its cursor no longer means anything (it replays from 0).
12
+ CREATE TABLE directory_meta (
13
+ id INTEGER PRIMARY KEY CHECK (id = 1),
14
+ directory_id TEXT NOT NULL,
15
+ created_at TEXT NOT NULL
16
+ );
17
+ INSERT INTO directory_meta (id, directory_id, created_at)
18
+ SELECT 1,
19
+ substr(h, 1, 8) || '-' || substr(h, 9, 4) || '-4' || substr(h, 14, 3) || '-' ||
20
+ substr('89ab', 1 + (random() & 3), 1) || substr(h, 18, 3) || '-' || substr(h, 21, 12),
21
+ strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
22
+ FROM (SELECT lower(hex(randomblob(16))) AS h);
23
+
24
+ -- The store-wide sequence the audience triggers stamp changes with. It only
25
+ -- grows: a cursor on it never sees a number twice, across every plugin.
26
+ CREATE TABLE directory_counter (
27
+ id INTEGER PRIMARY KEY CHECK (id = 1),
28
+ seq INTEGER NOT NULL
29
+ );
30
+ INSERT INTO directory_counter (id, seq) VALUES (1, 0);
31
+
32
+ -- One row per user the directory ever knew, never deleted:
33
+ -- user_id UUID v4, made when the username first appeared
34
+ -- username, display_name, email
35
+ -- as users.yml last had them (display_name / email NULL
36
+ -- when it had none); all three NULL once erased
37
+ -- status active | disabled (Authelia's `disabled: true`) | removed
38
+ -- removed_reason deleted (through Lamaste) | deleted-outside (gone from
39
+ -- users.yml without Lamaste) — set exactly when removed
40
+ -- removed_at when the user was removed
41
+ -- erased_at when an administrator erased the tombstone
42
+ -- principal_cleared_at
43
+ -- when Gatekeeper removed everything it held under the
44
+ -- removed user's username — the grants naming it and its
45
+ -- group memberships (Gatekeeper keys users by username,
46
+ -- which a later user may reuse). NULL on a removed row:
47
+ -- pending, retried every minute; the username is not given
48
+ -- to a new user, and no username with a pending cleanup
49
+ -- holds a role, until it is set. Set before an erasure
50
+ -- scrubs the username it needs.
51
+ -- version 1 at creation, +1 on every change of the row
52
+ -- A username names at most one user that is not removed; a removed user
53
+ -- keeps it (history stays readable) until erased, and a username that comes
54
+ -- back is a new user with a new id.
55
+ CREATE TABLE directory_users (
56
+ user_id TEXT PRIMARY KEY,
57
+ username TEXT,
58
+ display_name TEXT,
59
+ email TEXT,
60
+ status TEXT NOT NULL CHECK (status IN ('active', 'disabled', 'removed')),
61
+ removed_reason TEXT CHECK (removed_reason IS NULL OR removed_reason IN ('deleted', 'deleted-outside')),
62
+ removed_at TEXT,
63
+ erased_at TEXT,
64
+ principal_cleared_at TEXT,
65
+ version INTEGER NOT NULL CHECK (version >= 1),
66
+ created_at TEXT NOT NULL,
67
+ updated_at TEXT NOT NULL,
68
+ CHECK ((status = 'removed') = (removed_reason IS NOT NULL)),
69
+ CHECK ((status = 'removed') = (removed_at IS NOT NULL)),
70
+ CHECK (status = 'removed' OR username IS NOT NULL),
71
+ CHECK (erased_at IS NULL OR (status = 'removed' AND username IS NULL
72
+ AND display_name IS NULL AND email IS NULL)),
73
+ CHECK (principal_cleared_at IS NULL OR status = 'removed'),
74
+ CHECK (erased_at IS NULL OR principal_cleared_at IS NOT NULL)
75
+ );
76
+ CREATE UNIQUE INDEX directory_users_username ON directory_users (username)
77
+ WHERE status <> 'removed';
78
+ -- The removed users whose Gatekeeper principal is still to be cleared.
79
+ CREATE INDEX directory_users_principal_pending ON directory_users (username)
80
+ WHERE status = 'removed' AND principal_cleared_at IS NULL;
81
+
82
+ -- Each plugin's audience as last delivered (lib/audience.js): one row per
83
+ -- plugin and user who was ever a member, the change the feed carries for
84
+ -- them (the AudienceChange body without `seq`: an `upsert` with the member,
85
+ -- or a `remove` with its reason and, but for `erased`, the last known
86
+ -- declared attributes), its version (+1 whenever the change differs) and the
87
+ -- `seq` the triggers below stamp. Rows are written only when the change
88
+ -- differs; users who were never members have none. The plugin's ledger: kept
89
+ -- while any agent keeps data of the plugin (see 0014).
90
+ CREATE TABLE plugin_audience (
91
+ plugin TEXT NOT NULL,
92
+ user_id TEXT NOT NULL REFERENCES directory_users (user_id),
93
+ change TEXT NOT NULL,
94
+ version INTEGER NOT NULL CHECK (version >= 1),
95
+ seq INTEGER NOT NULL DEFAULT 0,
96
+ updated_at TEXT NOT NULL,
97
+ PRIMARY KEY (plugin, user_id)
98
+ );
99
+ CREATE INDEX plugin_audience_seq ON plugin_audience (plugin, seq);
100
+
101
+ -- A new row, and a row whose change was rewritten, take the next store-wide
102
+ -- seq. Only an UPDATE that names `change` stamps: the stamp itself updates
103
+ -- `seq` alone, so it does not fire again.
104
+ CREATE TRIGGER plugin_audience_stamp_insert AFTER INSERT ON plugin_audience
105
+ BEGIN
106
+ UPDATE directory_counter SET seq = seq + 1 WHERE id = 1;
107
+ UPDATE plugin_audience SET seq = (SELECT seq FROM directory_counter WHERE id = 1)
108
+ WHERE plugin = NEW.plugin AND user_id = NEW.user_id;
109
+ END;
110
+ CREATE TRIGGER plugin_audience_stamp_update AFTER UPDATE OF change ON plugin_audience
111
+ BEGIN
112
+ UPDATE directory_counter SET seq = seq + 1 WHERE id = 1;
113
+ UPDATE plugin_audience SET seq = (SELECT seq FROM directory_counter WHERE id = 1)
114
+ WHERE plugin = NEW.plugin AND user_id = NEW.user_id;
115
+ END;
116
+
117
+ -- What the panel knows of each plugin's agent half and its feed
118
+ -- (lib/identity-sync.js):
119
+ -- directory_id the directory the half follows, as it last answered
120
+ -- cursor the seq it has applied up to, as it last answered
121
+ -- ready_version the plugin version installed when the half last
122
+ -- applied every change up to the head after a complete
123
+ -- replay — user callers go to the half only while it is
124
+ -- the installed version
125
+ -- last_sync_at the last sync that ended with the half up to date
126
+ -- last_reconcile_at the last full replay (a reset or the daily reconcile);
127
+ -- cleared when one starts, so one cut short is owed
128
+ -- last_mismatches what the last daily reconcile found (null otherwise)
129
+ -- last_error why the last sync did not finish (or was not tried)
130
+ -- Removed when its hosting is removed (the half of a later hosting is sent
131
+ -- everything, and is ready only once it has applied it) and with the
132
+ -- plugin's ledger (0014); kept when the plugin stops declaring identity.
133
+ CREATE TABLE plugin_identity_sync (
134
+ plugin TEXT PRIMARY KEY,
135
+ directory_id TEXT,
136
+ cursor INTEGER,
137
+ ready_version TEXT,
138
+ last_sync_at TEXT,
139
+ last_reconcile_at TEXT,
140
+ last_mismatches INTEGER,
141
+ last_error TEXT,
142
+ updated_at TEXT NOT NULL
143
+ );
144
+
145
+ -- Who erased a removed user, and when. The erasure itself is the scrubbed
146
+ -- directory row; each plugin acknowledges it when its half's cursor passes
147
+ -- the `remove/erased` change of its audience.
148
+ CREATE TABLE directory_erasures (
149
+ user_id TEXT PRIMARY KEY REFERENCES directory_users (user_id),
150
+ requested_at TEXT NOT NULL,
151
+ requested_by TEXT NOT NULL
152
+ );
153
+
154
+ -- The manifest's `identity` block as normalized (core
155
+ -- `normalizeIdentityBlock`: roles by id, attributes sorted, the default
156
+ -- applied), NULL when the plugin declares none. It enters the approval
157
+ -- digest when present.
158
+ ALTER TABLE plugins ADD COLUMN identity TEXT;
@@ -0,0 +1,20 @@
1
+ -- Erasure obligations outlive a plugin's feed (4.5, slice 6).
2
+ --
3
+ -- plugin_audience (0013) is each plugin's ledger of everyone its agent
4
+ -- halves were ever sent, and so of the erasures it owes. It stays when the
5
+ -- plugin is uninstalled or stops declaring identity — its data stays on an
6
+ -- agent — and goes only once no data of the plugin is left anywhere: the
7
+ -- plugin is not installed and no agent retains its data (lib/audience.js
8
+ -- `dropIdentityLedgerIfNoData`). Erasing a user rewrites the user's row in
9
+ -- every ledger, so a plugin that comes back replays the erasure.
10
+ --
11
+ -- Data an agent retains (retained_agent_data, 0010) is an agent half's data
12
+ -- directory, its identity projection included. What that projection had
13
+ -- applied when the data was retained — the directory it followed and its
14
+ -- cursor, as the half last answered — is recorded with it: the erasures of
15
+ -- the plugin's ledger stamped after that cursor are pending on that agent
16
+ -- until the data is purged, or taken back by a hosting whose half replays
17
+ -- them. NULL when the relay knew no position (the half had never answered):
18
+ -- every erasure of the ledger is pending there.
19
+ ALTER TABLE retained_agent_data ADD COLUMN identity_directory_id TEXT;
20
+ ALTER TABLE retained_agent_data ADD COLUMN identity_cursor INTEGER;
@@ -854,16 +854,20 @@ export async function revokeAgentCert(label, logger) {
854
854
 
855
855
  // 7. Detach the agent from its tunnels, so a later enrollment that reuses
856
856
  // the label inherits nothing. Runs after the credential removal, whose
857
- // chisel restart already ended the agent's sessions.
857
+ // chisel restart already ended the agent's sessions. A released tunnel
858
+ // bound as a plugin's user surface serves none of it from now on: its
859
+ // vhost loses those locations.
858
860
  if (!label.startsWith(PLUGIN_AGENT_CN_PREFIX)) {
859
861
  try {
860
- await releaseAgentTunnels({
862
+ const { releasedIds } = await releaseAgentTunnels({
861
863
  agentLabel: label,
862
864
  nginx: tunnelNginxDeps,
863
865
  chisel: tunnelChiselDeps,
864
866
  state: tunnelStateDeps,
865
867
  logger,
866
868
  });
869
+ const { refreshTunnelUserSurfaceVhosts } = await import('./user-surface.js');
870
+ await refreshTunnelUserSurfaceVhosts(releasedIds, logger);
867
871
  } catch (err) {
868
872
  logger.error(
869
873
  { err, label },