@lamalibre/create-lamaste 4.4.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/package.json +2 -2
  2. package/scripts/lamaste-priv +200 -16
  3. package/src/index.js +1 -0
  4. package/src/lib/backend-cookie.js +65 -0
  5. package/src/lib/ip-panel-vhost.js +208 -0
  6. package/src/lib/service-config.js +5 -3
  7. package/src/tasks/nginx.js +18 -135
  8. package/src/tasks/redeploy.js +39 -1
  9. package/vendor/docs/00-introduction/how-it-works.md +2 -2
  10. package/vendor/docs/00-introduction/quickstart.md +5 -5
  11. package/vendor/docs/00-introduction/what-is-lamaste.md +5 -5
  12. package/vendor/docs/01-concepts/authentication.md +1 -1
  13. package/vendor/docs/01-concepts/authorization.md +66 -48
  14. package/vendor/docs/01-concepts/certificates.md +3 -3
  15. package/vendor/docs/01-concepts/mtls.md +2 -2
  16. package/vendor/docs/01-concepts/security-model.md +70 -33
  17. package/vendor/docs/01-concepts/tickets.md +2 -2
  18. package/vendor/docs/01-concepts/tunneling.md +4 -4
  19. package/vendor/docs/02-guides/agent-setup.md +5 -5
  20. package/vendor/docs/02-guides/certificate-management.md +2 -2
  21. package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
  22. package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
  23. package/vendor/docs/02-guides/installation.md +3 -3
  24. package/vendor/docs/02-guides/managing-users.md +113 -25
  25. package/vendor/docs/02-guides/onboarding.md +2 -2
  26. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
  27. package/vendor/docs/03-architecture/installer-flow.md +2 -2
  28. package/vendor/docs/03-architecture/installer.md +4 -4
  29. package/vendor/docs/03-architecture/management-flow.md +3 -1
  30. package/vendor/docs/03-architecture/nginx-configuration.md +165 -18
  31. package/vendor/docs/03-architecture/overview.md +13 -17
  32. package/vendor/docs/03-architecture/panel-client.md +6 -6
  33. package/vendor/docs/03-architecture/panel-server.md +3 -2
  34. package/vendor/docs/03-architecture/state-management.md +4 -8
  35. package/vendor/docs/03-architecture/system-overview.md +1 -1
  36. package/vendor/docs/04-api-reference/agent-hosted-plugins.md +292 -23
  37. package/vendor/docs/04-api-reference/app-host.md +3 -3
  38. package/vendor/docs/04-api-reference/gatekeeper.md +60 -5
  39. package/vendor/docs/04-api-reference/lifecycle-hooks.md +15 -13
  40. package/vendor/docs/04-api-reference/onboarding.md +1 -1
  41. package/vendor/docs/04-api-reference/registry-and-oidc.md +6 -4
  42. package/vendor/docs/04-api-reference/tunnels.md +67 -29
  43. package/vendor/docs/04-api-reference/users.md +241 -45
  44. package/vendor/docs/05-operations/backup-and-restore.md +35 -26
  45. package/vendor/docs/05-operations/monitoring.md +39 -0
  46. package/vendor/docs/05-operations/uninstalling.md +2 -1
  47. package/vendor/docs/05-operations/upgrades.md +15 -6
  48. package/vendor/docs/06-reference/config-files.md +83 -189
  49. package/vendor/docs/06-reference/glossary.md +3 -3
  50. package/vendor/docs/06-reference/installer-flags.md +13 -13
  51. package/vendor/docs/06-reference/ports-and-services.md +25 -26
  52. package/vendor/docs/06-reference/troubleshooting.md +8 -8
  53. package/vendor/docs/gatekeeper-design.md +10 -8
  54. package/vendor/docs/identity-directory-design.md +48 -14
  55. package/vendor/docs/package.json +1 -1
  56. package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
  57. package/vendor/gatekeeper/dist/index.d.ts +2 -1
  58. package/vendor/gatekeeper/dist/index.d.ts.map +1 -1
  59. package/vendor/gatekeeper/dist/index.js +2 -0
  60. package/vendor/gatekeeper/dist/index.js.map +1 -1
  61. package/vendor/gatekeeper/dist/lib/grants.d.ts +6 -0
  62. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -1
  63. package/vendor/gatekeeper/dist/lib/grants.js +6 -1
  64. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -1
  65. package/vendor/gatekeeper/dist/lib/groups.d.ts +5 -0
  66. package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -1
  67. package/vendor/gatekeeper/dist/lib/groups.js +5 -1
  68. package/vendor/gatekeeper/dist/lib/groups.js.map +1 -1
  69. package/vendor/gatekeeper/dist/lib/principals.d.ts +29 -0
  70. package/vendor/gatekeeper/dist/lib/principals.d.ts.map +1 -0
  71. package/vendor/gatekeeper/dist/lib/principals.js +67 -0
  72. package/vendor/gatekeeper/dist/lib/principals.js.map +1 -0
  73. package/vendor/gatekeeper/dist/lib/tunnels.d.ts +13 -0
  74. package/vendor/gatekeeper/dist/lib/tunnels.d.ts.map +1 -0
  75. package/vendor/gatekeeper/dist/lib/tunnels.js +68 -0
  76. package/vendor/gatekeeper/dist/lib/tunnels.js.map +1 -0
  77. package/vendor/gatekeeper/dist/lib/types.d.ts +19 -0
  78. package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -1
  79. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
  80. package/vendor/gatekeeper/dist/server/index.js +22 -48
  81. package/vendor/gatekeeper/dist/server/index.js.map +1 -1
  82. package/vendor/gatekeeper/dist/server/routes/authz.d.ts +15 -1
  83. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
  84. package/vendor/gatekeeper/dist/server/routes/authz.js +250 -103
  85. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
  86. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -1
  87. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +61 -4
  88. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -1
  89. package/vendor/gatekeeper/dist/server/routes/principals.d.ts +3 -0
  90. package/vendor/gatekeeper/dist/server/routes/principals.d.ts.map +1 -0
  91. package/vendor/gatekeeper/dist/server/routes/principals.js +27 -0
  92. package/vendor/gatekeeper/dist/server/routes/principals.js.map +1 -0
  93. package/vendor/gatekeeper/package.json +2 -2
  94. package/vendor/server/bin/lamaste-server.js +15 -1
  95. package/vendor/server/package.json +2 -2
  96. package/vendor/server/src/commands/plugin-identity.js +335 -0
  97. package/vendor/server/src/commands/plugins.js +99 -11
  98. package/vendor/server/src/commands/registry-credential.js +2 -1
  99. package/vendor/server/src/commands/tunnels.js +102 -2
  100. package/vendor/server/src/commands/uninstall.js +3 -1
  101. package/vendor/server/src/commands/users.js +358 -0
  102. package/vendor/server/src/plugin-approval.js +107 -5
  103. package/vendor/server/src/plugin-identity.js +382 -0
  104. package/vendor/server-ui/dist/assets/index-D-fer5ef.css +1 -0
  105. package/vendor/server-ui/dist/assets/index-DSaDPJaw.js +84 -0
  106. package/vendor/server-ui/dist/index.html +2 -2
  107. package/vendor/serverd/package.json +2 -2
  108. package/vendor/serverd/src/index.js +25 -1
  109. package/vendor/serverd/src/lib/audience.js +576 -0
  110. package/vendor/serverd/src/lib/authelia.js +78 -7
  111. package/vendor/serverd/src/lib/config.js +68 -43
  112. package/vendor/serverd/src/lib/directory.js +1113 -0
  113. package/vendor/serverd/src/lib/entitlements.js +517 -0
  114. package/vendor/serverd/src/lib/gatekeeper-client.js +215 -10
  115. package/vendor/serverd/src/lib/hook-pipelines.js +13 -0
  116. package/vendor/serverd/src/lib/identity-sync.js +905 -0
  117. package/vendor/serverd/src/lib/migrations/state/0013_identity_directory.sql +158 -0
  118. package/vendor/serverd/src/lib/migrations/state/0014_identity_ledger.sql +20 -0
  119. package/vendor/serverd/src/lib/mtls.js +6 -2
  120. package/vendor/serverd/src/lib/nginx.js +279 -48
  121. package/vendor/serverd/src/lib/plugin-hooks.js +98 -45
  122. package/vendor/serverd/src/lib/plugin-hosting.js +33 -5
  123. package/vendor/serverd/src/lib/plugin-lifecycle.js +100 -9
  124. package/vendor/serverd/src/lib/plugin-packages.js +30 -22
  125. package/vendor/serverd/src/lib/plugins.js +94 -15
  126. package/vendor/serverd/src/lib/registry-credential.js +46 -6
  127. package/vendor/serverd/src/lib/request-logging.js +19 -0
  128. package/vendor/serverd/src/lib/retained-data.js +50 -4
  129. package/vendor/serverd/src/lib/state.js +18 -0
  130. package/vendor/serverd/src/lib/tunnel-hooks.js +4 -1
  131. package/vendor/serverd/src/lib/user-access-session.js +21 -11
  132. package/vendor/serverd/src/lib/user-caller.js +67 -0
  133. package/vendor/serverd/src/lib/user-surface.js +733 -0
  134. package/vendor/serverd/src/lib/vhost-reconcile.js +136 -34
  135. package/vendor/serverd/src/middleware/user-access-session.js +9 -0
  136. package/vendor/serverd/src/routes/agent-forwarder.js +4 -2
  137. package/vendor/serverd/src/routes/invite.js +53 -12
  138. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +107 -16
  139. package/vendor/serverd/src/routes/management/identity-directory.js +79 -0
  140. package/vendor/serverd/src/routes/management/invitations.js +78 -68
  141. package/vendor/serverd/src/routes/management/plugin-identity.js +221 -0
  142. package/vendor/serverd/src/routes/management/registry-credential.js +1 -1
  143. package/vendor/serverd/src/routes/management/tunnels.js +98 -2
  144. package/vendor/serverd/src/routes/management/users.js +290 -208
  145. package/vendor/serverd/src/routes/management.js +4 -0
  146. package/vendor/serverd/src/routes/onboarding/provision.js +14 -1
  147. package/vendor/serverd/src/routes/user-access.js +17 -4
  148. package/vendor/serverd/src/routes/user-surface.js +69 -0
  149. package/vendor/server-ui/dist/assets/index-25wo_8av.css +0 -1
  150. package/vendor/server-ui/dist/assets/index-CESyyK8V.js +0 -84
