@lamalibre/create-lamaste 4.4.1 → 4.6.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 (170) hide show
  1. package/package.json +2 -2
  2. package/scripts/lamaste-priv +234 -18
  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/02-guides/static-sites.md +4 -0
  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 +3 -1
  31. package/vendor/docs/03-architecture/nginx-configuration.md +229 -24
  32. package/vendor/docs/03-architecture/overview.md +13 -17
  33. package/vendor/docs/03-architecture/panel-client.md +6 -6
  34. package/vendor/docs/03-architecture/panel-server.md +3 -2
  35. package/vendor/docs/03-architecture/state-management.md +4 -8
  36. package/vendor/docs/03-architecture/system-overview.md +1 -1
  37. package/vendor/docs/04-api-reference/agent-hosted-plugins.md +378 -34
  38. package/vendor/docs/04-api-reference/app-host.md +3 -3
  39. package/vendor/docs/04-api-reference/gatekeeper.md +78 -5
  40. package/vendor/docs/04-api-reference/lifecycle-hooks.md +14 -12
  41. package/vendor/docs/04-api-reference/onboarding.md +1 -1
  42. package/vendor/docs/04-api-reference/registry-and-oidc.md +3 -3
  43. package/vendor/docs/04-api-reference/sites.md +4 -0
  44. package/vendor/docs/04-api-reference/tunnels.md +87 -47
  45. package/vendor/docs/04-api-reference/users.md +241 -45
  46. package/vendor/docs/05-operations/backup-and-restore.md +35 -26
  47. package/vendor/docs/05-operations/monitoring.md +39 -0
  48. package/vendor/docs/05-operations/uninstalling.md +2 -1
  49. package/vendor/docs/05-operations/upgrades.md +24 -6
  50. package/vendor/docs/06-reference/config-files.md +100 -202
  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 +25 -26
  54. package/vendor/docs/06-reference/troubleshooting.md +8 -8
  55. package/vendor/docs/gatekeeper-design.md +10 -8
  56. package/vendor/docs/identity-directory-design.md +48 -14
  57. package/vendor/docs/package.json +1 -1
  58. package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
  59. package/vendor/gatekeeper/dist/cli/index.js +0 -0
  60. package/vendor/gatekeeper/dist/index.d.ts +4 -3
  61. package/vendor/gatekeeper/dist/index.d.ts.map +1 -1
  62. package/vendor/gatekeeper/dist/index.js +4 -2
  63. package/vendor/gatekeeper/dist/index.js.map +1 -1
  64. package/vendor/gatekeeper/dist/lib/authz.d.ts +9 -0
  65. package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -1
  66. package/vendor/gatekeeper/dist/lib/authz.js +31 -0
  67. package/vendor/gatekeeper/dist/lib/authz.js.map +1 -1
  68. package/vendor/gatekeeper/dist/lib/constants.d.ts +5 -2
  69. package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -1
  70. package/vendor/gatekeeper/dist/lib/constants.js +5 -2
  71. package/vendor/gatekeeper/dist/lib/constants.js.map +1 -1
  72. package/vendor/gatekeeper/dist/lib/grants.d.ts +6 -0
  73. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
  74. package/vendor/gatekeeper/dist/lib/grants.js +6 -1
  75. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
  76. package/vendor/gatekeeper/dist/lib/groups.d.ts +5 -0
  77. package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -1
  78. package/vendor/gatekeeper/dist/lib/groups.js +5 -1
  79. package/vendor/gatekeeper/dist/lib/groups.js.map +1 -1
  80. package/vendor/gatekeeper/dist/lib/principals.d.ts +29 -0
  81. package/vendor/gatekeeper/dist/lib/principals.d.ts.map +1 -0
  82. package/vendor/gatekeeper/dist/lib/principals.js +67 -0
  83. package/vendor/gatekeeper/dist/lib/principals.js.map +1 -0
  84. package/vendor/gatekeeper/dist/lib/tunnels.d.ts +10 -0
  85. package/vendor/gatekeeper/dist/lib/tunnels.d.ts.map +1 -0
  86. package/vendor/gatekeeper/dist/lib/tunnels.js +56 -0
  87. package/vendor/gatekeeper/dist/lib/tunnels.js.map +1 -0
  88. package/vendor/gatekeeper/dist/server/index.d.ts +2 -1
  89. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
  90. package/vendor/gatekeeper/dist/server/index.js +49 -56
  91. package/vendor/gatekeeper/dist/server/index.js.map +1 -1
  92. package/vendor/gatekeeper/dist/server/routes/authz.d.ts +15 -1
  93. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
  94. package/vendor/gatekeeper/dist/server/routes/authz.js +332 -104
  95. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
  96. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -1
  97. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +61 -4
  98. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
  99. package/vendor/gatekeeper/dist/server/routes/principals.d.ts +3 -0
  100. package/vendor/gatekeeper/dist/server/routes/principals.d.ts.map +1 -0
  101. package/vendor/gatekeeper/dist/server/routes/principals.js +27 -0
  102. package/vendor/gatekeeper/dist/server/routes/principals.js.map +1 -0
  103. package/vendor/gatekeeper/package.json +2 -2
  104. package/vendor/server/bin/lamaste-server.js +15 -1
  105. package/vendor/server/package.json +2 -2
  106. package/vendor/server/src/commands/plugin-identity.js +335 -0
  107. package/vendor/server/src/commands/plugin-web-surface.js +269 -0
  108. package/vendor/server/src/commands/plugins.js +156 -11
  109. package/vendor/server/src/commands/registry-credential.js +2 -1
  110. package/vendor/server/src/commands/sites.js +15 -1
  111. package/vendor/server/src/commands/tunnels.js +102 -2
  112. package/vendor/server/src/commands/uninstall.js +3 -1
  113. package/vendor/server/src/commands/users.js +358 -0
  114. package/vendor/server/src/plugin-approval.js +186 -5
  115. package/vendor/server/src/plugin-identity.js +382 -0
  116. package/vendor/server/src/plugin-web-surface.js +307 -0
  117. package/vendor/server-ui/dist/assets/index-BZwQ_aQc.css +1 -0
  118. package/vendor/server-ui/dist/assets/index-BvEfCZYS.js +84 -0
  119. package/vendor/server-ui/dist/index.html +2 -2
  120. package/vendor/serverd/package.json +2 -2
  121. package/vendor/serverd/src/index.js +34 -5
  122. package/vendor/serverd/src/lib/audience.js +576 -0
  123. package/vendor/serverd/src/lib/authelia.js +78 -7
  124. package/vendor/serverd/src/lib/chisel-runtime.js +18 -6
  125. package/vendor/serverd/src/lib/chisel.js +10 -2
  126. package/vendor/serverd/src/lib/config.js +68 -43
  127. package/vendor/serverd/src/lib/directory.js +1113 -0
  128. package/vendor/serverd/src/lib/entitlements.js +517 -0
  129. package/vendor/serverd/src/lib/gatekeeper-client.js +226 -10
  130. package/vendor/serverd/src/lib/hook-pipelines.js +21 -3
  131. package/vendor/serverd/src/lib/identity-sync.js +905 -0
  132. package/vendor/serverd/src/lib/migrations/state/0013_identity_directory.sql +158 -0
  133. package/vendor/serverd/src/lib/migrations/state/0014_identity_ledger.sql +20 -0
  134. package/vendor/serverd/src/lib/migrations/state/0015_plugin_web_surface.sql +14 -0
  135. package/vendor/serverd/src/lib/mtls.js +6 -2
  136. package/vendor/serverd/src/lib/nginx.js +546 -48
  137. package/vendor/serverd/src/lib/plugin-hooks.js +127 -45
  138. package/vendor/serverd/src/lib/plugin-hosting.js +33 -5
  139. package/vendor/serverd/src/lib/plugin-lifecycle.js +227 -13
  140. package/vendor/serverd/src/lib/plugin-packages.js +74 -2
  141. package/vendor/serverd/src/lib/plugins.js +95 -7
  142. package/vendor/serverd/src/lib/registry-credential.js +9 -6
  143. package/vendor/serverd/src/lib/request-logging.js +19 -0
  144. package/vendor/serverd/src/lib/retained-data.js +50 -4
  145. package/vendor/serverd/src/lib/state.js +36 -0
  146. package/vendor/serverd/src/lib/tunnel-hooks.js +4 -1
  147. package/vendor/serverd/src/lib/user-access-session.js +21 -11
  148. package/vendor/serverd/src/lib/user-caller.js +67 -0
  149. package/vendor/serverd/src/lib/user-surface.js +754 -0
  150. package/vendor/serverd/src/lib/vhost-reconcile.js +137 -33
  151. package/vendor/serverd/src/lib/web-surface.js +766 -0
  152. package/vendor/serverd/src/middleware/user-access-session.js +9 -0
  153. package/vendor/serverd/src/routes/agent-forwarder.js +4 -2
  154. package/vendor/serverd/src/routes/invite.js +53 -12
  155. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +107 -16
  156. package/vendor/serverd/src/routes/management/identity-directory.js +79 -0
  157. package/vendor/serverd/src/routes/management/invitations.js +78 -68
  158. package/vendor/serverd/src/routes/management/plugin-identity.js +221 -0
  159. package/vendor/serverd/src/routes/management/plugin-web-surface.js +151 -0
  160. package/vendor/serverd/src/routes/management/plugins.js +2 -0
  161. package/vendor/serverd/src/routes/management/registry-credential.js +1 -1
  162. package/vendor/serverd/src/routes/management/sites.js +143 -65
  163. package/vendor/serverd/src/routes/management/tunnels.js +109 -22
  164. package/vendor/serverd/src/routes/management/users.js +290 -208
  165. package/vendor/serverd/src/routes/management.js +6 -0
  166. package/vendor/serverd/src/routes/onboarding/provision.js +14 -1
  167. package/vendor/serverd/src/routes/user-access.js +17 -4
  168. package/vendor/serverd/src/routes/user-surface.js +69 -0
  169. package/vendor/server-ui/dist/assets/index-25wo_8av.css +0 -1
  170. package/vendor/server-ui/dist/assets/index-roDHz3dM.js +0 -84
