@lamalibre/create-lamaste 4.5.0 → 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.
- package/package.json +2 -2
- package/scripts/lamaste-priv +34 -2
- package/vendor/docs/00-introduction/how-it-works.md +2 -2
- package/vendor/docs/00-introduction/quickstart.md +5 -5
- package/vendor/docs/00-introduction/what-is-lamaste.md +5 -5
- package/vendor/docs/01-concepts/certificates.md +3 -3
- package/vendor/docs/01-concepts/mtls.md +2 -2
- package/vendor/docs/01-concepts/security-model.md +2 -2
- package/vendor/docs/01-concepts/tickets.md +2 -2
- package/vendor/docs/01-concepts/tunneling.md +4 -4
- package/vendor/docs/02-guides/agent-setup.md +5 -5
- package/vendor/docs/02-guides/certificate-management.md +2 -2
- package/vendor/docs/02-guides/cloud-provisioning.md +3 -3
- package/vendor/docs/02-guides/desktop-app-setup.md +10 -10
- package/vendor/docs/02-guides/installation.md +3 -3
- package/vendor/docs/02-guides/onboarding.md +2 -2
- package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +2 -2
- package/vendor/docs/02-guides/static-sites.md +4 -0
- package/vendor/docs/03-architecture/installer-flow.md +2 -2
- package/vendor/docs/03-architecture/installer.md +4 -4
- package/vendor/docs/03-architecture/management-flow.md +1 -1
- package/vendor/docs/03-architecture/nginx-configuration.md +65 -7
- package/vendor/docs/03-architecture/overview.md +5 -5
- package/vendor/docs/03-architecture/panel-client.md +6 -6
- package/vendor/docs/03-architecture/panel-server.md +2 -2
- package/vendor/docs/03-architecture/state-management.md +2 -2
- package/vendor/docs/03-architecture/system-overview.md +1 -1
- package/vendor/docs/04-api-reference/agent-hosted-plugins.md +112 -37
- package/vendor/docs/04-api-reference/app-host.md +3 -3
- package/vendor/docs/04-api-reference/gatekeeper.md +19 -1
- package/vendor/docs/04-api-reference/lifecycle-hooks.md +4 -4
- package/vendor/docs/04-api-reference/onboarding.md +1 -1
- package/vendor/docs/04-api-reference/sites.md +4 -0
- package/vendor/docs/04-api-reference/tunnels.md +21 -19
- package/vendor/docs/05-operations/backup-and-restore.md +1 -1
- package/vendor/docs/05-operations/uninstalling.md +1 -1
- package/vendor/docs/05-operations/upgrades.md +15 -6
- package/vendor/docs/06-reference/config-files.md +19 -15
- package/vendor/docs/06-reference/glossary.md +3 -3
- package/vendor/docs/06-reference/installer-flags.md +13 -13
- package/vendor/docs/06-reference/ports-and-services.md +1 -1
- package/vendor/docs/06-reference/troubleshooting.md +8 -8
- package/vendor/docs/gatekeeper-design.md +8 -8
- package/vendor/docs/identity-directory-design.md +3 -3
- package/vendor/docs/package.json +1 -1
- package/vendor/docs/todo/lib-cli-desktop-refactor.md +27 -27
- package/vendor/gatekeeper/dist/cli/index.js +0 -0
- package/vendor/gatekeeper/dist/index.d.ts +3 -3
- package/vendor/gatekeeper/dist/index.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/index.js +2 -2
- package/vendor/gatekeeper/dist/index.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/authz.d.ts +9 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/authz.js +31 -0
- package/vendor/gatekeeper/dist/lib/authz.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/constants.d.ts +5 -2
- package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/constants.js +5 -2
- package/vendor/gatekeeper/dist/lib/constants.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/tunnels.d.ts +3 -6
- package/vendor/gatekeeper/dist/lib/tunnels.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/lib/tunnels.js +4 -16
- package/vendor/gatekeeper/dist/lib/tunnels.js.map +1 -1
- package/vendor/gatekeeper/dist/lib/types.d.ts +0 -19
- package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/index.d.ts +2 -1
- package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/index.js +29 -10
- package/vendor/gatekeeper/dist/server/index.js.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -1
- package/vendor/gatekeeper/dist/server/routes/authz.js +103 -22
- package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -1
- package/vendor/gatekeeper/package.json +2 -2
- package/vendor/server/package.json +2 -2
- package/vendor/server/src/commands/plugin-web-surface.js +269 -0
- package/vendor/server/src/commands/plugins.js +63 -6
- package/vendor/server/src/commands/sites.js +15 -1
- package/vendor/server/src/plugin-approval.js +80 -1
- package/vendor/server/src/plugin-web-surface.js +307 -0
- package/vendor/server-ui/dist/assets/index-BZwQ_aQc.css +1 -0
- package/vendor/server-ui/dist/assets/index-BvEfCZYS.js +84 -0
- package/vendor/server-ui/dist/index.html +2 -2
- package/vendor/serverd/package.json +2 -2
- package/vendor/serverd/src/index.js +9 -4
- package/vendor/serverd/src/lib/chisel-runtime.js +18 -6
- package/vendor/serverd/src/lib/chisel.js +10 -2
- package/vendor/serverd/src/lib/gatekeeper-client.js +18 -7
- package/vendor/serverd/src/lib/hook-pipelines.js +8 -3
- package/vendor/serverd/src/lib/migrations/state/0015_plugin_web_surface.sql +14 -0
- package/vendor/serverd/src/lib/nginx.js +269 -2
- package/vendor/serverd/src/lib/plugin-hooks.js +40 -11
- package/vendor/serverd/src/lib/plugin-lifecycle.js +128 -5
- package/vendor/serverd/src/lib/plugin-packages.js +74 -2
- package/vendor/serverd/src/lib/plugins.js +39 -6
- package/vendor/serverd/src/lib/state.js +18 -0
- package/vendor/serverd/src/lib/user-surface.js +48 -27
- package/vendor/serverd/src/lib/vhost-reconcile.js +5 -3
- package/vendor/serverd/src/lib/web-surface.js +766 -0
- package/vendor/serverd/src/routes/management/plugin-web-surface.js +151 -0
- package/vendor/serverd/src/routes/management/plugins.js +2 -0
- package/vendor/serverd/src/routes/management/sites.js +143 -65
- package/vendor/serverd/src/routes/management/tunnels.js +11 -20
- package/vendor/serverd/src/routes/management.js +2 -0
- package/vendor/server-ui/dist/assets/index-D-fer5ef.css +0 -1
- package/vendor/server-ui/dist/assets/index-DSaDPJaw.js +0 -84
|
@@ -153,24 +153,24 @@ curl -s --cert client.p12:password \
|
|
|
153
153
|
|
|
154
154
|
**Errors:**
|
|
155
155
|
|
|
156
|
-
| Status | Body
|
|
157
|
-
| ------ |
|
|
158
|
-
| 400 | `{"error":"Validation failed","details":{"issues":[...]}}`
|
|
159
|
-
| 400 | `{"error":"agentLabel is required: name the agent that will carry the tunnel"}`
|
|
160
|
-
| 400 | `{"error":"Failed to create tunnel","details":"Agent 'x' is not enrolled or has been revoked"}`
|
|
161
|
-
| 400 | `{"error":"Failed to create tunnel","details":"Subdomain 'panel' is reserved"}`
|
|
162
|
-
| 400 | `{"error":"Failed to create tunnel","details":"Subdomain 'app' is already in use"}`
|
|
163
|
-
| 400 | `{"error":"Failed to create tunnel","details":"Port 3000 is already in use by another tunnel"}`
|
|
164
|
-
| 400 | `{"error":"Failed to create tunnel","details":"Domain 'app.example.com' is already served by a static site"}` | A static site or site alias already answers on this hostname |
|
|
165
|
-
| 400 | `{"error":"Domain and email must be configured before creating tunnels"}`
|
|
166
|
-
| 403 | `{"error":"Agents can only create tunnels they carry themselves"}`
|
|
167
|
-
| 403 | `{"error":"Plugin-agent certificates cannot create tunnels — use the agent certificate of ..."}`
|
|
168
|
-
| 403 | `{"error":"Only administrators can set a body limit above 100 MiB"}`
|
|
169
|
-
| 403 | `{"error":"Only administrators can set tunnel access mode to public or authenticated"}`
|
|
170
|
-
| 500 | `{"error":"Failed to create tunnel","details":"Certificate issuance failed: ..."}`
|
|
171
|
-
| 500 | `{"error":"Failed to create tunnel","details":"Nginx configuration failed: ..."}`
|
|
172
|
-
| 500 | `{"error":"Failed to create tunnel","details":"State persistence failed: ..."}`
|
|
173
|
-
| 500 | `{"error":"Failed to create tunnel","details":"Chisel reconfiguration failed: ..."}`
|
|
156
|
+
| Status | Body | When |
|
|
157
|
+
| ------ | --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
158
|
+
| 400 | `{"error":"Validation failed","details":{"issues":[...]}}` | Invalid subdomain format, port out of range or reserved |
|
|
159
|
+
| 400 | `{"error":"agentLabel is required: name the agent that will carry the tunnel"}` | Admin certificate did not name the carrying agent |
|
|
160
|
+
| 400 | `{"error":"Failed to create tunnel","details":"Agent 'x' is not enrolled or has been revoked"}` | `agentLabel` does not name an active agent |
|
|
161
|
+
| 400 | `{"error":"Failed to create tunnel","details":"Subdomain 'panel' is reserved"}` | Subdomain is in the reserved list |
|
|
162
|
+
| 400 | `{"error":"Failed to create tunnel","details":"Subdomain 'app' is already in use"}` | Another tunnel uses this subdomain |
|
|
163
|
+
| 400 | `{"error":"Failed to create tunnel","details":"Port 3000 is already in use by another tunnel"}` | Another tunnel uses this port |
|
|
164
|
+
| 400 | `{"error":"Failed to create tunnel","details":"Domain 'app.example.com' is already served by a static site ('app')"}` | A static site or site alias already answers on this hostname (checked under the tunnel lock; enabling a tunnel is refused the same way) |
|
|
165
|
+
| 400 | `{"error":"Domain and email must be configured before creating tunnels"}` | Domain not set in config |
|
|
166
|
+
| 403 | `{"error":"Agents can only create tunnels they carry themselves"}` | Agent certificate named another agent |
|
|
167
|
+
| 403 | `{"error":"Plugin-agent certificates cannot create tunnels — use the agent certificate of ..."}` | Plugin-agent certificate |
|
|
168
|
+
| 403 | `{"error":"Only administrators can set a body limit above 100 MiB"}` | Agent certificate asked for `maxBodySizeMb` over 100 |
|
|
169
|
+
| 403 | `{"error":"Only administrators can set tunnel access mode to public or authenticated"}` | Agent certificate asked for a non-restricted mode |
|
|
170
|
+
| 500 | `{"error":"Failed to create tunnel","details":"Certificate issuance failed: ..."}` | certbot failed |
|
|
171
|
+
| 500 | `{"error":"Failed to create tunnel","details":"Nginx configuration failed: ..."}` | nginx vhost write or test failed |
|
|
172
|
+
| 500 | `{"error":"Failed to create tunnel","details":"State persistence failed: ..."}` | Failed to write tunnels.json |
|
|
173
|
+
| 500 | `{"error":"Failed to create tunnel","details":"Chisel reconfiguration failed: ..."}` | Chisel authfile sync failed |
|
|
174
174
|
|
|
175
175
|
### Creation Flow
|
|
176
176
|
|
|
@@ -318,7 +318,7 @@ curl -s --cert client.p12:password \
|
|
|
318
318
|
| `chiselArgs` | `string[]` | Chisel client arguments: `client`, the server URL, and one `R:127.0.0.1:<port>:127.0.0.1:<port>` remote per tunnel. No `--tls-skip-verify` (the agent verifies the relay's certificate) and no credential — the agent supplies its own through the service environment, never argv |
|
|
319
319
|
| `chiselCredentialIssuedAt` | `string \| null` | When the agent's current Chisel credential was issued — a timestamp, never the credential. An agent holding a credential with a different issue time (an administrator rotated it) fetches the current one from `GET /api/agents/me/chisel-credential` |
|
|
320
320
|
| `tunnels` | `array` | The agent's enabled tunnels with port and subdomain |
|
|
321
|
-
| `hostFactsHash` | `string \| null` | Agent certificates only: the SHA-256 of the [host facts](agent-hosted-plugins.md#host-facts) the relay stores for the agent, computed as the agent computes it over its own (`hostFactsHash` in `@lamalibre/lamaste@4.
|
|
321
|
+
| `hostFactsHash` | `string \| null` | Agent certificates only: the SHA-256 of the [host facts](agent-hosted-plugins.md#host-facts) the relay stores for the agent, computed as the agent computes it over its own (`hostFactsHash` in `@lamalibre/lamaste@4.6.0`); `null` when it stores none. The agent's sync reports its facts again when this is not the hash of its own, so a record replaced since its last report — the agent enrolled again on its label, the relay restored from a backup — has them again after one sync, not a day. An agent behind a relay without the field reports as before |
|
|
322
322
|
|
|
323
323
|
**Errors:**
|
|
324
324
|
|
|
@@ -329,6 +329,8 @@ curl -s --cert client.p12:password \
|
|
|
329
329
|
|
|
330
330
|
## User Surface Binding
|
|
331
331
|
|
|
332
|
+
A plugin that owns a site for its [web surface](agent-hosted-plugins.md#web-surface) serves its user surface there; binding it to a tunnel is refused (`400`). A tunnel bound to one plugin alone can hand its host over to that plugin's web surface in one reload ([Moving from a bound tunnel](agent-hosted-plugins.md#moving-from-a-bound-tunnel)); it stays in the state, disabled and unbound, and cannot be enabled again while the site holds its hostname.
|
|
333
|
+
|
|
332
334
|
An app tunnel can be **bound** as the user surface of an agent-hosted plugin: its host then serves the plugin's users at `/api/<route>/app` and everything under it — Gatekeeper authenticates the Authelia session and vouches for the user to the panel, and the panel forwards the request to the plugin's agent half with the directory's `userId`, username and the user's roles ([Agent-Hosted Plugins](agent-hosted-plugins.md#the-user-surface)). Every other path of the host goes down the tunnel as before. Admin only, 30 a minute.
|
|
333
335
|
|
|
334
336
|
**What can be bound.** An enabled app tunnel (`type` `app`, not internal), with access mode `authenticated` or `restricted` — a public host has no signed-in user to vouch for — **carried by the agent that hosts the plugin** (`400` otherwise: "Plugin '…' is hosted on agent '…', but this tunnel is carried by '…'", or "… is not hosted on an agent" before it is hosted). The host whose sessions reach the plugin's users is never another agent's: whatever answers on its other paths — another agent's application — would share the user surface's origin. On a `restricted` tunnel the user also needs a grant for the tunnel. The route must be held by an installed agent-hosted plugin; a plugin's user surface is on one host at most, and one host serves at most 16 plugins' user surfaces. A bound tunnel cannot be made public (`PATCH` answers `409` "… cannot be made public — unbind it first").
|
|
@@ -199,7 +199,7 @@ sudo chown lamaste-authelia:lamaste-authelia /etc/authelia/db.sqlite3* /etc/auth
|
|
|
199
199
|
sudo chmod 600 /etc/authelia/db.sqlite3* /etc/authelia/notifications.txt
|
|
200
200
|
```
|
|
201
201
|
|
|
202
|
-
A backup taken on a version before the privilege boundary holds root-owned Authelia files and older unit files. After restoring one, re-run `npx @lamalibre/create-lamaste@4.
|
|
202
|
+
A backup taken on a version before the privilege boundary holds root-owned Authelia files and older unit files. After restoring one, re-run `npx @lamalibre/create-lamaste@4.6.0 --yes`: the redeploy rewrites the `chisel` and `authelia` units and converts the ownership of `/etc/authelia`, the Chisel key and the PKI directory (see [Upgrades](upgrades.md)).
|
|
203
203
|
|
|
204
204
|
The panel re-applies the authfile's group and mode itself on every start, so a Chisel that fails to read it before the panel is up is started again by the panel's reconciliation.
|
|
205
205
|
|
|
@@ -29,7 +29,7 @@ It stops and disables the panel, gatekeeper, Chisel and Authelia; removes their
|
|
|
29
29
|
The manual guide is also available from the CLI:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
npx @lamalibre/create-lamaste@4.
|
|
32
|
+
npx @lamalibre/create-lamaste@4.6.0 --uninstall
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
This prints the same steps listed below.
|
|
@@ -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.
|
|
30
|
+
sudo npm install -g @lamalibre/lamaste-agent@4.6.0
|
|
31
31
|
lamaste-agent update
|
|
32
32
|
```
|
|
33
33
|
|
|
@@ -35,13 +35,22 @@ 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
|
+
|
|
38
47
|
### Upgrading to 4.5
|
|
39
48
|
|
|
40
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.
|
|
41
50
|
|
|
42
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)).
|
|
43
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`.
|
|
44
|
-
- **No agent upgrade is needed**, and no agent half must be rebuilt. An agent half built on `@lamalibre/lamaste@4.
|
|
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.
|
|
45
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).
|
|
46
55
|
|
|
47
56
|
### Updating Lamaste (Panel Server and Client)
|
|
@@ -93,7 +102,7 @@ exit
|
|
|
93
102
|
|
|
94
103
|
### Updating Chisel
|
|
95
104
|
|
|
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.
|
|
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.
|
|
97
106
|
|
|
98
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:
|
|
99
108
|
|
|
@@ -107,7 +116,7 @@ Tunnel clients reconnect on their own after the brief interruption (they retry a
|
|
|
107
116
|
|
|
108
117
|
### Updating Authelia
|
|
109
118
|
|
|
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.
|
|
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.
|
|
111
120
|
|
|
112
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.
|
|
113
122
|
|
|
@@ -246,7 +255,7 @@ The panel server, CLI, client, docs and gatekeeper are always redeployed (files
|
|
|
246
255
|
|
|
247
256
|
### Version Pinning
|
|
248
257
|
|
|
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.
|
|
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.
|
|
250
259
|
|
|
251
260
|
### Automated Updates
|
|
252
261
|
|
|
@@ -268,7 +277,7 @@ sudo dpkg-reconfigure -plow unattended-upgrades
|
|
|
268
277
|
| Panel server | `/opt/lamalibre/lamaste/lamaste-serverd/` | Re-run `npx @lamalibre/create-lamaste@latest` |
|
|
269
278
|
| Panel client | `/opt/lamalibre/lamaste/lamaste-server-ui/` | Re-run `npx @lamalibre/create-lamaste@latest` |
|
|
270
279
|
| Chisel | `/usr/local/bin/chisel` | Pinned; installed by `create-lamaste` |
|
|
271
|
-
| Agents | `sudo npm install -g @lamalibre/lamaste-agent@4.
|
|
280
|
+
| Agents | `sudo npm install -g @lamalibre/lamaste-agent@4.6.0` | Upgrade after the server, then `lamaste-agent update` |
|
|
272
281
|
| Authelia | `/usr/local/bin/authelia` | Pinned; installed by `create-lamaste` (newer is kept) |
|
|
273
282
|
| nginx | System package | `sudo apt-get update && sudo apt-get upgrade` |
|
|
274
283
|
| certbot | System package | `sudo apt-get update && sudo apt-get upgrade` |
|
|
@@ -245,20 +245,24 @@ Stores the array of static sites hosted through Lamaste.
|
|
|
245
245
|
|
|
246
246
|
**Schema:** Array of site objects.
|
|
247
247
|
|
|
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
|
|
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.
|
|
262
266
|
|
|
263
267
|
**Example:**
|
|
264
268
|
|
|
@@ -818,7 +822,7 @@ Service files use per-agent names:
|
|
|
818
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`
|
|
819
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
|
|
820
824
|
|
|
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.
|
|
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).
|
|
822
826
|
|
|
823
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):
|
|
824
828
|
|
|
@@ -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.
|
|
27
|
+
- Enrolled from the panel (**Certificates → Enrollment Token**) and `lamaste-agent setup` (installed globally with `npm install -g @lamalibre/lamaste-agent@4.6.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.
|
|
245
|
+
- Generated by `lamaste-agent setup` / `update` (implementation in `@lamalibre/lamaste@4.6.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.
|
|
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.6.0`.
|
|
377
377
|
|
|
378
378
|
**Where it appears:**
|
|
379
379
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Installer Flags
|
|
2
2
|
|
|
3
|
-
> CLI flags, environment variables, and exit codes for `npx @lamalibre/create-lamaste@4.
|
|
3
|
+
> CLI flags, environment variables, and exit codes for `npx @lamalibre/create-lamaste@4.6.0`.
|
|
4
4
|
|
|
5
5
|
## Usage
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx @lamalibre/create-lamaste@4.
|
|
8
|
+
npx @lamalibre/create-lamaste@4.6.0 [flags]
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
The installer runs as root on a fresh Ubuntu 24.04 server. It is completely non-interactive by default — all configuration happens later through the browser-based onboarding wizard.
|
|
@@ -26,7 +26,7 @@ The installer runs as root on a fresh Ubuntu 24.04 server. It is completely non-
|
|
|
26
26
|
Prints a description of what the installer does, lists all flags, and exits with code 0. Does not modify anything on the system.
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
npx @lamalibre/create-lamaste@4.
|
|
29
|
+
npx @lamalibre/create-lamaste@4.6.0 --help
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
### `--yes`, `-y`
|
|
@@ -34,7 +34,7 @@ npx @lamalibre/create-lamaste@4.5.0 --help
|
|
|
34
34
|
Skips the interactive confirmation prompt that appears before installation begins. Useful for automated deployments or scripts where you cannot press Enter.
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
|
-
npx @lamalibre/create-lamaste@4.
|
|
37
|
+
npx @lamalibre/create-lamaste@4.6.0 --yes
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Without this flag, the installer displays a banner listing all changes it will make and waits for the user to press Enter or Ctrl+C.
|
|
@@ -51,7 +51,7 @@ Skips all OS hardening tasks:
|
|
|
51
51
|
Everything else (Node.js, nginx, mTLS, panel deployment) still runs.
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
npx @lamalibre/create-lamaste@4.
|
|
54
|
+
npx @lamalibre/create-lamaste@4.6.0 --skip-harden
|
|
55
55
|
```
|
|
56
56
|
|
|
57
57
|
Use this if you manage your own firewall rules, already have fail2ban configured, or are running on a platform that handles security at a different layer.
|
|
@@ -61,7 +61,7 @@ Use this if you manage your own firewall rules, already have fail2ban configured
|
|
|
61
61
|
Allows the installer to run on a machine with a private or non-routable IP address (e.g., `192.168.x.x`, `10.x.x.x`). By default, the installer requires a public IP.
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
npx @lamalibre/create-lamaste@4.
|
|
64
|
+
npx @lamalibre/create-lamaste@4.6.0 --dev
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
This is useful for:
|
|
@@ -76,7 +76,7 @@ When `--dev` is active, the installer prints the detected IP with a note: `(dev
|
|
|
76
76
|
Forces the installer to run the complete installation pipeline, ignoring skip guards that would normally detect an existing installation. This is useful when an installation is in an inconsistent state and you want to ensure all components are fully deployed.
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
npx @lamalibre/create-lamaste@4.
|
|
79
|
+
npx @lamalibre/create-lamaste@4.6.0 --force-full
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
Use this if:
|
|
@@ -90,7 +90,7 @@ Use this if:
|
|
|
90
90
|
Prints a step-by-step guide for manually removing Lamaste from the server, then exits with code 0. Does not modify anything on the system.
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
|
-
npx @lamalibre/create-lamaste@4.
|
|
93
|
+
npx @lamalibre/create-lamaste@4.6.0 --uninstall
|
|
94
94
|
```
|
|
95
95
|
|
|
96
96
|
The printed guide first points to the automated removal, `sudo lamaste-server uninstall`, then covers:
|
|
@@ -207,25 +207,25 @@ Components that are always redeployed on re-run:
|
|
|
207
207
|
|
|
208
208
|
```bash
|
|
209
209
|
ssh root@203.0.113.42
|
|
210
|
-
npx @lamalibre/create-lamaste@4.
|
|
210
|
+
npx @lamalibre/create-lamaste@4.6.0
|
|
211
211
|
```
|
|
212
212
|
|
|
213
213
|
**Automated install (no confirmation prompt):**
|
|
214
214
|
|
|
215
215
|
```bash
|
|
216
|
-
npx @lamalibre/create-lamaste@4.
|
|
216
|
+
npx @lamalibre/create-lamaste@4.6.0 --yes
|
|
217
217
|
```
|
|
218
218
|
|
|
219
219
|
**Install without OS hardening:**
|
|
220
220
|
|
|
221
221
|
```bash
|
|
222
|
-
npx @lamalibre/create-lamaste@4.
|
|
222
|
+
npx @lamalibre/create-lamaste@4.6.0 --yes --skip-harden
|
|
223
223
|
```
|
|
224
224
|
|
|
225
225
|
**Test in a local VM:**
|
|
226
226
|
|
|
227
227
|
```bash
|
|
228
|
-
npx @lamalibre/create-lamaste@4.
|
|
228
|
+
npx @lamalibre/create-lamaste@4.6.0 --dev
|
|
229
229
|
```
|
|
230
230
|
|
|
231
231
|
**Update an existing installation:**
|
|
@@ -237,7 +237,7 @@ npx @lamalibre/create-lamaste@latest --yes
|
|
|
237
237
|
**View the uninstall guide:**
|
|
238
238
|
|
|
239
239
|
```bash
|
|
240
|
-
npx @lamalibre/create-lamaste@4.
|
|
240
|
+
npx @lamalibre/create-lamaste@4.6.0 --uninstall
|
|
241
241
|
```
|
|
242
242
|
|
|
243
243
|
## Quick Reference
|
|
@@ -34,7 +34,7 @@ A tunnel's port is also a loopback port on the relay: its vhost proxies to `127.
|
|
|
34
34
|
| 9292 | IP-based panel listener |
|
|
35
35
|
| 9294 | Gatekeeper |
|
|
36
36
|
|
|
37
|
-
A tunnel on one of them would publish that internal service on a public hostname. For the panel that is an administrator takeover, not a leak: the panel trusts the client-certificate headers nginx sets. `RESERVED_TUNNEL_PORTS` in `@lamalibre/lamaste@4.
|
|
37
|
+
A tunnel on one of them would publish that internal service on a public hostname. For the panel that is an administrator takeover, not a leak: the panel trusts the client-certificate headers nginx sets. `RESERVED_TUNNEL_PORTS` in `@lamalibre/lamaste@4.6.0` is enforced by the request schema, inside the tunnel workflow, and again when the Chisel grants are rendered. Tunnel ports must also be 1024–65535.
|
|
38
38
|
|
|
39
39
|
## Systemd Units
|
|
40
40
|
|
|
@@ -217,7 +217,7 @@ The agent's sync timer applies tunnel changes within about 30 seconds. If that d
|
|
|
217
217
|
lamaste-agent update # apply now and (re)install the sync timer
|
|
218
218
|
```
|
|
219
219
|
|
|
220
|
-
`update` needs the agent installed globally (`npm install -g @lamalibre/lamaste-agent@4.
|
|
220
|
+
`update` needs the agent installed globally (`npm install -g @lamalibre/lamaste-agent@4.6.0`); an agent originally set up with `npx` must be installed first.
|
|
221
221
|
|
|
222
222
|
**Cause 3: The agent does not carry the tunnel.**
|
|
223
223
|
|
|
@@ -320,7 +320,7 @@ ls -la /usr/local/bin/authelia
|
|
|
320
320
|
| Missing `panel.json` | `Config file not found` | Re-run installer or create the file manually |
|
|
321
321
|
| Invalid JSON in `panel.json` | `contains invalid JSON` | Fix the JSON syntax |
|
|
322
322
|
| Port 3100 in use | `EADDRINUSE` | Find and stop the conflicting process: `sudo ss -tlnp sport = :3100` |
|
|
323
|
-
| Missing Node.js modules | `Cannot find module` | Re-run the installer (`npx @lamalibre/create-lamaste@4.
|
|
323
|
+
| Missing Node.js modules | `Cannot find module` | Re-run the installer (`npx @lamalibre/create-lamaste@4.6.0 --yes`); `/opt/lamalibre/lamaste` is root-owned and redeployed as a whole |
|
|
324
324
|
| Permission denied writing state | `EACCES` under `/etc/lamalibre/lamaste` | Re-run the installer; the redeploy re-applies the ownership of the config and PKI directories |
|
|
325
325
|
|
|
326
326
|
### chisel fails to start
|
|
@@ -329,7 +329,7 @@ ls -la /usr/local/bin/authelia
|
|
|
329
329
|
|
|
330
330
|
| Cause | Log Message | Fix |
|
|
331
331
|
| -------------------------- | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
332
|
-
| Binary missing | `exec format error` or `not found` | Re-run the installer (`npx @lamalibre/create-lamaste@4.
|
|
332
|
+
| Binary missing | `exec format error` or `not found` | Re-run the installer (`npx @lamalibre/create-lamaste@4.6.0 --yes`) — it installs the pinned, checksum-verified release for the server's architecture; the panel cannot install binaries |
|
|
333
333
|
| Not the pinned release | (panel log) `The installed chisel is not the pinned release — run create-lamaste ...` | Re-run the installer. Until then the panel restarts Chisel on every authfile change |
|
|
334
334
|
| Authfile or key unreadable | `permission denied` on `chisel-users` or `chisel-server.key` | Both must be `0640 lamaste:lamaste-chisel` and the unit `Group=lamaste-chisel`; restart the panel, which re-applies the authfile's. If the group, the unit or the key's ownership is wrong, re-run the installer in redeploy mode |
|
|
335
335
|
| Stopped by the panel | (panel log) `Chisel stopped: ...`; unit disabled, `chisel-failed-closed` present | Reconciliation failed closed; see [Tunnel Client Cannot Connect](#tunnel-client-cannot-connect), Cause 1 |
|
|
@@ -343,7 +343,7 @@ ls -la /usr/local/bin/authelia
|
|
|
343
343
|
| --------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
344
344
|
| Invalid `configuration.yml` | `configuration: error` | Check YAML syntax with `authelia validate-configuration --config /etc/authelia/configuration.yml` |
|
|
345
345
|
| Missing `users.yml` | `cannot open file` | Create an initial users file (see [Config Files](config-files.md)) |
|
|
346
|
-
| Binary missing | `not found` | Re-run the installer (`npx @lamalibre/create-lamaste@4.
|
|
346
|
+
| Binary missing | `not found` | Re-run the installer (`npx @lamalibre/create-lamaste@4.6.0 --yes`); it installs the pinned release |
|
|
347
347
|
| Wrong permissions | `permission denied` | Authelia runs as `lamaste-authelia`: `/etc/authelia` must be `lamaste:lamaste-authelia 2770`, `configuration.yml` `0640`, `users.yml` `0660`, `db.sqlite3` owned by `lamaste-authelia`. Re-run the installer to re-apply (a root-owned `/etc/authelia` from an older version is converted), or see [Config Files](config-files.md#file-permissions-table) |
|
|
348
348
|
| Database newer than binary | storage schema version error at startup | A newer Authelia ran against this database and was replaced by an older one; the installer never downgrades an installed Authelia, so reinstall that newer release by hand |
|
|
349
349
|
|
|
@@ -516,14 +516,14 @@ sudo systemctl restart authelia
|
|
|
516
516
|
|
|
517
517
|
## Onboarding Fails: "Chisel is not installed" / "Authelia is not installed"
|
|
518
518
|
|
|
519
|
-
**Symptom:** The **Starting Chisel** or **Configuring Authelia** provisioning task fails with "Chisel is not installed. Run `npx @lamalibre/create-lamaste@4.
|
|
519
|
+
**Symptom:** The **Starting Chisel** or **Configuring Authelia** provisioning task fails with "Chisel is not installed. Run `npx @lamalibre/create-lamaste@4.6.0` on the server to repair the installation." (or the same for Authelia).
|
|
520
520
|
|
|
521
521
|
**Cause:** Onboarding downloads nothing: the installer installs both binaries (pinned releases), their systemd units and the `lamaste-authelia` account. The binary at `/usr/local/bin/chisel` or `/usr/local/bin/authelia` is missing — the installer was interrupted, or the file was removed.
|
|
522
522
|
|
|
523
523
|
**Fix:** Re-run the installer on the server, then start provisioning again from the wizard:
|
|
524
524
|
|
|
525
525
|
```bash
|
|
526
|
-
npx @lamalibre/create-lamaste@4.
|
|
526
|
+
npx @lamalibre/create-lamaste@4.6.0 --yes
|
|
527
527
|
```
|
|
528
528
|
|
|
529
529
|
If provisioning then fails writing Authelia's configuration with `/etc/authelia is not writable by the panel — run create-lamaste to repair the installation`, the directory's ownership is wrong; the same command repairs it.
|
|
@@ -538,7 +538,7 @@ If provisioning then fails writing Authelia's configuration with `/etc/authelia
|
|
|
538
538
|
|
|
539
539
|
**Fix:**
|
|
540
540
|
|
|
541
|
-
1. Re-run the installer so the helper matches the panel: `npx @lamalibre/create-lamaste@4.
|
|
541
|
+
1. Re-run the installer so the helper matches the panel: `npx @lamalibre/create-lamaste@4.6.0 --yes`
|
|
542
542
|
2. If it persists on a current install, it is a bug: the vhost generators (`packages/server/daemon/src/lib/nginx.js`) and the allow-list (`packages/provisioners/server/scripts/lamaste-priv`) must change together — `npm test` checks every generated vhost against the allow-list. Do not work around it by editing files in `/etc/nginx` by hand.
|
|
543
543
|
|
|
544
544
|
`sudo: a password is required` for `lamaste-priv` means the helper or the sudoers file is missing or outdated: re-run the installer.
|
|
@@ -621,7 +621,7 @@ df -h /
|
|
|
621
621
|
|
|
622
622
|
**Cause 3: The web root is not writable by the panel (`EACCES`).**
|
|
623
623
|
|
|
624
|
-
The panel writes `/var/www/lamaste` itself: it must be `lamaste:www-data`, directories `2750`, files `0640`. An install from before this layout had it owned by `www-data`. Re-run the installer (`npx @lamalibre/create-lamaste@4.
|
|
624
|
+
The panel writes `/var/www/lamaste` itself: it must be `lamaste:www-data`, directories `2750`, files `0640`. An install from before this layout had it owned by `www-data`. Re-run the installer (`npx @lamalibre/create-lamaste@4.6.0 --yes`); the redeploy converts the tree.
|
|
625
625
|
|
|
626
626
|
---
|
|
627
627
|
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
`@lamalibre/lamaste-gatekeeper@4.
|
|
7
|
+
`@lamalibre/lamaste-gatekeeper@4.6.0` is a standalone authorization package for Lamaste. It manages **groups** and **grants**, enforces tunnel access control via a lightweight Fastify service, and serves user-friendly "request access" pages when access is denied.
|
|
8
8
|
|
|
9
|
-
It follows the same architectural pattern as `@lamalibre/lamaste-tickets@4.
|
|
9
|
+
It follows the same architectural pattern as `@lamalibre/lamaste-tickets@4.6.0` — a solid library at the core, with a service, CLI, and desktop as consumers.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -206,7 +206,7 @@ The grant system is resource-agnostic. It doesn't know what a "tunnel" or "plugi
|
|
|
206
206
|
|
|
207
207
|
```js
|
|
208
208
|
import { createGroup, listGroups, getGroup, updateGroup, deleteGroup,
|
|
209
|
-
addMembers, removeMembers, getGroupsForUser } from '@lamalibre/lamaste-gatekeeper@4.
|
|
209
|
+
addMembers, removeMembers, getGroupsForUser } from '@lamalibre/lamaste-gatekeeper@4.6.0';
|
|
210
210
|
|
|
211
211
|
createGroup(name, { description?, createdBy? })
|
|
212
212
|
// → { name, description, members: [], createdAt, createdBy }
|
|
@@ -242,7 +242,7 @@ getGroupsForUser(username)
|
|
|
242
242
|
### Grants
|
|
243
243
|
|
|
244
244
|
```js
|
|
245
|
-
import { createGrant, listGrants, getGrant, revokeGrant } from '@lamalibre/lamaste-gatekeeper@4.
|
|
245
|
+
import { createGrant, listGrants, getGrant, revokeGrant } from '@lamalibre/lamaste-gatekeeper@4.6.0';
|
|
246
246
|
|
|
247
247
|
createGrant({ principalType, principalId, resourceType, resourceId, context? })
|
|
248
248
|
// → grant object
|
|
@@ -269,7 +269,7 @@ revokeGrant(grantId)
|
|
|
269
269
|
### Authorization
|
|
270
270
|
|
|
271
271
|
```js
|
|
272
|
-
import { checkAccess } from '@lamalibre/lamaste-gatekeeper@4.
|
|
272
|
+
import { checkAccess } from '@lamalibre/lamaste-gatekeeper@4.6.0';
|
|
273
273
|
|
|
274
274
|
checkAccess(username, resourceType, resourceId);
|
|
275
275
|
// 1. Find direct user grants: principalType='user', principalId=username
|
|
@@ -284,7 +284,7 @@ checkAccess(username, resourceType, resourceId);
|
|
|
284
284
|
### Templates
|
|
285
285
|
|
|
286
286
|
```js
|
|
287
|
-
import { getAccessRequestTemplates } from '@lamalibre/lamaste-gatekeeper@4.
|
|
287
|
+
import { getAccessRequestTemplates } from '@lamalibre/lamaste-gatekeeper@4.6.0';
|
|
288
288
|
|
|
289
289
|
getAccessRequestTemplates(username, resourceName, { adminContact?, domain? })
|
|
290
290
|
// → {
|
|
@@ -866,14 +866,14 @@ On first startup, gatekeeper checks for legacy files:
|
|
|
866
866
|
|
|
867
867
|
### Panel-Server Refactoring
|
|
868
868
|
|
|
869
|
-
- `lib/user-access.js` → delegates to gatekeeper library (import from `@lamalibre/lamaste-gatekeeper@4.
|
|
869
|
+
- `lib/user-access.js` → delegates to gatekeeper library (import from `@lamalibre/lamaste-gatekeeper@4.6.0`)
|
|
870
870
|
- `lib/access-control-sync.js` → removed (gatekeeper handles authorization at nginx layer, no more Authelia config rewriting for per-user access rules)
|
|
871
871
|
- `routes/user-access.js` → simplified, delegates grant CRUD to gatekeeper
|
|
872
872
|
- Tunnel creation/update routes → call gatekeeper for access mode changes
|
|
873
873
|
|
|
874
874
|
### Installer Updates (create-lamaste)
|
|
875
875
|
|
|
876
|
-
- Install `@lamalibre/lamaste-gatekeeper@4.
|
|
876
|
+
- Install `@lamalibre/lamaste-gatekeeper@4.6.0` package
|
|
877
877
|
- Create `/etc/lamalibre/lamaste/groups.json` (empty initial state)
|
|
878
878
|
- Create `/etc/lamalibre/lamaste/access-grants.json` (empty or migrated)
|
|
879
879
|
- Create `lamalibre-lamaste-gatekeeper.service` systemd unit
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Lamaste Identity Directory — Design Document
|
|
2
2
|
|
|
3
3
|
> **Status:** design, 2026-10-13. Partly implemented in Lamaste 4.5 for agent-hosted plugins — see [Status](#status-4-5-slice-6).
|
|
4
|
-
> **Package:** `@lamalibre/lamaste-identity@4.
|
|
4
|
+
> **Package:** `@lamalibre/lamaste-identity@4.6.0` (completes the existing SDK).
|
|
5
5
|
> **Companions:** `gatekeeper-design.md` (authorization),
|
|
6
6
|
> `plugin-development/design/agent-hosted-app-plugins.md` (app plugins).
|
|
7
7
|
|
|
@@ -16,7 +16,7 @@ Slice 6 of the agent-hosted app plugins (`plugin-development/design/agent-hosted
|
|
|
16
16
|
- **The manifest `identity` block** (roles, `attributes` ⊆ `displayName`, `email`) for agent-hosted plugins with an agent half, inside the approval digest when present; an update that adds or removes a role or widens the attributes waits for an administrator (`identity.changed`) — auto-approve never covers it.
|
|
17
17
|
- **Entitlements** are Gatekeeper plugin grants with `context.roles`, checked against the manifest; roleless grants never count. `user-plugin-access.json` is **not** migrated: it still gates the desktop's enrolment, not requests.
|
|
18
18
|
- **The audience** per plugin, materialized and recomputed after every panel-side change, every minute and at start.
|
|
19
|
-
- **The feed is pushed, not pulled.** An agent half cannot reach the panel, so the panel sends the data itself through the internal tunnel — `POST /admin/identity/notify`, then `/admin/identity/changes` batches, their changes sealed to the request (AES-256-GCM under a key derived from the installation secret) — with replay from 0 as the snapshot and a daily reconcile whose mismatches are audited. A plugin's users reach it only once its half has applied the feed up to the head. The subscriber is `createIdentityProjection` + `createIdentityHandlers` in `@lamalibre/lamaste@4.
|
|
19
|
+
- **The feed is pushed, not pulled.** An agent half cannot reach the panel, so the panel sends the data itself through the internal tunnel — `POST /admin/identity/notify`, then `/admin/identity/changes` batches, their changes sealed to the request (AES-256-GCM under a key derived from the installation secret) — with replay from 0 as the snapshot and a daily reconcile whose mismatches are audited. A plugin's users reach it only once its half has applied the feed up to the head. The subscriber is `createIdentityProjection` + `createIdentityHandlers` in `@lamalibre/lamaste@4.6.0/agent`, not an `IdentitySubscriber` in this SDK.
|
|
20
20
|
- **Identity in requests, for agent-hosted plugins:** a tunnel bound as a plugin's user surface serves `/api/<route>/app/*`; Gatekeeper attests the session's username to the panel, and the panel forwards to the agent half with `{ type: "user", userId, username, roles }` in the HMAC caller assertion — not a JWT ([question 6](#open-questions)).
|
|
21
21
|
|
|
22
22
|
**Not yet:**
|
|
@@ -201,7 +201,7 @@ and compares it with the local projection (by `userId` and `version`). It
|
|
|
201
201
|
applies differences and logs how many it found — a non-zero count on a
|
|
202
202
|
healthy system is a bug in the change feed and is reported to the panel.
|
|
203
203
|
|
|
204
|
-
## SDK (`@lamalibre/lamaste-identity@4.
|
|
204
|
+
## SDK (`@lamalibre/lamaste-identity@4.6.0`)
|
|
205
205
|
|
|
206
206
|
Today's surface stays; three pieces are added.
|
|
207
207
|
|
package/vendor/docs/package.json
CHANGED