@@ -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.0
30
+ sudo npm install -g @lamalibre/lamaste-agent@4.5.0
31
31
  lamaste-agent update
32
32
  ```
33
33
 
@@ -35,6 +35,15 @@ 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.5
39
+
40
+ 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.
41
+
42
+ - **`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)).
43
+ - **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`.
44
+ - **No agent upgrade is needed**, and no agent half must be rebuilt. An agent half built on `@lamalibre/lamaste@4.5.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.
45
+ - **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).
46
+
38
47
  ### Updating Lamaste (Panel Server and Client)
39
48
 
40
49
  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 +72,7 @@ The `@latest` tag ensures you get the newest published version. The `--yes` flag
63
72
  - 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
73
  - 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
74
  - 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
75
+ - 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
76
  - 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
77
 
69
78
  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 +93,7 @@ exit
84
93
 
85
94
  ### Updating Chisel
86
95
 
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.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.
96
+ 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.5.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
97
 
89
98
  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
99
 
@@ -98,7 +107,7 @@ Tunnel clients reconnect on their own after the brief interruption (they retry a
98
107
 
99
108
  ### Updating Authelia
100
109
 
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.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.
110
+ 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.5.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
111
 
103
112
  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
113
 
@@ -237,7 +246,7 @@ The panel server, CLI, client, docs and gatekeeper are always redeployed (files
237
246
 
238
247
  ### Version Pinning
239
248
 
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.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.
249
+ 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.5.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
250
 
242
251
  ### Automated Updates
243
252
 
@@ -259,7 +268,7 @@ sudo dpkg-reconfigure -plow unattended-upgrades
259
268
  | Panel server | `/opt/lamalibre/lamaste/lamaste-serverd/` | Re-run `npx @lamalibre/create-lamaste@latest` |
260
269
  | Panel client | `/opt/lamalibre/lamaste/lamaste-server-ui/` | Re-run `npx @lamalibre/create-lamaste@latest` |
261
270
  | Chisel | `/usr/local/bin/chisel` | Pinned; installed by `create-lamaste` |
262
- | Agents | `sudo npm install -g @lamalibre/lamaste-agent@4.4.0` | Upgrade after the server, then `lamaste-agent update` |
271
+ | Agents | `sudo npm install -g @lamalibre/lamaste-agent@4.5.0` | Upgrade after the server, then `lamaste-agent update` |
263
272
  | Authelia | `/usr/local/bin/authelia` | Pinned; installed by `create-lamaste` (newer is kept) |
264
273
  | nginx | System package | `sudo apt-get update && sudo apt-get upgrade` |
265
274
  | 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
 
@@ -457,92 +456,17 @@ Stores active tickets and sessions for agent-to-agent authorization. Created aut
457
456
 
458
457
  ---
459
458
 
460
- ## `/etc/lamalibre/lamaste/groups.json`
459
+ ## `/etc/lamalibre/lamaste/gatekeeper.db`
461
460
 
462
- Stores Lamaste group definitions and membership. Separate from Authelia groups — Lamaste groups are used exclusively for Gatekeeper access control without modifying `users.yml`.
461
+ 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
462
 
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
- ```
463
+ | Table | Columns |
464
+ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
465
+ | `groups` | `name` (PK; 2–63 chars, lowercase alphanumeric and `-`), `description`, `members` (JSON array of usernames), `created_at`, `created_by` — at most 200 groups |
466
+ | `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 |
467
+ | `access_request_log` | `timestamp`, `username`, `resource_type`, `resource_id`, `resource_fqdn` — denied attempts, when `accessLoggingEnabled` is on |
544
468
 
545
- **Write pattern:** Atomic — temp file, `fsync()`, `rename()`. Concurrency controlled by promise-chain mutex.
469
+ 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
470
 
547
471
  ---
548
472
 
@@ -579,38 +503,6 @@ Gatekeeper service settings. Controls cache behavior, admin contact information
579
503
 
580
504
  ---
581
505
 
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
506
  ## `/etc/authelia/configuration.yml`
615
507
 
616
508
  Authelia server configuration. Written during onboarding provisioning.
@@ -733,7 +625,7 @@ The RSA-4096 private key (PKCS#8) Authelia signs ID and JWT access tokens with.
733
625
 
734
626
  ## `/etc/lamalibre/lamaste/registry-credential.json`
735
627
 
736
- The panel's service credential on the Lamalibre npm registry (Feria), used to broker one-hour install tokens for agents (`GET /api/agents/me/registry-credential`) and to revoke a user's tokens when a `feria-*` group is lost.
628
+ The panel's service credential on the Lamalibre npm registry (Feria), used for the panel's own npm calls (plugin installs, update staging, agent-half pinning — through a throw-away userconfig, never a `.npmrc` here), to broker one-hour install tokens for agents (`GET /api/agents/me/registry-credential`) and to revoke a user's tokens when a `feria-*` group is lost.
737
629
 
738
630
  ```json
739
631
  {
@@ -926,7 +818,7 @@ Service files use per-agent names:
926
818
  - 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
819
  - 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
820
 
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.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).
821
+ 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.5.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
822
 
931
823
  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
824
 
@@ -1127,6 +1019,12 @@ This cache zone is available for nginx-level caching of Gatekeeper authorization
1127
1019
 
1128
1020
  ---
1129
1021
 
1022
+ ## `/etc/nginx/conf.d/lamalibre-lamaste-backend-cookie.conf`
1023
+
1024
+ 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).
1025
+
1026
+ ---
1027
+
1130
1028
  ## `/etc/systemd/system/lamalibre-lamaste-gatekeeper.service`
1131
1029
 
1132
1030
  Systemd unit for the Gatekeeper tunnel authorization service. Runs as the `lamaste` user on `127.0.0.1:9294`.
@@ -1179,10 +1077,8 @@ WantedBy=multi-user.target
1179
1077
  | `/etc/lamalibre/lamaste/plugins.json` | lamaste:lamaste | 0600 | Plugin registry |
1180
1078
  | `/etc/lamalibre/lamaste/storage-config.json` | lamaste:lamaste | 0600 | Storage registry |
1181
1079
  | `/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 |
1080
+ | `/etc/lamalibre/lamaste/gatekeeper.db` | lamaste:lamaste | 0600 | Gatekeeper groups, grants, access log |
1184
1081
  | `/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
1082
  | `/etc/lamalibre/lamaste/pki/enrollment-tokens.json` | lamaste:lamaste | 0600 | Enrollment tokens |
1187
1083
  | `/etc/lamalibre/lamaste/pki/revoked.json` | lamaste:lamaste | 0600 | Revocation list |
1188
1084
  | `/etc/lamalibre/lamaste/pki/agents/registry.json` | lamaste:lamaste | 0600 | Agent cert metadata |
@@ -1232,10 +1128,8 @@ WantedBy=multi-user.target
1232
1128
  | `ticket-scopes.json` | lamalibre-lamaste-serverd | lamalibre-lamaste-serverd (atomic write + mutex) | No |
1233
1129
  | `tickets.json` | lamalibre-lamaste-serverd | lamalibre-lamaste-serverd (atomic write + mutex) | No |
1234
1130
  | `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) |
1131
+ | `gatekeeper.db` | gatekeeper | gatekeeper (its API; the panel through it) | No (read on every check) |
1237
1132
  | `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
1133
  | `configuration.yml` | authelia | onboarding provisioning | Yes (`systemctl restart authelia`) |
1240
1134
  | `users.yml` | authelia | lamalibre-lamaste-serverd (atomic rename, no sudo) | Yes (`systemctl restart authelia`) |
1241
1135
  | `lamalibre-lamaste-*` vhosts | nginx | lamalibre-lamaste-serverd (via `sudo lamaste-priv nginx-site`) | Yes (`nginx -t && systemctl reload nginx`) |
@@ -24,7 +24,7 @@ If you are reading documentation and hit an unfamiliar term, this is the place t
24
24
 
25
25
  **Where it appears:**
26
26
 
27
- - Enrolled from the panel (**Certificates → Enrollment Token**) and `lamaste-agent setup` (installed globally with `npm install -g @lamalibre/lamaste-agent@4.4.0`)
27
+ - Enrolled from the panel (**Certificates → Enrollment Token**) and `lamaste-agent setup` (installed globally with `npm install -g @lamalibre/lamaste-agent@4.5.0`)
28
28
  - Agent registry: `/etc/lamalibre/lamaste/agents.json` on the server; `~/.lamalibre/lamaste/agents/<label>/` on the agent
29
29
  - The **Agent** column and field on the panel's Tunnels page
30
30
 
@@ -242,7 +242,7 @@ See also: [mTLS](#mtls-mutual-tls), [CA](#ca-certificate-authority), [PKCS12](#p
242
242
 
243
243
  **Where it appears:**
244
244
 
245
- - Generated by `lamaste-agent setup` / `update` (implementation in `@lamalibre/lamaste@4.4.0/agent`)
245
+ - Generated by `lamaste-agent setup` / `update` (implementation in `@lamalibre/lamaste@4.5.0/agent`)
246
246
  - Installed to `~/Library/LaunchAgents/com.lamalibre.lamaste.chisel-<label>.plist` on the agent
247
247
  - Manages the Chisel client process lifecycle
248
248
 
@@ -373,7 +373,7 @@ See also: [Client Certificate](#client-certificate), [CA](#ca-certificate-author
373
373
 
374
374
  **Plain English:** A small scheduled job on every agent that checks with the panel every 30 seconds and adjusts the tunnel client when the agent's tunnels changed — so tunnels created, disabled or moved in the panel reach the agent without anyone running a command on it.
375
375
 
376
- **Technical:** Runs `lamaste-agent sync --label <label>`, which fetches `GET /api/tunnels/agent-config` and converges the agent's Chisel client with it (relay URL, credential, pinned binary, granted remotes, running or stopped). It exists because Chisel rejects a client's whole session when one requested remote is not granted: an agent must drop a revoked tunnel promptly or all its other tunnels go dark. Requires a global install of `@lamalibre/lamaste-agent@4.4.0`.
376
+ **Technical:** Runs `lamaste-agent sync --label <label>`, which fetches `GET /api/tunnels/agent-config` and converges the agent's Chisel client with it (relay URL, credential, pinned binary, granted remotes, running or stopped). It exists because Chisel rejects a client's whole session when one requested remote is not granted: an agent must drop a revoked tunnel promptly or all its other tunnels go dark. Requires a global install of `@lamalibre/lamaste-agent@4.5.0`.
377
377
 
378
378
  **Where it appears:**
379
379