@@ -27,7 +27,7 @@ Coming from 3.x, upgrade the **agents first**, as 4.0 required: agents from befo
27
27
  On each agent machine, after the server:
28
28
 
29
29
  ```bash
30
- sudo npm install -g @lamalibre/lamaste-agent@4.4.1
30
+ sudo npm install -g @lamalibre/lamaste-agent@4.6.0
31
31
  lamaste-agent update
32
32
  ```
33
33
 
@@ -35,6 +35,24 @@ lamaste-agent update
35
35
 
36
36
  A machine that hosts app plugins' agent halves needs the root-owned install shown above and its app host helper enabled once with `sudo lamaste-agent apphost enable` (see [App host](../04-api-reference/app-host.md)); after replacing the server's relay signing key, run `sudo lamaste-agent apphost pin` there. An upgrade of `lamaste-agent` does not replace that helper: when a release raises the app host protocol (4.4 speaks 2), run `sudo lamaste-agent apphost enable` again there — until then the agent refuses to install agent halves and the server does not offer it for hosting (`lamaste-agent apphost status` shows the helper as out of date).
37
37
 
38
+ ### Upgrading to 4.6
39
+
40
+ 4.6 adds plugins' web surfaces ([Web surface](../04-api-reference/agent-hosted-plugins.md#web-surface)). **Only the relay is upgraded**: the panel's **Update** action, or a `create-lamaste@4.6.0 --yes` redeploy.
41
+
42
+ - **`state.db` migration `0015`** adds `plugins.user_surface` and `plugins.web_tree_sha256`. Existing plugins declare no web surface: their approval digests are unchanged.
43
+ - **`lamaste-priv` must be the 4.6 one** before the panel writes a web surface's vhost: it now accepts a server-level `auth_request`, named locations and a named location as `try_files`' last argument. The Update action and the redeploy install it; a relay whose `lamaste-priv` is older refuses the vhost (`nginx site write failed … directive "auth_request" is not allowed in server`) and keeps the vhost it had.
44
+ - **Web trees live under `/var/www/lamaste/apps/`.** They are copies of approved package contents, made again at the panel's start when missing: nothing there needs a backup.
45
+ - **What changes for existing setups.** Gatekeeper reads `sites.json` as well as `tunnels.json`. The check that a tunnel and a site never share a hostname now runs under the tunnel lock, for enabling a tunnel too. The sites API serves `sites.json` under a lock, and an upload's size is recorded from the file as it is then.
46
+
47
+ ### Upgrading to 4.5
48
+
49
+ 4.5 adds the user directory and users of agent-hosted plugins ([Users and identity](../04-api-reference/agent-hosted-plugins.md#users-and-identity)). **Only the relay is upgraded**: the panel's **Update** action, or a `create-lamaste@4.5.0 --yes` redeploy.
50
+
51
+ - **`state.db` migration `0013`.** On its first start the panel creates the user directory (a `directoryId`, a `userId` per user, tombstones), the plugin audiences, the per-plugin feed state and the erasure records, and adds `plugins.identity`. It then reads `users.yml` — without writing it — and gives every existing user a `userId`. Back up `state.db` before upgrading, as before any upgrade: from now on it holds the mapping from usernames to user ids ([Backup and Restore](backup-and-restore.md#backup-considerations)).
52
+ - **The redeploy now touches the IP panel vhost.** Until 4.4 a redeploy left every panel vhost alone. From 4.5 it refreshes `lamalibre-lamaste-panel-ip` — the vhost the installer writes and the panel cannot — when its text differs from the current generator's: written, checked with `nginx -t`, put back on failure, and nginx reloaded; its `sites-enabled` link (which panel 2FA owns) is left as it is. A failure is reported and skipped (`Refreshing the IP panel vhost — Skipped`): the panel keeps working on the vhost it had, which still passes a client's `X-Lamalibre-Relay-Assertion` through to the panel (which accepts only a valid, single-use one Gatekeeper signed) — fix what `nginx -t` names and redeploy. The panel itself rewrites the domain panel, auth portal and tunnel vhosts at start, as since 4.3; each now clears a client's `X-Lamalibre-Relay-Assertion`.
53
+ - **No agent upgrade is needed**, and no agent half must be rebuilt. An agent half built on `@lamalibre/lamaste@4.6.0` 4.4 keeps working and **never receives a user caller**: the panel sends one only after the half has answered the identity feed with protocol 1 for its installed version. A plugin gets users by shipping a version that declares `identity` with a half built on 4.5 — an update that waits for approval — then binding its user surface to a tunnel.
54
+ - **What changes for existing setups.** The admin forwarder no longer reaches an agent half's `/admin/app` or anything under it (on the panel `/api/<route>/app*` is the user surface). The hook preview's `inactiveRoutes` is now `userSurfaceRoutes`. Every write of `users.yml` the panel makes — creating, updating, deleting users, accepting invitations — now runs under one lock, one after the other. Deleting a user keeps a tombstone in the directory and clears the username's grants and group memberships in Gatekeeper. A registry credential must carry the `read` scope as well as `admin` (a `PUT /api/registry-credential` with an admin-only identity is refused).
55
+
38
56
  ### Updating Lamaste (Panel Server and Client)
39
57
 
40
58
  The Lamaste installer is idempotent — you can re-run it on an existing installation to update the panel server and client without losing your configuration.
@@ -63,7 +81,7 @@ The `@latest` tag ensures you get the newest published version. The `--yes` flag
63
81
  - It installs the pinned Chisel and Authelia releases if they are not already installed (a newer Authelia is kept), writes their systemd units, creates the `lamaste-chisel` group and the `lamaste-authelia` account, and sets the ownership described in [Configuration Files](../06-reference/config-files.md#file-permissions-table): `/var/www/lamaste` becomes `lamaste:www-data`, `/etc/authelia` `lamaste:lamaste-authelia`, the Chisel key `lamaste:lamaste-chisel 0640`, and the PKI directory `lamaste`'s. A running Authelia is stopped while its files change hands and started again afterwards
64
82
  - It generates the OpenID Connect issuer key `/etc/authelia/oidc-issuer.pem` (0600, `lamaste-authelia`) if it is missing, and the Authelia unit it writes enables the `template` configuration filter. A 4.0 server updating to 4.1 therefore has the key before the new panel starts; plugin OIDC clients and the `--oidc` registry credential need it
65
83
  - It upgrades Node.js from NodeSource when the installed version is older than 22.13 — the plugin hook runner's sandbox uses Node's stable permission model — and writes the hook runner's units (`lamalibre-lamaste-hooks@.socket`, `lamalibre-lamaste-hooks@.service`; see [Lifecycle hooks](../04-api-reference/lifecycle-hooks.md))
66
- - It rewrites the panel's systemd unit and the sudoers rules (checked with `visudo -c` before they replace the old file), installs the root-owned programs in `/usr/local/sbin/` (`lamaste-priv`, `lamaste-certbot`, `lamaste-cert-info`) and removes the retired `lamaste-sign-csr` and `lamaste-pki-rename`, and installs the port-80 redirect site
84
+ - It rewrites the panel's systemd unit and the sudoers rules (checked with `visudo -c` before they replace the old file), installs the root-owned programs in `/usr/local/sbin/` (`lamaste-priv`, `lamaste-certbot`, `lamaste-cert-info`) and removes the retired `lamaste-sign-csr` and `lamaste-pki-rename`, and installs the port-80 redirect site, and refreshes the IP panel vhost when its text differs (from 4.5; `nginx -t`, put back on failure)
67
85
  - It restarts Chisel if its binary or unit changed, starts the gatekeeper if it was running, and restarts `lamalibre-lamaste-serverd`, whose startup reconciliation rewrites Chisel's authfile. The first start of a 4.3 panel also creates the relay signing key (`/etc/lamalibre/lamaste/relay-signing-key.json`, 0600) and rewrites existing tunnel, static site and auth portal vhosts; check its log for `Left tunnel vhosts as they are`, `Left site vhosts as they are` and `Failed to rewrite … vhost` (see the [4.3.0 upgrade notes](https://github.com/lamalibre/lamaste/blob/main/CHANGELOG.md))
68
86
 
69
87
  The panel's **Update** action (`POST /api/system/update`) runs the same redeploy: it asks `sudo lamaste-priv self-update <version>` to start `create-lamaste@<version> --yes` in a transient systemd unit (see [System API](../04-api-reference/system.md)).
@@ -84,7 +102,7 @@ exit
84
102
 
85
103
  ### Updating Chisel
86
104
 
87
- Chisel is the tunnel server binary at `/usr/local/bin/chisel`. Lamaste pins it: server and agents run Chisel 1.12.0 (`CHISEL_RELEASE` in `@lamalibre/lamaste@4.4.1`), downloaded from the fixed release URL and verified against a pinned SHA-256 before it is unpacked. **Do not replace the binary by hand.** On the server, `create-lamaste` installs it (as root) and replaces a binary that reports any other version; the panel cannot install binaries, and only logs an error at startup when the installed Chisel is not the pinned release (it then restarts Chisel on every authfile change). Each agent's sync replaces its own copy.
105
+ Chisel is the tunnel server binary at `/usr/local/bin/chisel`. Lamaste pins it: server and agents run Chisel 1.12.0 (`CHISEL_RELEASE` in `@lamalibre/lamaste@4.6.0`), downloaded from the fixed release URL and verified against a pinned SHA-256 before it is unpacked. **Do not replace the binary by hand.** On the server, `create-lamaste` installs it (as root) and replaces a binary that reports any other version; the panel cannot install binaries, and only logs an error at startup when the installed Chisel is not the pinned release (it then restarts Chisel on every authfile change). Each agent's sync replaces its own copy.
88
106
 
89
107
  A new Chisel version therefore arrives with a Lamaste release that changes the pin: re-run the installer, which installs it and restarts Chisel. To check what is running:
90
108
 
@@ -98,7 +116,7 @@ Tunnel clients reconnect on their own after the brief interruption (they retry a
98
116
 
99
117
  ### Updating Authelia
100
118
 
101
- Authelia is the authentication server binary at `/usr/local/bin/authelia`. Lamaste pins it too: Authelia 4.39.28 (`AUTHELIA_RELEASE` in `@lamalibre/lamaste@4.4.1`), downloaded by `create-lamaste` from its fixed release URL and verified against a pinned SHA-256 per architecture. A new Authelia version arrives with a Lamaste release that changes the pin — re-run the installer. It stops Authelia while it replaces the binary and starts it again.
119
+ Authelia is the authentication server binary at `/usr/local/bin/authelia`. Lamaste pins it too: Authelia 4.39.28 (`AUTHELIA_RELEASE` in `@lamalibre/lamaste@4.6.0`), downloaded by `create-lamaste` from its fixed release URL and verified against a pinned SHA-256 per architecture. A new Authelia version arrives with a Lamaste release that changes the pin — re-run the installer. It stops Authelia while it replaces the binary and starts it again.
102
120
 
103
121
  An installed Authelia **newer** than the pin is kept, never downgraded: its database may already use a schema the pinned release cannot read, and Authelia refuses to start on a database newer than itself. If you install a newer release by hand, stop the service, replace the binary as root with a `root:root 0755` file, and start it again; check the [Authelia changelog](https://github.com/authelia/authelia/blob/master/CHANGELOG.md) first, since the configuration format may change between versions.
104
122
 
@@ -237,7 +255,7 @@ The panel server, CLI, client, docs and gatekeeper are always redeployed (files
237
255
 
238
256
  ### Version Pinning
239
257
 
240
- Chisel and Authelia are pinned by version and SHA-256 in `packages/core/lib/src/constants.ts` (`CHISEL_RELEASE`, `AUTHELIA_RELEASE`); changing a pin means updating the version and every digest there. The downloads are verified by `downloadVerifiedChisel` / `downloadVerifiedAuthelia` (exported from `@lamalibre/lamaste@4.4.1`) before anything is unpacked; the server installer uses them in `packages/provisioners/server/src/lib/binaries.js`. The configuration the panel writes needs Authelia 4.38 or later.
258
+ Chisel and Authelia are pinned by version and SHA-256 in `packages/core/lib/src/constants.ts` (`CHISEL_RELEASE`, `AUTHELIA_RELEASE`); changing a pin means updating the version and every digest there. The downloads are verified by `downloadVerifiedChisel` / `downloadVerifiedAuthelia` (exported from `@lamalibre/lamaste@4.6.0`) before anything is unpacked; the server installer uses them in `packages/provisioners/server/src/lib/binaries.js`. The configuration the panel writes needs Authelia 4.38 or later.
241
259
 
242
260
  ### Automated Updates
243
261
 
@@ -259,7 +277,7 @@ sudo dpkg-reconfigure -plow unattended-upgrades
259
277
  | Panel server | `/opt/lamalibre/lamaste/lamaste-serverd/` | Re-run `npx @lamalibre/create-lamaste@latest` |
260
278
  | Panel client | `/opt/lamalibre/lamaste/lamaste-server-ui/` | Re-run `npx @lamalibre/create-lamaste@latest` |
261
279
  | Chisel | `/usr/local/bin/chisel` | Pinned; installed by `create-lamaste` |
262
- | Agents | `sudo npm install -g @lamalibre/lamaste-agent@4.4.1` | Upgrade after the server, then `lamaste-agent update` |
280
+ | Agents | `sudo npm install -g @lamalibre/lamaste-agent@4.6.0` | Upgrade after the server, then `lamaste-agent update` |
263
281
  | Authelia | `/usr/local/bin/authelia` | Pinned; installed by `create-lamaste` (newer is kept) |
264
282
  | nginx | System package | `sudo apt-get update && sudo apt-get upgrade` |
265
283
  | certbot | System package | `sudo apt-get update && sudo apt-get upgrade` |
@@ -4,72 +4,71 @@
4
4
 
5
5
  ## File Overview
6
6
 
7
- | File | Format | Owner | Mode | Purpose |
8
- | ------------------------------------------------------------------ | ---------- | ------------------------ | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
9
- | `/etc/lamalibre/lamaste/panel.json` | JSON | lamaste:lamaste | 0600 | Panel server configuration |
10
- | `/etc/lamalibre/lamaste/tunnels.json` | JSON | lamaste:lamaste | 0600 | Tunnel definitions |
11
- | `/etc/lamalibre/lamaste/sites.json` | JSON | lamaste:lamaste | 0600 | Static site definitions |
12
- | `/etc/lamalibre/lamaste/chisel-credentials.json` | JSON | lamaste:lamaste | 0600 | Per-agent Chisel credentials (source of truth for the authfile) |
13
- | `/etc/lamalibre/lamaste/chisel-users` | JSON | lamaste:lamaste-chisel | 0640 | Chisel `--authfile`: per-agent credentials and port grants (rendered) |
14
- | `/etc/lamalibre/lamaste/chisel-sentinel` | text | lamaste:lamaste | 0600 | Password of the `lamaste-no-grants` sentinel user |
15
- | `/etc/lamalibre/lamaste/chisel-server.key` | PEM | lamaste:lamaste-chisel | 0640 | Chisel SSH host key (`--keyfile`), generated by the panel at onboarding |
16
- | `/etc/authelia/configuration.yml` | YAML | lamaste:lamaste-authelia | 0640 | Authelia server configuration |
17
- | `/etc/authelia/users.yml` | YAML | lamaste:lamaste-authelia | 0660 | User database (Authelia rewrites it on a password change) |
18
- | `/etc/authelia/.secrets.json` | JSON | lamaste:lamaste-authelia | 0600 | Authelia secrets (panel only) |
19
- | `/etc/authelia/oidc-issuer.pem` | PEM | lamaste-authelia | 0600 | RSA-4096 key Authelia signs OIDC tokens with, written by `create-lamaste`; the panel cannot read it |
20
- | `/etc/lamalibre/lamaste/registry-credential.json` | JSON | lamaste:lamaste | 0600 | The panel's registry (Feria) credential: a pasted token, or the `lamaste-server` OIDC client |
21
- | `/etc/lamalibre/lamaste/oidc-clients.json` | JSON | lamaste:lamaste | 0600 | Plaintext secrets (and pbkdf2 salts) of confidential OIDC clients |
22
- | `/etc/lamalibre/lamaste/relay-signing-key.json` | JSON | lamaste:lamaste | 0600 | Ed25519 key relay assertions (panel, Gatekeeper) and agents' app jobs (panel) are signed with |
23
- | `/etc/lamalibre/lamaste/push-install-config.json` | JSON | lamaste:lamaste | 0600 | Push install: the switch, the policies, the default policy |
24
- | `/etc/lamalibre/lamaste/push-install-sessions.json` | JSON | lamaste:lamaste | 0600 | Push install log (last 500 pushes) |
25
- | `/etc/lamalibre/lamaste/ticket-scopes.json` | JSON | lamaste:lamaste | 0600 | Ticket scope registry |
26
- | `/etc/lamalibre/lamaste/tickets.json` | JSON | lamaste:lamaste | 0600 | Ticket and session store |
27
- | `/etc/lamalibre/lamaste/invitations.json` | JSON | lamaste:lamaste | 0600 | Pending user invitations |
28
- | `/etc/lamalibre/lamaste/plugins.json` | JSON | lamaste:lamaste | 0600 | Plugin registry (before 4.2; the registry is now in `state.db`) |
29
- | `/etc/lamalibre/lamaste/state.db` | SQLite | lamaste:lamaste | 0600 | Plugins (with their hooks), agents, tickets, enrollment tokens, the audit log, notifications, relay hook approvals, plugin operations, agent jobs, the cache of agent-hosted plugins' settings (never a secret), each agent's last contact |
30
- | `/etc/lamalibre/lamaste/plugin-hostings.json` | JSON | lamaste:lamaste | 0600 | Hostings of agent-hosted plugins: agent, port, phase, installation secrets, health |
31
- | `/opt/lamalibre/lamaste/hooks/<route>/` | directory | root:root | 0755 | A plugin's approved relay hook module (`<sha256>.mjs`, 0644) and `runner.env`, written by `lamaste-priv` |
32
- | `/etc/lamalibre/lamaste/storage-config.json` | JSON | lamaste:lamaste | 0600 | Storage server registry and plugin bindings (credentials AES-256-GCM encrypted) |
33
- | `/etc/lamalibre/lamaste/storage-master.key` | Binary | lamaste:lamaste | 0600 | 32-byte master key for storage credential encryption |
34
- | `/etc/lamalibre/lamaste/groups.json` | JSON | lamaste:lamaste | 0600 | Lamaste group definitions and membership |
35
- | `/etc/lamalibre/lamaste/access-grants.json` | JSON | lamaste:lamaste | 0600 | Generic access grants (principal → resource) |
36
- | `/etc/lamalibre/lamaste/gatekeeper.json` | JSON | lamaste:lamaste | 0600 | Gatekeeper settings (cache TTL, admin contact, logging) |
37
- | `/etc/lamalibre/lamaste/access-request-log.json` | JSON | lamaste:lamaste | 0600 | Optional denied access log |
38
- | `/etc/lamalibre/lamaste/pki/enrollment-tokens.json` | JSON | lamaste:lamaste | 0600 | One-time enrollment tokens for hardware-bound enrollment |
39
- | `/etc/lamalibre/lamaste/pki/revoked.json` | JSON | lamaste:lamaste | 0600 | Revoked certificate serial numbers |
40
- | `/etc/lamalibre/lamaste/pki/agents/registry.json` | JSON | lamaste:lamaste | 0600 | Agent certificate metadata |
41
- | `/etc/nginx/sites-available/lamalibre-lamaste-*` | nginx conf | root:root | 0644 | Vhost configurations (the panel's are installed by `lamaste-priv`) |
42
- | `/etc/nginx/snippets/lamalibre-lamaste-mtls.conf` | nginx conf | root:root | 0644 | mTLS snippet |
43
- | `/etc/nginx/snippets/lamalibre-lamaste-authz-cache.conf` | nginx conf | root:root | 0644 | Gatekeeper proxy_cache zone |
44
- | `/etc/systemd/system/lamalibre-lamaste-gatekeeper.service` | systemd | root:root | 0644 | Gatekeeper systemd unit |
45
- | `/etc/systemd/system/chisel.service` | systemd | root:root | 0644 | Chisel unit, written by `create-lamaste` |
46
- | `/etc/systemd/system/authelia.service` | systemd | root:root | 0644 | Authelia unit, written by `create-lamaste` |
47
- | `/etc/systemd/system/lamalibre-lamaste-hooks@.socket`, `@.service` | systemd | root:root | 0644 | Relay hook runner (one instance per plugin with relay hooks), written by `create-lamaste` |
48
- | `~/.lamalibre/lamaste/servers.json` | JSON | user | 0600 | Desktop app server registry |
49
- | `~/.lamalibre/lamaste/agents.json` | JSON | user | 0600 | Multi-agent registry |
50
- | `~/.lamalibre/lamaste/agentd.token` | JSON | user | 0600 | Bearer token of lamaste-agentd's owner (the desktop app, scripts run as the user) |
51
- | `~/.lamalibre/lamaste/agents/<label>/config.json` | JSON | user | 0600 | Per-agent configuration |
52
- | `~/.lamalibre/lamaste/agents/<label>/client.p12` | PKCS#12 | user | 0600 | Per-agent mTLS certificate |
53
- | `~/.lamalibre/lamaste/agents/<label>/ca.crt` | PEM | user | 0644 | Per-agent CA certificate |
54
- | `~/.lamalibre/lamaste/agents/<label>/chisel.json` | JSON | user | 0600 | Per-agent Chisel credential (source of truth for the service) |
55
- | `~/.lamalibre/lamaste/agents/<label>/chisel.env` | env file | user | 0600 | Linux only: `AUTH=` for the systemd unit's `EnvironmentFile=` |
56
- | `~/.lamalibre/lamaste/agents/<label>/` | directory | user | 0700 | Per-agent data directory |
57
- | `~/.lamalibre/lamaste/agents/<label>/sync-state.json` | JSON | user | 0600 | Outcome of the last `lamaste-agent sync` |
58
- | `~/.lamalibre/lamaste/agents/<label>/app-plugins/<route>.json` | JSON | user | 0600 | Port and installation secret of a plugin hosted on this agent |
59
- | `~/.lamalibre/lamaste/agents/<label>/app-plugin-tunnel-state.json` | JSON | user | 0600 | The tunnel state last delivered to each hosted plugin's agent half |
60
- | `~/.lamalibre/lamaste/agents/<label>/apphost-state.json` | JSON | user | 0600 | The agent halves the app host helper installed for this agent |
61
- | `~/.lamalibre/lamaste/agents/<label>/host-facts.json` | JSON | user | 0600 | What the agent last reported about its host, and the helper's last answer |
62
- | `~/.lamalibre/lamaste/agents/<label>/app-job-results.json` | JSON | user | 0600 | App job results the relay has not taken yet |
63
- | `~/.lamalibre/lamaste/agents/<label>/logs/` | directory | user | 0700 | Per-agent Chisel and sync log files |
64
- | `~/.lamalibre/lamaste/agent.json` | JSON | user | 0600 | Legacy single-server config |
65
- | `/usr/local/sbin/lamaste-apphost` | Node.js | root:root | 0755 | Agent machine: the app host helper — see [Agent machine: the app host](#agent-machine-the-app-host) |
66
- | `/etc/sudoers.d/lamaste-apphost` | sudoers | root:root | 0440 | Agent machine: lets the agent's user run the helper |
67
- | `/etc/lamalibre/apphost/relays/<label>.json` | JSON | root:root | 0644 | Agent machine: the relay key pinned for agent `<label>` |
68
- | `/opt/lamalibre/apps/<route>/` | directory | root:root | 0755 | Agent machine: an agent half's installed versions |
69
- | `/var/lib/lamalibre/apps/<route>/` | directory | lamaste-app-\<route\> | 0700 | Agent machine: an agent half's data |
70
- | `/etc/lamalibre/apps/<route>/plugin-config.json` | JSON | lamaste-app-\<route\> | 0600 | Agent machine: an agent half's port and installation secret |
71
- | `/etc/systemd/system/lamalibre-app-<route>.service` | systemd | root:root | 0644 | Agent machine: an agent half's unit |
72
- | `/etc/systemd/system/lamalibre-app-<route>.socket` | systemd | root:root | 0644 | Agent machine: the socket unit holding an agent half's port |
7
+ | File | Format | Owner | Mode | Purpose |
8
+ | ------------------------------------------------------------------ | ---------- | ------------------------ | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | `/etc/lamalibre/lamaste/panel.json` | JSON | lamaste:lamaste | 0600 | Panel server configuration |
10
+ | `/etc/lamalibre/lamaste/tunnels.json` | JSON | lamaste:lamaste | 0600 | Tunnel definitions |
11
+ | `/etc/lamalibre/lamaste/sites.json` | JSON | lamaste:lamaste | 0600 | Static site definitions |
12
+ | `/etc/lamalibre/lamaste/chisel-credentials.json` | JSON | lamaste:lamaste | 0600 | Per-agent Chisel credentials (source of truth for the authfile) |
13
+ | `/etc/lamalibre/lamaste/chisel-users` | JSON | lamaste:lamaste-chisel | 0640 | Chisel `--authfile`: per-agent credentials and port grants (rendered) |
14
+ | `/etc/lamalibre/lamaste/chisel-sentinel` | text | lamaste:lamaste | 0600 | Password of the `lamaste-no-grants` sentinel user |
15
+ | `/etc/lamalibre/lamaste/chisel-server.key` | PEM | lamaste:lamaste-chisel | 0640 | Chisel SSH host key (`--keyfile`), generated by the panel at onboarding |
16
+ | `/etc/authelia/configuration.yml` | YAML | lamaste:lamaste-authelia | 0640 | Authelia server configuration |
17
+ | `/etc/authelia/users.yml` | YAML | lamaste:lamaste-authelia | 0660 | User database (Authelia rewrites it on a password change) |
18
+ | `/etc/authelia/.secrets.json` | JSON | lamaste:lamaste-authelia | 0600 | Authelia secrets (panel only) |
19
+ | `/etc/authelia/oidc-issuer.pem` | PEM | lamaste-authelia | 0600 | RSA-4096 key Authelia signs OIDC tokens with, written by `create-lamaste`; the panel cannot read it |
20
+ | `/etc/lamalibre/lamaste/registry-credential.json` | JSON | lamaste:lamaste | 0600 | The panel's registry (Feria) credential: a pasted token, or the `lamaste-server` OIDC client |
21
+ | `/etc/lamalibre/lamaste/oidc-clients.json` | JSON | lamaste:lamaste | 0600 | Plaintext secrets (and pbkdf2 salts) of confidential OIDC clients |
22
+ | `/etc/lamalibre/lamaste/relay-signing-key.json` | JSON | lamaste:lamaste | 0600 | Ed25519 key relay assertions (panel, Gatekeeper) and agents' app jobs (panel) are signed with |
23
+ | `/etc/lamalibre/lamaste/push-install-config.json` | JSON | lamaste:lamaste | 0600 | Push install: the switch, the policies, the default policy |
24
+ | `/etc/lamalibre/lamaste/push-install-sessions.json` | JSON | lamaste:lamaste | 0600 | Push install log (last 500 pushes) |
25
+ | `/etc/lamalibre/lamaste/ticket-scopes.json` | JSON | lamaste:lamaste | 0600 | Ticket scope registry |
26
+ | `/etc/lamalibre/lamaste/tickets.json` | JSON | lamaste:lamaste | 0600 | Ticket and session store |
27
+ | `/etc/lamalibre/lamaste/invitations.json` | JSON | lamaste:lamaste | 0600 | Pending user invitations |
28
+ | `/etc/lamalibre/lamaste/plugins.json` | JSON | lamaste:lamaste | 0600 | Plugin registry (before 4.2; the registry is now in `state.db`) |
29
+ | `/etc/lamalibre/lamaste/state.db` | SQLite | lamaste:lamaste | 0600 | Plugins (with their hooks), agents, tickets, enrollment tokens, the audit log, notifications, relay hook approvals, plugin operations, agent jobs, the cache of agent-hosted plugins' settings (never a secret), each agent's last contact, the user directory (each user's `userId`, tombstones, the `directoryId`), plugin audiences and the identity feed's state |
30
+ | `/etc/lamalibre/lamaste/plugin-hostings.json` | JSON | lamaste:lamaste | 0600 | Hostings of agent-hosted plugins: agent, port, phase, installation secrets, health |
31
+ | `/opt/lamalibre/lamaste/hooks/<route>/` | directory | root:root | 0755 | A plugin's approved relay hook module (`<sha256>.mjs`, 0644) and `runner.env`, written by `lamaste-priv` |
32
+ | `/etc/lamalibre/lamaste/storage-config.json` | JSON | lamaste:lamaste | 0600 | Storage server registry and plugin bindings (credentials AES-256-GCM encrypted) |
33
+ | `/etc/lamalibre/lamaste/storage-master.key` | Binary | lamaste:lamaste | 0600 | 32-byte master key for storage credential encryption |
34
+ | `/etc/lamalibre/lamaste/gatekeeper.db` | SQLite | lamaste:lamaste | 0600 | Gatekeeper: Lamaste groups and members, access grants (plugin entitlements included), the denied-access log |
35
+ | `/etc/lamalibre/lamaste/gatekeeper.json` | JSON | lamaste:lamaste | 0600 | Gatekeeper settings (cache TTL, admin contact, logging) |
36
+ | `/etc/lamalibre/lamaste/pki/enrollment-tokens.json` | JSON | lamaste:lamaste | 0600 | One-time enrollment tokens for hardware-bound enrollment |
37
+ | `/etc/lamalibre/lamaste/pki/revoked.json` | JSON | lamaste:lamaste | 0600 | Revoked certificate serial numbers |
38
+ | `/etc/lamalibre/lamaste/pki/agents/registry.json` | JSON | lamaste:lamaste | 0600 | Agent certificate metadata |
39
+ | `/etc/nginx/sites-available/lamalibre-lamaste-*` | nginx conf | root:root | 0644 | Vhost configurations (the panel's are installed by `lamaste-priv`) |
40
+ | `/etc/nginx/snippets/lamalibre-lamaste-mtls.conf` | nginx conf | root:root | 0644 | mTLS snippet |
41
+ | `/etc/nginx/snippets/lamalibre-lamaste-authz-cache.conf` | nginx conf | root:root | 0644 | Gatekeeper proxy_cache zone |
42
+ | `/etc/nginx/conf.d/lamalibre-lamaste-backend-cookie.conf` | nginx conf | root:root | 0644 | http-level map defining `$lamaste_backend_cookie` — the browser's cookies without `authelia_session`, which every tunnel and agent-panel vhost sends its backend; written by `create-lamaste` (install and redeploy) |
43
+ | `/etc/systemd/system/lamalibre-lamaste-gatekeeper.service` | systemd | root:root | 0644 | Gatekeeper systemd unit |
44
+ | `/etc/systemd/system/chisel.service` | systemd | root:root | 0644 | Chisel unit, written by `create-lamaste` |
45
+ | `/etc/systemd/system/authelia.service` | systemd | root:root | 0644 | Authelia unit, written by `create-lamaste` |
46
+ | `/etc/systemd/system/lamalibre-lamaste-hooks@.socket`, `@.service` | systemd | root:root | 0644 | Relay hook runner (one instance per plugin with relay hooks), written by `create-lamaste` |
47
+ | `~/.lamalibre/lamaste/servers.json` | JSON | user | 0600 | Desktop app server registry |
48
+ | `~/.lamalibre/lamaste/agents.json` | JSON | user | 0600 | Multi-agent registry |
49
+ | `~/.lamalibre/lamaste/agentd.token` | JSON | user | 0600 | Bearer token of lamaste-agentd's owner (the desktop app, scripts run as the user) |
50
+ | `~/.lamalibre/lamaste/agents/<label>/config.json` | JSON | user | 0600 | Per-agent configuration |
51
+ | `~/.lamalibre/lamaste/agents/<label>/client.p12` | PKCS#12 | user | 0600 | Per-agent mTLS certificate |
52
+ | `~/.lamalibre/lamaste/agents/<label>/ca.crt` | PEM | user | 0644 | Per-agent CA certificate |
53
+ | `~/.lamalibre/lamaste/agents/<label>/chisel.json` | JSON | user | 0600 | Per-agent Chisel credential (source of truth for the service) |
54
+ | `~/.lamalibre/lamaste/agents/<label>/chisel.env` | env file | user | 0600 | Linux only: `AUTH=` for the systemd unit's `EnvironmentFile=` |
55
+ | `~/.lamalibre/lamaste/agents/<label>/` | directory | user | 0700 | Per-agent data directory |
56
+ | `~/.lamalibre/lamaste/agents/<label>/sync-state.json` | JSON | user | 0600 | Outcome of the last `lamaste-agent sync` |
57
+ | `~/.lamalibre/lamaste/agents/<label>/app-plugins/<route>.json` | JSON | user | 0600 | Port and installation secret of a plugin hosted on this agent |
58
+ | `~/.lamalibre/lamaste/agents/<label>/app-plugin-tunnel-state.json` | JSON | user | 0600 | The tunnel state last delivered to each hosted plugin's agent half |
59
+ | `~/.lamalibre/lamaste/agents/<label>/apphost-state.json` | JSON | user | 0600 | The agent halves the app host helper installed for this agent |
60
+ | `~/.lamalibre/lamaste/agents/<label>/host-facts.json` | JSON | user | 0600 | What the agent last reported about its host, and the helper's last answer |
61
+ | `~/.lamalibre/lamaste/agents/<label>/app-job-results.json` | JSON | user | 0600 | App job results the relay has not taken yet |
62
+ | `~/.lamalibre/lamaste/agents/<label>/logs/` | directory | user | 0700 | Per-agent Chisel and sync log files |
63
+ | `~/.lamalibre/lamaste/agent.json` | JSON | user | 0600 | Legacy single-server config |
64
+ | `/usr/local/sbin/lamaste-apphost` | Node.js | root:root | 0755 | Agent machine: the app host helper — see [Agent machine: the app host](#agent-machine-the-app-host) |
65
+ | `/etc/sudoers.d/lamaste-apphost` | sudoers | root:root | 0440 | Agent machine: lets the agent's user run the helper |
66
+ | `/etc/lamalibre/apphost/relays/<label>.json` | JSON | root:root | 0644 | Agent machine: the relay key pinned for agent `<label>` |
67
+ | `/opt/lamalibre/apps/<route>/` | directory | root:root | 0755 | Agent machine: an agent half's installed versions |
68
+ | `/var/lib/lamalibre/apps/<route>/` | directory | lamaste-app-\<route\> | 0700 | Agent machine: an agent half's data |
69
+ | `/etc/lamalibre/apps/<route>/plugin-config.json` | JSON | lamaste-app-\<route\> | 0600 | Agent machine: an agent half's port and installation secret |
70
+ | `/etc/systemd/system/lamalibre-app-<route>.service` | systemd | root:root | 0644 | Agent machine: an agent half's unit |
71
+ | `/etc/systemd/system/lamalibre-app-<route>.socket` | systemd | root:root | 0644 | Agent machine: the socket unit holding an agent half's port |
73
72
 
74
73
  ---
75
74
 
@@ -246,20 +245,24 @@ Stores the array of static sites hosted through Lamaste.
246
245
 
247
246
  **Schema:** Array of site objects.
248
247
 
249
- | Field | Type | Description |
250
- | ------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------- |
251
- | `id` | string | UUID |
252
- | `name` | string | Site name (the subdomain for managed sites) |
253
- | `fqdn` | string | Full domain (e.g., `blog.example.com`) |
254
- | `type` | string | `"managed"` (subdomain of the Lamaste domain) or `"custom"` (your own domain) |
255
- | `spaMode` | boolean | If true, `try_files` falls back to `/index.html` |
256
- | `autheliaProtected` | boolean | If true, requires Authelia authentication |
257
- | `allowedUsers` | string[] | Authelia users allowed when protected (empty: all authenticated users) |
258
- | `dnsVerified` | boolean | DNS verified (always `true` for managed sites) |
259
- | `certIssued` | boolean | TLS certificate issued and vhost live |
260
- | `aliases` | string[] \| undefined | Custom sites only: hostnames answered with a 301 to `https://<fqdn>`. One certificate lineage named after `fqdn` covers all |
261
- | `rootPath` | string | Document root (e.g., `/var/www/lamaste/<id>/`) |
262
- | `createdAt` | string | ISO 8601 timestamp |
248
+ | Field | Type | Description |
249
+ | ------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
250
+ | `id` | string | UUID |
251
+ | `name` | string | Site name (the subdomain for managed sites) |
252
+ | `fqdn` | string | Full domain (e.g., `blog.example.com`) |
253
+ | `type` | string | `"managed"` (subdomain of the Lamaste domain) or `"custom"` (your own domain) |
254
+ | `spaMode` | boolean | If true, `try_files` falls back to `/index.html` |
255
+ | `autheliaProtected` | boolean | If true, requires Authelia authentication |
256
+ | `allowedUsers` | string[] | Authelia users allowed when protected (empty: all authenticated users) |
257
+ | `dnsVerified` | boolean | DNS verified (always `true` for managed sites) |
258
+ | `certIssued` | boolean | TLS certificate issued and vhost live |
259
+ | `aliases` | string[] \| undefined | Custom sites only: hostnames answered with a 301 to `https://<fqdn>`. One certificate lineage named after `fqdn` covers all |
260
+ | `rootPath` | string | Document root (e.g., `/var/www/lamaste/<id>/`) |
261
+ | `createdAt` | string | ISO 8601 timestamp |
262
+ | `owner` | object \| undefined | `{ plugin: <route> }` — a plugin's [web surface](../04-api-reference/agent-hosted-plugins.md#web-surface); its `rootPath` is `/var/www/lamaste/apps/<route>/current` and only the plugin's workflows change it |
263
+ | `accessMode` | string \| undefined | A plugin-owned site's: `"authenticated"` or `"restricted"` (a `site` grant in Gatekeeper) |
264
+
265
+ Gatekeeper reads this file too (the hosts of plugins' user surfaces). Every change runs under the panel's sites lock.
263
266
 
264
267
  **Example:**
265
268
 
@@ -457,92 +460,17 @@ Stores active tickets and sessions for agent-to-agent authorization. Created aut
457
460
 
458
461
  ---
459
462
 
460
- ## `/etc/lamalibre/lamaste/groups.json`
463
+ ## `/etc/lamalibre/lamaste/gatekeeper.db`
461
464
 
462
- Stores Lamaste group definitions and membership. Separate from Authelia groups — Lamaste groups are used exclusively for Gatekeeper access control without modifying `users.yml`.
465
+ Gatekeeper's SQLite store (WAL; 0600 with its `-wal` and `-shm` files; numbered migrations in `packages/sdks/gatekeeper/src/lib/migrations/gatekeeper/`): Lamaste groups, access grants and the access-request log. Gatekeeper reads it on every authorization check and writes it through its own API — the panel reaches that API through `/api/gatekeeper/*` and its own Gatekeeper client, never by opening the file. The JSON files of earlier versions (`groups.json`, `access-grants.json`, `access-request-log.json`) are no longer read; the installer still creates empty `groups.json` and `access-grants.json`.
463
466
 
464
- **Schema:**
465
-
466
- | Field | Type | Description |
467
- | ---------------------- | -------- | ------------------------------------------------------- |
468
- | `groups` | array | Array of group objects |
469
- | `groups[].name` | string | Group name (unique, lowercase alphanumeric, 2-63 chars) |
470
- | `groups[].description` | string | Human-readable description |
471
- | `groups[].members` | string[] | Array of Authelia usernames |
472
- | `groups[].createdAt` | string | ISO 8601 timestamp |
473
- | `groups[].createdBy` | string | Admin who created the group |
474
-
475
- **Example:**
476
-
477
- ```json
478
- {
479
- "groups": [
480
- {
481
- "name": "developers",
482
- "description": "Backend and frontend developers",
483
- "members": ["alice", "bob"],
484
- "createdAt": "2026-04-01T10:00:00.000Z",
485
- "createdBy": "admin"
486
- }
487
- ]
488
- }
489
- ```
490
-
491
- **Write pattern:** Atomic — temp file, `fsync()`, `rename()`. Concurrency controlled by promise-chain mutex.
492
-
493
- ---
494
-
495
- ## `/etc/lamalibre/lamaste/access-grants.json`
496
-
497
- Stores generic access grants mapping principals (users or groups) to resources (tunnel subdomains or other protected endpoints).
498
-
499
- **Schema:**
500
-
501
- | Field | Type | Description |
502
- | ------------------------ | -------------- | ----------------------------------------------- |
503
- | `grants` | array | Array of grant objects |
504
- | `grants[].grantId` | string | Unique identifier (e.g., `g_abc123`) |
505
- | `grants[].principalType` | string | `"user"` or `"group"` |
506
- | `grants[].principalId` | string | Authelia username or Lamaste group name |
507
- | `grants[].resourceType` | string | `"tunnel"`, `"plugin"`, or custom resource type |
508
- | `grants[].resourceId` | string | Resource identifier (e.g., tunnel subdomain) |
509
- | `grants[].context` | object | Optional metadata (empty `{}` by default) |
510
- | `grants[].used` | boolean | Whether the grant has been consumed |
511
- | `grants[].createdAt` | string | ISO 8601 timestamp |
512
- | `grants[].usedAt` | string \| null | ISO 8601 timestamp of consumption, or `null` |
513
-
514
- **Example:**
515
-
516
- ```json
517
- {
518
- "grants": [
519
- {
520
- "grantId": "g_b2c3d4e5",
521
- "principalType": "user",
522
- "principalId": "alice",
523
- "resourceType": "tunnel",
524
- "resourceId": "myapp",
525
- "context": {},
526
- "used": false,
527
- "createdAt": "2026-04-01T10:05:00.000Z",
528
- "usedAt": null
529
- },
530
- {
531
- "grantId": "g_c3d4e5f6",
532
- "principalType": "group",
533
- "principalId": "developers",
534
- "resourceType": "tunnel",
535
- "resourceId": "staging",
536
- "context": {},
537
- "used": false,
538
- "createdAt": "2026-04-01T10:10:00.000Z",
539
- "usedAt": null
540
- }
541
- ]
542
- }
543
- ```
467
+ | Table | Columns |
468
+ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
469
+ | `groups` | `name` (PK; 2–63 chars, lowercase alphanumeric and `-`), `description`, `members` (JSON array of usernames), `created_at`, `created_by` — at most 200 groups |
470
+ | `access_grants` | `grant_id` (UUID), `principal_type` (`user` \| `group`), `principal_id`, `resource_type` (`tunnel`, `plugin`, …), `resource_id`, `context` (JSON object — `{ "roles": [...] }` on an agent-hosted plugin's entitlement), `used`, `created_at`, `used_at` — at most 1000 grants, consumed ones kept 90 days |
471
+ | `access_request_log` | `timestamp`, `username`, `resource_type`, `resource_id`, `resource_fqdn` — denied attempts, when `accessLoggingEnabled` is on |
544
472
 
545
- **Write pattern:** Atomic — temp file, `fsync()`, `rename()`. Concurrency controlled by promise-chain mutex.
473
+ Removing a user principal (`POST /api/principals/user/remove { username }`, the panel's call when a user is removed or created under a username a removed user held) deletes their grants and their membership of every group in one transaction; erasing a removed user deletes their access-request log rows from before their removal.
546
474
 
547
475
  ---
548
476
 
@@ -579,38 +507,6 @@ Gatekeeper service settings. Controls cache behavior, admin contact information
579
507
 
580
508
  ---
581
509
 
582
- ## `/etc/lamalibre/lamaste/access-request-log.json`
583
-
584
- Optional log of denied access attempts. Written by the Gatekeeper when `accessLoggingEnabled` is true. Read by the Panel Server for the admin UI access request review page.
585
-
586
- **Schema:** Array of access request entries.
587
-
588
- | Field | Type | Description |
589
- | -------------- | ------ | -------------------------------------------- |
590
- | `timestamp` | string | ISO 8601 timestamp of the denied request |
591
- | `username` | string | Authelia username of the denied user |
592
- | `resourceType` | string | Resource type (e.g., `"tunnel"`, `"plugin"`) |
593
- | `resourceId` | string | Resource identifier (e.g., tunnel subdomain) |
594
- | `resourceFqdn` | string | Full domain the user attempted to access |
595
-
596
- **Example:**
597
-
598
- ```json
599
- [
600
- {
601
- "timestamp": "2026-04-01T14:30:00.000Z",
602
- "username": "charlie",
603
- "resourceType": "tunnel",
604
- "resourceId": "internal",
605
- "resourceFqdn": "internal.example.com"
606
- }
607
- ]
608
- ```
609
-
610
- **Write pattern:** Atomic — temp file, `fsync()`, `rename()`.
611
-
612
- ---
613
-
614
510
  ## `/etc/authelia/configuration.yml`
615
511
 
616
512
  Authelia server configuration. Written during onboarding provisioning.
@@ -926,7 +822,7 @@ Service files use per-agent names:
926
822
  - macOS: `com.lamalibre.lamaste.chisel-<label>` (plist label), `~/Library/LaunchAgents/com.lamalibre.lamaste.chisel-<label>.plist` — mode 0600, because it carries `AUTH` in `EnvironmentVariables`
927
823
  - Linux: `lamalibre-lamaste-chisel-<label>` (unit name), `~/.config/systemd/user/lamalibre-lamaste-chisel-<label>.service` — a systemd **user** unit with `EnvironmentFile=` pointing at `chisel.env`; enable lingering (`sudo loginctl enable-linger <user>`) for it to start at boot without a login
928
824
 
929
- Both run `chisel client --max-retry-interval 30s https://tunnel.<domain>:443 R:127.0.0.1:<port>:127.0.0.1:<port> ...` with TLS verification and no credential in argv. They are generated by `@lamalibre/lamaste@4.4.1/agent` (`chisel-service.ts`) and rewritten by `lamaste-agent setup`, `update` and `sync` — do not edit them by hand. An agent carrying no tunnels has its service unloaded (Chisel cannot run without a remote).
825
+ Both run `chisel client --max-retry-interval 30s https://tunnel.<domain>:443 R:127.0.0.1:<port>:127.0.0.1:<port> ...` with TLS verification and no credential in argv. They are generated by `@lamalibre/lamaste@4.6.0/agent` (`chisel-service.ts`) and rewritten by `lamaste-agent setup`, `update` and `sync` — do not edit them by hand. An agent carrying no tunnels has its service unloaded (Chisel cannot run without a remote).
930
826
 
931
827
  The sync timer, which runs `<node> <installed lamaste-agent> sync --label <label> --quiet` (`<node>` is a stable path such as `/opt/homebrew/bin/node` when one on `PATH` resolves to the running binary, so a Node.js upgrade does not break it):
932
828
 
@@ -1127,6 +1023,12 @@ This cache zone is available for nginx-level caching of Gatekeeper authorization
1127
1023
 
1128
1024
  ---
1129
1025
 
1026
+ ## `/etc/nginx/conf.d/lamalibre-lamaste-backend-cookie.conf`
1027
+
1028
+ The http-level map every location proxying to a tunnel or agent backend sets `Cookie` from (`proxy_set_header Cookie $lamaste_backend_cookie;`): the browser's cookies with every `authelia_session` pair removed, at most four, and no `Cookie` at all when one is still there. Rendered by core `renderBackendCookieMap()` from the session cookie name Authelia is configured with, written root-owned 0644 by `create-lamaste` on install and as the first step of every redeploy (`nginx -t`, previous file restored on failure), removed by `lamaste-server uninstall`. Not edited by hand: a redeploy rewrites it. See [nginx Configuration](../03-architecture/nginx-configuration.md#the-backend-cookie-map).
1029
+
1030
+ ---
1031
+
1130
1032
  ## `/etc/systemd/system/lamalibre-lamaste-gatekeeper.service`
1131
1033
 
1132
1034
  Systemd unit for the Gatekeeper tunnel authorization service. Runs as the `lamaste` user on `127.0.0.1:9294`.
@@ -1179,10 +1081,8 @@ WantedBy=multi-user.target
1179
1081
  | `/etc/lamalibre/lamaste/plugins.json` | lamaste:lamaste | 0600 | Plugin registry |
1180
1082
  | `/etc/lamalibre/lamaste/storage-config.json` | lamaste:lamaste | 0600 | Storage registry |
1181
1083
  | `/etc/lamalibre/lamaste/storage-master.key` | lamaste:lamaste | 0600 | Storage encryption key |
1182
- | `/etc/lamalibre/lamaste/groups.json` | lamaste:lamaste | 0600 | Lamaste groups |
1183
- | `/etc/lamalibre/lamaste/access-grants.json` | lamaste:lamaste | 0600 | Access grants |
1084
+ | `/etc/lamalibre/lamaste/gatekeeper.db` | lamaste:lamaste | 0600 | Gatekeeper groups, grants, access log |
1184
1085
  | `/etc/lamalibre/lamaste/gatekeeper.json` | lamaste:lamaste | 0600 | Gatekeeper settings |
1185
- | `/etc/lamalibre/lamaste/access-request-log.json` | lamaste:lamaste | 0600 | Denied access log |
1186
1086
  | `/etc/lamalibre/lamaste/pki/enrollment-tokens.json` | lamaste:lamaste | 0600 | Enrollment tokens |
1187
1087
  | `/etc/lamalibre/lamaste/pki/revoked.json` | lamaste:lamaste | 0600 | Revocation list |
1188
1088
  | `/etc/lamalibre/lamaste/pki/agents/registry.json` | lamaste:lamaste | 0600 | Agent cert metadata |
@@ -1232,10 +1132,8 @@ WantedBy=multi-user.target
1232
1132
  | `ticket-scopes.json` | lamalibre-lamaste-serverd | lamalibre-lamaste-serverd (atomic write + mutex) | No |
1233
1133
  | `tickets.json` | lamalibre-lamaste-serverd | lamalibre-lamaste-serverd (atomic write + mutex) | No |
1234
1134
  | `storage-config.json` | lamalibre-lamaste-serverd | lamalibre-lamaste-serverd (atomic write + mutex) | No |
1235
- | `groups.json` | gatekeeper | lamalibre-lamaste-serverd (atomic write + mutex) | No (gatekeeper watches file) |
1236
- | `access-grants.json` | gatekeeper | lamalibre-lamaste-serverd (atomic write + mutex) | No (gatekeeper watches file) |
1135
+ | `gatekeeper.db` | gatekeeper | gatekeeper (its API; the panel through it) | No (read on every check) |
1237
1136
  | `gatekeeper.json` | gatekeeper | lamalibre-lamaste-serverd (atomic write) | Yes (`systemctl restart lamalibre-lamaste-gatekeeper`) |
1238
- | `access-request-log.json` | lamalibre-lamaste-serverd | gatekeeper (atomic write) | No |
1239
1137
  | `configuration.yml` | authelia | onboarding provisioning | Yes (`systemctl restart authelia`) |
1240
1138
  | `users.yml` | authelia | lamalibre-lamaste-serverd (atomic rename, no sudo) | Yes (`systemctl restart authelia`) |
1241
1139
  | `lamalibre-lamaste-*` vhosts | nginx | lamalibre-lamaste-serverd (via `sudo lamaste-priv nginx-site`) | Yes (`nginx -t && systemctl reload nginx`) |