@lamalibre/create-lamaste 4.0.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 (270) hide show
  1. package/LICENSE.md +118 -0
  2. package/README.md +114 -0
  3. package/bin/create-lamaste.js +15 -0
  4. package/package.json +54 -0
  5. package/scripts/bundle-vendor.js +110 -0
  6. package/scripts/lamaste-cert-info +62 -0
  7. package/scripts/lamaste-certbot +96 -0
  8. package/scripts/lamaste-priv +693 -0
  9. package/src/index.js +646 -0
  10. package/src/lib/accounts.js +86 -0
  11. package/src/lib/binaries.js +137 -0
  12. package/src/lib/cert-help-page.js +160 -0
  13. package/src/lib/env.js +132 -0
  14. package/src/lib/http-redirect.js +38 -0
  15. package/src/lib/ownership.js +231 -0
  16. package/src/lib/relay-services.js +103 -0
  17. package/src/lib/secrets.js +19 -0
  18. package/src/lib/service-config.js +311 -0
  19. package/src/lib/summary.js +131 -0
  20. package/src/lib/wrappers.js +63 -0
  21. package/src/tasks/gatekeeper.js +233 -0
  22. package/src/tasks/harden.js +293 -0
  23. package/src/tasks/mtls.js +193 -0
  24. package/src/tasks/nginx.js +265 -0
  25. package/src/tasks/node.js +110 -0
  26. package/src/tasks/panel.js +408 -0
  27. package/src/tasks/redeploy.js +438 -0
  28. package/vendor/docs/00-introduction/how-it-works.md +447 -0
  29. package/vendor/docs/00-introduction/quickstart.md +472 -0
  30. package/vendor/docs/00-introduction/what-is-lamaste.md +112 -0
  31. package/vendor/docs/01-concepts/authentication.md +464 -0
  32. package/vendor/docs/01-concepts/authorization.md +242 -0
  33. package/vendor/docs/01-concepts/certificates.md +452 -0
  34. package/vendor/docs/01-concepts/dns-and-domains.md +343 -0
  35. package/vendor/docs/01-concepts/mtls.md +490 -0
  36. package/vendor/docs/01-concepts/nginx-reverse-proxy.md +540 -0
  37. package/vendor/docs/01-concepts/security-model.md +600 -0
  38. package/vendor/docs/01-concepts/tickets.md +414 -0
  39. package/vendor/docs/01-concepts/tunneling.md +367 -0
  40. package/vendor/docs/02-guides/agent-setup.md +194 -0
  41. package/vendor/docs/02-guides/certificate-management.md +341 -0
  42. package/vendor/docs/02-guides/cloud-provisioning.md +406 -0
  43. package/vendor/docs/02-guides/desktop-app-setup.md +226 -0
  44. package/vendor/docs/02-guides/disaster-recovery.md +464 -0
  45. package/vendor/docs/02-guides/first-tunnel.md +230 -0
  46. package/vendor/docs/02-guides/installation.md +393 -0
  47. package/vendor/docs/02-guides/managing-users.md +255 -0
  48. package/vendor/docs/02-guides/onboarding.md +244 -0
  49. package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +375 -0
  50. package/vendor/docs/02-guides/static-sites.md +364 -0
  51. package/vendor/docs/03-architecture/e2e-three-vm-sequences.md +457 -0
  52. package/vendor/docs/03-architecture/installer-flow.md +151 -0
  53. package/vendor/docs/03-architecture/installer.md +445 -0
  54. package/vendor/docs/03-architecture/management-flow.md +288 -0
  55. package/vendor/docs/03-architecture/nginx-configuration.md +830 -0
  56. package/vendor/docs/03-architecture/onboarding-flow.md +164 -0
  57. package/vendor/docs/03-architecture/overview.md +541 -0
  58. package/vendor/docs/03-architecture/panel-client.md +416 -0
  59. package/vendor/docs/03-architecture/panel-server.md +695 -0
  60. package/vendor/docs/03-architecture/state-management.md +529 -0
  61. package/vendor/docs/03-architecture/system-overview.md +167 -0
  62. package/vendor/docs/04-api-reference/certificates.md +1141 -0
  63. package/vendor/docs/04-api-reference/gatekeeper.md +592 -0
  64. package/vendor/docs/04-api-reference/onboarding.md +473 -0
  65. package/vendor/docs/04-api-reference/overview.md +404 -0
  66. package/vendor/docs/04-api-reference/services.md +267 -0
  67. package/vendor/docs/04-api-reference/settings.md +343 -0
  68. package/vendor/docs/04-api-reference/sites.md +716 -0
  69. package/vendor/docs/04-api-reference/system.md +268 -0
  70. package/vendor/docs/04-api-reference/tickets.md +618 -0
  71. package/vendor/docs/04-api-reference/tunnels.md +417 -0
  72. package/vendor/docs/04-api-reference/users.md +333 -0
  73. package/vendor/docs/05-operations/backup-and-restore.md +342 -0
  74. package/vendor/docs/05-operations/monitoring.md +285 -0
  75. package/vendor/docs/05-operations/uninstalling.md +344 -0
  76. package/vendor/docs/05-operations/upgrades.md +270 -0
  77. package/vendor/docs/06-reference/config-files.md +1080 -0
  78. package/vendor/docs/06-reference/glossary.md +528 -0
  79. package/vendor/docs/06-reference/installer-flags.md +260 -0
  80. package/vendor/docs/06-reference/ports-and-services.md +244 -0
  81. package/vendor/docs/06-reference/troubleshooting.md +665 -0
  82. package/vendor/docs/_index.json +233 -0
  83. package/vendor/docs/gatekeeper-design.md +953 -0
  84. package/vendor/docs/package.json +15 -0
  85. package/vendor/docs/todo/lib-cli-desktop-refactor.md +641 -0
  86. package/vendor/gatekeeper/dist/boot.d.ts +1 -0
  87. package/vendor/gatekeeper/dist/boot.d.ts.map +1 -0
  88. package/vendor/gatekeeper/dist/boot.js +17 -0
  89. package/vendor/gatekeeper/dist/boot.js.map +1 -0
  90. package/vendor/gatekeeper/dist/cli/commands/access.d.ts +2 -0
  91. package/vendor/gatekeeper/dist/cli/commands/access.d.ts.map +1 -0
  92. package/vendor/gatekeeper/dist/cli/commands/access.js +33 -0
  93. package/vendor/gatekeeper/dist/cli/commands/access.js.map +1 -0
  94. package/vendor/gatekeeper/dist/cli/commands/grants.d.ts +2 -0
  95. package/vendor/gatekeeper/dist/cli/commands/grants.d.ts.map +1 -0
  96. package/vendor/gatekeeper/dist/cli/commands/grants.js +110 -0
  97. package/vendor/gatekeeper/dist/cli/commands/grants.js.map +1 -0
  98. package/vendor/gatekeeper/dist/cli/commands/groups.d.ts +2 -0
  99. package/vendor/gatekeeper/dist/cli/commands/groups.d.ts.map +1 -0
  100. package/vendor/gatekeeper/dist/cli/commands/groups.js +98 -0
  101. package/vendor/gatekeeper/dist/cli/commands/groups.js.map +1 -0
  102. package/vendor/gatekeeper/dist/cli/index.d.ts +3 -0
  103. package/vendor/gatekeeper/dist/cli/index.d.ts.map +1 -0
  104. package/vendor/gatekeeper/dist/cli/index.js +45 -0
  105. package/vendor/gatekeeper/dist/cli/index.js.map +1 -0
  106. package/vendor/gatekeeper/dist/index.d.ts +9 -0
  107. package/vendor/gatekeeper/dist/index.d.ts.map +1 -0
  108. package/vendor/gatekeeper/dist/index.js +13 -0
  109. package/vendor/gatekeeper/dist/index.js.map +1 -0
  110. package/vendor/gatekeeper/dist/lib/authz.d.ts +16 -0
  111. package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -0
  112. package/vendor/gatekeeper/dist/lib/authz.js +42 -0
  113. package/vendor/gatekeeper/dist/lib/authz.js.map +1 -0
  114. package/vendor/gatekeeper/dist/lib/cache-bust.d.ts +15 -0
  115. package/vendor/gatekeeper/dist/lib/cache-bust.d.ts.map +1 -0
  116. package/vendor/gatekeeper/dist/lib/cache-bust.js +19 -0
  117. package/vendor/gatekeeper/dist/lib/cache-bust.js.map +1 -0
  118. package/vendor/gatekeeper/dist/lib/constants.d.ts +82 -0
  119. package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -0
  120. package/vendor/gatekeeper/dist/lib/constants.js +79 -0
  121. package/vendor/gatekeeper/dist/lib/constants.js.map +1 -0
  122. package/vendor/gatekeeper/dist/lib/grants.d.ts +32 -0
  123. package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -0
  124. package/vendor/gatekeeper/dist/lib/grants.js +314 -0
  125. package/vendor/gatekeeper/dist/lib/grants.js.map +1 -0
  126. package/vendor/gatekeeper/dist/lib/groups.d.ts +10 -0
  127. package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -0
  128. package/vendor/gatekeeper/dist/lib/groups.js +247 -0
  129. package/vendor/gatekeeper/dist/lib/groups.js.map +1 -0
  130. package/vendor/gatekeeper/dist/lib/migration.d.ts +17 -0
  131. package/vendor/gatekeeper/dist/lib/migration.d.ts.map +1 -0
  132. package/vendor/gatekeeper/dist/lib/migration.js +79 -0
  133. package/vendor/gatekeeper/dist/lib/migration.js.map +1 -0
  134. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0001_groups.sql +7 -0
  135. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0002_access_grants.sql +14 -0
  136. package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0003_access_request_log.sql +9 -0
  137. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +7 -0
  138. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +14 -0
  139. package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +9 -0
  140. package/vendor/gatekeeper/dist/lib/state-db.d.ts +16 -0
  141. package/vendor/gatekeeper/dist/lib/state-db.d.ts.map +1 -0
  142. package/vendor/gatekeeper/dist/lib/state-db.js +154 -0
  143. package/vendor/gatekeeper/dist/lib/state-db.js.map +1 -0
  144. package/vendor/gatekeeper/dist/lib/templates.d.ts +21 -0
  145. package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -0
  146. package/vendor/gatekeeper/dist/lib/templates.js +151 -0
  147. package/vendor/gatekeeper/dist/lib/templates.js.map +1 -0
  148. package/vendor/gatekeeper/dist/lib/types.d.ts +178 -0
  149. package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -0
  150. package/vendor/gatekeeper/dist/lib/types.js +2 -0
  151. package/vendor/gatekeeper/dist/lib/types.js.map +1 -0
  152. package/vendor/gatekeeper/dist/server/index.d.ts +15 -0
  153. package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -0
  154. package/vendor/gatekeeper/dist/server/index.js +251 -0
  155. package/vendor/gatekeeper/dist/server/index.js.map +1 -0
  156. package/vendor/gatekeeper/dist/server/routes/access-request.d.ts +7 -0
  157. package/vendor/gatekeeper/dist/server/routes/access-request.d.ts.map +1 -0
  158. package/vendor/gatekeeper/dist/server/routes/access-request.js +17 -0
  159. package/vendor/gatekeeper/dist/server/routes/access-request.js.map +1 -0
  160. package/vendor/gatekeeper/dist/server/routes/authz.d.ts +3 -0
  161. package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -0
  162. package/vendor/gatekeeper/dist/server/routes/authz.js +279 -0
  163. package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -0
  164. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts +13 -0
  165. package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -0
  166. package/vendor/gatekeeper/dist/server/routes/diagnostic.js +249 -0
  167. package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -0
  168. package/vendor/gatekeeper/dist/server/routes/grants.d.ts +3 -0
  169. package/vendor/gatekeeper/dist/server/routes/grants.d.ts.map +1 -0
  170. package/vendor/gatekeeper/dist/server/routes/grants.js +112 -0
  171. package/vendor/gatekeeper/dist/server/routes/grants.js.map +1 -0
  172. package/vendor/gatekeeper/dist/server/routes/groups.d.ts +3 -0
  173. package/vendor/gatekeeper/dist/server/routes/groups.d.ts.map +1 -0
  174. package/vendor/gatekeeper/dist/server/routes/groups.js +139 -0
  175. package/vendor/gatekeeper/dist/server/routes/groups.js.map +1 -0
  176. package/vendor/gatekeeper/package.json +49 -0
  177. package/vendor/server/bin/lamaste-server.js +204 -0
  178. package/vendor/server/package.json +31 -0
  179. package/vendor/server/src/commands/certs.js +224 -0
  180. package/vendor/server/src/commands/chisel.js +132 -0
  181. package/vendor/server/src/commands/logs.js +49 -0
  182. package/vendor/server/src/commands/plugins.js +321 -0
  183. package/vendor/server/src/commands/reset-admin.js +478 -0
  184. package/vendor/server/src/commands/restart.js +94 -0
  185. package/vendor/server/src/commands/sites.js +257 -0
  186. package/vendor/server/src/commands/status.js +158 -0
  187. package/vendor/server/src/commands/tunnels.js +365 -0
  188. package/vendor/server/src/commands/uninstall.js +326 -0
  189. package/vendor/server/src/config.js +38 -0
  190. package/vendor/server/src/exec.js +26 -0
  191. package/vendor/server/src/logger.js +39 -0
  192. package/vendor/server/src/ndjson.js +56 -0
  193. package/vendor/server/src/panel-api.js +85 -0
  194. package/vendor/server/src/state.js +45 -0
  195. package/vendor/server-ui/dist/assets/index-B0nWuUyL.js +257 -0
  196. package/vendor/server-ui/dist/assets/index-BqWWFlTU.css +1 -0
  197. package/vendor/server-ui/dist/index.html +13 -0
  198. package/vendor/serverd/package.json +44 -0
  199. package/vendor/serverd/src/boot.js +13 -0
  200. package/vendor/serverd/src/index.js +191 -0
  201. package/vendor/serverd/src/lib/app-error.js +14 -0
  202. package/vendor/serverd/src/lib/authelia.js +85 -0
  203. package/vendor/serverd/src/lib/certbot.js +74 -0
  204. package/vendor/serverd/src/lib/chisel-args.js +6 -0
  205. package/vendor/serverd/src/lib/chisel-reconcile.js +232 -0
  206. package/vendor/serverd/src/lib/chisel-runtime.js +46 -0
  207. package/vendor/serverd/src/lib/chisel-users.js +109 -0
  208. package/vendor/serverd/src/lib/chisel.js +81 -0
  209. package/vendor/serverd/src/lib/config.js +190 -0
  210. package/vendor/serverd/src/lib/constants.js +8 -0
  211. package/vendor/serverd/src/lib/csr-signing.js +331 -0
  212. package/vendor/serverd/src/lib/enrollment.js +302 -0
  213. package/vendor/serverd/src/lib/files.js +19 -0
  214. package/vendor/serverd/src/lib/gatekeeper-client.js +135 -0
  215. package/vendor/serverd/src/lib/invite-page.js +281 -0
  216. package/vendor/serverd/src/lib/ip-utils.js +79 -0
  217. package/vendor/serverd/src/lib/migrations/state/0001_enrollment_tokens.sql +17 -0
  218. package/vendor/serverd/src/lib/migrations/state/0002_tickets.sql +70 -0
  219. package/vendor/serverd/src/lib/migrations/state/0003_plugins.sql +15 -0
  220. package/vendor/serverd/src/lib/migrations/state/0004_agents.sql +19 -0
  221. package/vendor/serverd/src/lib/mtls.js +795 -0
  222. package/vendor/serverd/src/lib/nginx.js +1090 -0
  223. package/vendor/serverd/src/lib/pki-paths.js +41 -0
  224. package/vendor/serverd/src/lib/pki-sign.js +103 -0
  225. package/vendor/serverd/src/lib/plugins.js +538 -0
  226. package/vendor/serverd/src/lib/push-install.js +390 -0
  227. package/vendor/serverd/src/lib/revocation.js +112 -0
  228. package/vendor/serverd/src/lib/services.js +131 -0
  229. package/vendor/serverd/src/lib/session.js +151 -0
  230. package/vendor/serverd/src/lib/state-db.js +130 -0
  231. package/vendor/serverd/src/lib/state.js +140 -0
  232. package/vendor/serverd/src/lib/storage.js +63 -0
  233. package/vendor/serverd/src/lib/system-stats.js +58 -0
  234. package/vendor/serverd/src/lib/tickets.js +1556 -0
  235. package/vendor/serverd/src/lib/totp.js +76 -0
  236. package/vendor/serverd/src/lib/tunnel-deps.js +41 -0
  237. package/vendor/serverd/src/lib/user-access-session.js +142 -0
  238. package/vendor/serverd/src/lib/user-access.js +52 -0
  239. package/vendor/serverd/src/middleware/errors.js +63 -0
  240. package/vendor/serverd/src/middleware/mtls.js +120 -0
  241. package/vendor/serverd/src/middleware/onboarding-guard.js +30 -0
  242. package/vendor/serverd/src/middleware/role-guard.js +58 -0
  243. package/vendor/serverd/src/middleware/twofa-session.js +65 -0
  244. package/vendor/serverd/src/middleware/user-access-session.js +52 -0
  245. package/vendor/serverd/src/routes/enrollment.js +120 -0
  246. package/vendor/serverd/src/routes/health.js +22 -0
  247. package/vendor/serverd/src/routes/invite.js +163 -0
  248. package/vendor/serverd/src/routes/management/agents.js +182 -0
  249. package/vendor/serverd/src/routes/management/certs.js +911 -0
  250. package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +160 -0
  251. package/vendor/serverd/src/routes/management/identity.js +107 -0
  252. package/vendor/serverd/src/routes/management/invitations.js +166 -0
  253. package/vendor/serverd/src/routes/management/logs.js +218 -0
  254. package/vendor/serverd/src/routes/management/plugins.js +560 -0
  255. package/vendor/serverd/src/routes/management/services.js +63 -0
  256. package/vendor/serverd/src/routes/management/settings.js +325 -0
  257. package/vendor/serverd/src/routes/management/sites.js +522 -0
  258. package/vendor/serverd/src/routes/management/storage.js +192 -0
  259. package/vendor/serverd/src/routes/management/system.js +201 -0
  260. package/vendor/serverd/src/routes/management/tickets.js +457 -0
  261. package/vendor/serverd/src/routes/management/tunnels.js +709 -0
  262. package/vendor/serverd/src/routes/management/users.js +377 -0
  263. package/vendor/serverd/src/routes/management.js +36 -0
  264. package/vendor/serverd/src/routes/onboarding/dns.js +101 -0
  265. package/vendor/serverd/src/routes/onboarding/domain.js +42 -0
  266. package/vendor/serverd/src/routes/onboarding/index.js +18 -0
  267. package/vendor/serverd/src/routes/onboarding/provision.js +327 -0
  268. package/vendor/serverd/src/routes/onboarding/status.js +12 -0
  269. package/vendor/serverd/src/routes/plugin-router.js +79 -0
  270. package/vendor/serverd/src/routes/user-access.js +389 -0
@@ -0,0 +1,288 @@
1
+ # Management Flow
2
+
3
+ ## Overview
4
+
5
+ After onboarding completes, the panel becomes the full management interface for the Lamaste. All operations that would traditionally require SSH are handled through the UI.
6
+
7
+ ## Management Areas
8
+
9
+ ### Dashboard
10
+
11
+ - System stats: CPU, RAM, disk usage (polled every 5s)
12
+ - Service health: nginx, Chisel, Authelia, Panel (green/red indicators)
13
+ - Quick overview: active tunnels count, registered users count, cert expiry warnings
14
+
15
+ ### Tunnels
16
+
17
+ Full lifecycle management of tunneled applications.
18
+
19
+ **Add Tunnel Flow:**
20
+
21
+ ```
22
+ User fills form:
23
+ Subdomain: [app1] .example.com
24
+ Local port: [8001]
25
+ Agent: [laptop]
26
+ Description: [My web app]
27
+ [Add Tunnel]
28
+ │
29
+ ▼
30
+ POST /api/tunnels
31
+ ├─ tunnel lock taken (held until the response)
32
+ ├─ agentLabel checked against the agent registry; port not reserved, not in use
33
+ ├─ certbot issues TLS cert for app1.example.com
34
+ ├─ nginx vhost written + symlinked + tested
35
+ ├─ systemctl reload nginx
36
+ ├─ tunnels.json updated
37
+ ├─ chisel-users re-rendered: agent-laptop may bind ^R:127\.0\.0\.1:8001$
38
+ │ (Chisel reloads the file itself — an added grant needs no restart)
39
+ └─ response: { ok: true, tunnel: { ..., agentLabel: "laptop" } }
40
+ │
41
+ ▼
42
+ UI updates: new tunnel appears in list with its agent
43
+ └─ within ~30 s laptop's sync timer fetches agent-config and starts forwarding 8001
44
+ ```
45
+
46
+ **Remove Tunnel Flow:**
47
+
48
+ ```
49
+ DELETE /api/tunnels/:id
50
+ ├─ nginx vhost removed + reload
51
+ ├─ tunnels.json updated
52
+ ├─ chisel-users re-rendered (owner's grant for the port withdrawn)
53
+ ├─ systemctl try-restart chisel (a withdrawn grant must end live sessions)
54
+ └─ response: { ok: true }
55
+ │
56
+ ▼
57
+ within ~30 s the owner's sync timer drops the remote — otherwise Chisel would
58
+ reject the owner's whole session, and all its other tunnels with it
59
+ ```
60
+
61
+ **Agent Integration:**
62
+
63
+ - Every tunnel is carried by one agent (`agentLabel`). The Chisel authfile grants each agent only the ports of the enabled tunnels it carries, so no agent can bind another's port
64
+ - Each agent's sync timer (`lamaste-agent sync`, every 30 s) fetches that agent's config via `GET /api/tunnels/agent-config` and converges its Chisel client; `lamaste-agent update` does the same at once and restarts the client
65
+ - On macOS, the agent writes a launchd plist; on Linux, a systemd user unit. An agent with no tunnels keeps the client stopped
66
+
67
+ ### Users (Authelia)
68
+
69
+ CRUD for Authelia users who access tunneled applications.
70
+
71
+ **Add User:**
72
+
73
+ - Username + display name + email
74
+ - Password (bcrypt hashed, written to users.yml)
75
+ - TOTP enrollment: generate secret, show QR code
76
+ - `systemctl reload authelia` after users.yml change
77
+
78
+ **Edit User:**
79
+
80
+ - Change password, display name, email
81
+ - Reset TOTP (generate new secret + QR)
82
+
83
+ **Delete User:**
84
+
85
+ - Safety: cannot delete last user
86
+ - Removes from users.yml, reloads Authelia
87
+
88
+ ### Certificates
89
+
90
+ Track and manage all TLS certificates.
91
+
92
+ **Certificate Types:**
93
+
94
+ 1. **Let's Encrypt** — per-subdomain, auto-renewing via certbot
95
+ 2. **mTLS CA** — 10yr validity, internal
96
+ 3. **mTLS Admin** — 2yr validity, full panel access, importable to browser
97
+ 4. **mTLS Agent** — 2yr validity, capability-based access, issued per agent
98
+
99
+ **Actions:**
100
+
101
+ - View all certs with expiry dates
102
+ - Force renewal of Let's Encrypt certs
103
+ - Download the admin p12 (rotation itself is `sudo lamaste-server reset-admin` on the server; the panel does not issue admin certificates)
104
+ - Generate agent certificates (label, capabilities, download p12, share password)
105
+ - List and revoke agent certificates
106
+ - Update agent capabilities (without reissuing the certificate)
107
+ - Expiry warnings at 30/14/7 days
108
+
109
+ ### Services
110
+
111
+ Direct control over system services.
112
+
113
+ **Service Control:**
114
+
115
+ - Start / Stop / Restart / Reload for: nginx, chisel, authelia, lamalibre-lamaste-serverd
116
+ - Status indicator (active/inactive/failed)
117
+ - Current uptime
118
+
119
+ **Live Logs:**
120
+
121
+ - WebSocket streaming of journald logs per service
122
+ - Real-time tail with auto-scroll
123
+ - Service selector dropdown
124
+
125
+ ### Invitations
126
+
127
+ Admin can invite new users via a shareable link. The invitation workflow is separate from direct user creation.
128
+
129
+ **Create Invitation:**
130
+
131
+ - Admin provides username, email, optional groups, and expiry (1-30 days, default 7)
132
+ - Server generates a 64-byte hex token and returns an invite URL
133
+ - Invitation is stored in `invitations.json`
134
+
135
+ **Accept Invitation (public):**
136
+
137
+ - Invited user opens the invite URL and sets their password
138
+ - Server creates the Authelia user with bcrypt-hashed password
139
+ - Invitation is marked as used
140
+
141
+ **Revoke Invitation:**
142
+
143
+ - Admin can delete a pending invitation before it is accepted
144
+
145
+ ### Static Sites
146
+
147
+ Host static websites directly on the Lamaste server, served via nginx.
148
+
149
+ **Site Types:**
150
+
151
+ 1. **Managed** — subdomain of the configured domain (e.g., `blog.example.com`). Certificate and nginx vhost are provisioned automatically on creation.
152
+ 2. **Custom** — external domain. Requires DNS verification before certificate issuance and vhost activation.
153
+
154
+ **Features:**
155
+
156
+ - SPA mode (single-page application fallback to `index.html`)
157
+ - Authelia protection (restrict access to authenticated users)
158
+ - Per-site allowed user lists
159
+ - File management: upload, list, and delete files via the API
160
+ - Max upload size: 50 MB per file
161
+
162
+ ## API Routes
163
+
164
+ ### Tunnel Management
165
+
166
+ | Method | Path | Description | Roles |
167
+ | ------ | --------------------------------- | ---------------------------------------------- | ------------------------------ |
168
+ | GET | `/api/tunnels` | List tunnels (an agent sees only its own) | admin, agent |
169
+ | POST | `/api/tunnels` | Add tunnel (triggers nginx + certbot + chisel) | admin, agent (`tunnels:write`) |
170
+ | PATCH | `/api/tunnels/:id` | Move (admin), access mode, body limit, enable | admin, agent (`tunnels:write`) |
171
+ | DELETE | `/api/tunnels/:id` | Remove tunnel | admin, agent (`tunnels:write`) |
172
+ | GET | `/api/tunnels/agent-config` | One agent's Chisel config | admin, agent (`tunnels:read`) |
173
+ | GET | `/api/tunnels/agent-panel-status` | Check agent panel expose status | admin, agent (`panel:expose`) |
174
+ | POST | `/api/tunnels/expose-panel` | Expose agent management panel as subdomain | admin, agent (`panel:expose`) |
175
+ | DELETE | `/api/tunnels/retract-panel` | Retract agent management panel | admin, agent (`panel:expose`) |
176
+
177
+ ### User Management
178
+
179
+ | Method | Path | Description |
180
+ | ------ | --------------------------------- | --------------------------------------- |
181
+ | GET | `/api/users` | List Authelia users |
182
+ | POST | `/api/users` | Create user (bcrypt hash + TOTP secret) |
183
+ | PUT | `/api/users/:username` | Update user |
184
+ | DELETE | `/api/users/:username` | Delete user (not last) |
185
+ | POST | `/api/users/:username/reset-totp` | Generate new TOTP secret |
186
+
187
+ ### Certificate Management
188
+
189
+ | Method | Path | Description |
190
+ | ------ | --------------------------------------- | ------------------------------------ |
191
+ | GET | `/api/certs` | List all certs with expiry |
192
+ | GET | `/api/certs/auto-renew-status` | Certbot auto-renewal timer status |
193
+ | POST | `/api/certs/:domain/renew` | Force certbot renewal |
194
+ | POST | `/api/certs/mtls/rotate` | Generate new admin client cert + p12 |
195
+ | GET | `/api/certs/mtls/download` | Download admin client.p12 |
196
+ | POST | `/api/certs/agent` | Generate agent-scoped certificate |
197
+ | GET | `/api/certs/agent` | List agent certificates |
198
+ | GET | `/api/certs/agent/:label/download` | Download agent .p12 |
199
+ | PATCH | `/api/certs/agent/:label/capabilities` | Update agent capabilities |
200
+ | PATCH | `/api/certs/agent/:label/allowed-sites` | Update agent site access |
201
+ | DELETE | `/api/certs/agent/:label` | Revoke agent certificate |
202
+
203
+ ### Service Management
204
+
205
+ | Method | Path | Description | Roles |
206
+ | ------ | ----------------------------- | --------------------------------- | ------------------------------- |
207
+ | GET | `/api/services` | List service statuses | admin, agent (`services:read`) |
208
+ | POST | `/api/services/:name/:action` | start/stop/restart/reload service | admin, agent (`services:write`) |
209
+ | GET | `/api/services/:name/logs` | WebSocket log stream | admin only |
210
+
211
+ ### Invitation Management
212
+
213
+ | Method | Path | Description | Roles |
214
+ | ------ | ---------------------- | -------------------------------------- | ----- |
215
+ | GET | `/api/invitations` | List all invitations (tokens redacted) | admin |
216
+ | POST | `/api/invitations` | Create a new invitation | admin |
217
+ | DELETE | `/api/invitations/:id` | Revoke an invitation | admin |
218
+
219
+ **Public invite routes** (no mTLS required):
220
+
221
+ | Method | Path | Description |
222
+ | ------ | --------------------------- | ---------------------------------- |
223
+ | GET | `/api/invite/:token` | Get invitation details |
224
+ | POST | `/api/invite/:token/accept` | Accept invitation and set password |
225
+
226
+ ### Static Sites Management
227
+
228
+ | Method | Path | Description | Roles |
229
+ | ------ | --------------------------- | --------------------------------- | ---------------------------- |
230
+ | GET | `/api/sites` | List all static sites | admin, agent (`sites:read`) |
231
+ | POST | `/api/sites` | Create a static site | admin |
232
+ | DELETE | `/api/sites/:id` | Delete a static site | admin |
233
+ | PATCH | `/api/sites/:id` | Update site settings | admin |
234
+ | POST | `/api/sites/:id/verify-dns` | Verify DNS for custom domain site | admin |
235
+ | GET | `/api/sites/:id/files` | List files in site directory | admin, agent (`sites:read`) |
236
+ | POST | `/api/sites/:id/files` | Upload files (multipart) | admin, agent (`sites:write`) |
237
+ | DELETE | `/api/sites/:id/files` | Delete a file from site directory | admin, agent (`sites:write`) |
238
+
239
+ ### System
240
+
241
+ | Method | Path | Description | Roles |
242
+ | ------ | ------------------- | -------------------- | ---------------------------- |
243
+ | GET | `/api/system/stats` | CPU, RAM, disk usage | admin, agent (`system:read`) |
244
+ | GET | `/api/health` | Panel health check | admin, agent (all) |
245
+
246
+ ## Sudoers Rules
247
+
248
+ The panel runs as a non-root user (`lamaste`) and cannot become root. `/etc/sudoers.d/lamaste` is written by `generateSudoersContent()` in `packages/provisioners/server/src/lib/service-config.js` and contains **no wildcard at all**: a sudoers `*` matches spaces too, so a rule like `certbot renew --cert-name * --non-interactive` would also accept `--deploy-hook <command>`, and `mv /tmp/nginx-* /etc/nginx/sites-available/*` would accept `-t /etc/sudoers.d`. Every rule is a fixed command line or a root-owned program that validates its own arguments:
249
+
250
+ ```sudoers
251
+ # --- systemctl: managed services (fixed command lines) ---
252
+ lamaste ALL=(root) NOPASSWD: /usr/bin/systemctl reload nginx
253
+ lamaste ALL=(root) NOPASSWD: /usr/bin/systemctl try-restart chisel
254
+ # fail-closed startup reconciliation disables chisel, and re-enables it on success
255
+ lamaste ALL=(root) NOPASSWD: /usr/bin/systemctl disable chisel
256
+ lamaste ALL=(root) NOPASSWD: /usr/bin/systemctl reload authelia
257
+ # ... start/stop/restart/enable for nginx, chisel, authelia, certbot.timer,
258
+ # start/stop/restart for lamalibre-lamaste-serverd and lamalibre-lamaste-gatekeeper
259
+
260
+ # --- nginx config test ---
261
+ lamaste ALL=(root) NOPASSWD: /usr/sbin/nginx -t
262
+
263
+ # --- root-owned programs that validate their own arguments ---
264
+ # lamaste-priv nginx-site write|backup|restore|discard-backup|enable|disable|remove <name>
265
+ # lamaste-priv authelia-totp <username> secret on stdin
266
+ # lamaste-priv self-update <version> create-lamaste in a transient unit
267
+ # lamaste-certbot issue <email> <cert-name> <domain>... certbot certonly --nginx
268
+ # lamaste-certbot renew <cert-name> [force] | renew-all | list
269
+ # lamaste-cert-info <lineage> enddate|checkend|san read-only openssl queries
270
+ lamaste ALL=(root) NOPASSWD: /usr/local/sbin/lamaste-priv
271
+ lamaste ALL=(root) NOPASSWD: /usr/local/sbin/lamaste-certbot
272
+ lamaste ALL=(root) NOPASSWD: /usr/local/sbin/lamaste-cert-info
273
+ ```
274
+
275
+ Everything else the panel does needs no rule: the PKI directory (agent CSR signing), the web root, `/etc/authelia` and the Chisel authfile and key belong to `lamaste` or to a group it is in, and binaries, units and service accounts are installed by `create-lamaste` as root. `lamaste-priv` installs a vhost only if every directive is on its allow-list — nginx's root master process opens the files a configuration names. See [Security Model](../01-concepts/security-model.md#privilege-boundary).
276
+
277
+ The certbot wrappers accept only lowercase DNS hostnames (no wildcards or path characters, at most 100 per certificate) and a syntactically valid email address. Renewals the panel triggers pass `--no-random-sleep-on-renew`, because certbot otherwise sleeps up to about 8 minutes before a non-interactive renewal (a delay meant for `certbot.timer`) while an operator waits.
278
+
279
+ Redeploying (`npx @lamalibre/create-lamaste@4.0.0` on an existing install) reinstalls the programs, removes retired ones (`lamaste-sign-csr`, `lamaste-pki-rename`), and replaces this file atomically after `visudo -c` accepts it, so upgrades pick up new rules.
280
+
281
+ ## File Operation Safety
282
+
283
+ - **YAML writes** (users.yml): write to temp file, then atomic rename
284
+ - **nginx changes**: always run `nginx -t` before reload; rollback on failure
285
+ - **Authelia changes**: reload service after users.yml update
286
+ - **Chisel changes**: tunnel state is written first, then the authfile is re-rendered from it (per-agent port grants); Chisel reloads it, and is restarted only when a grant or password is withdrawn
287
+ - **Last-user protection**: never delete the last Authelia user
288
+ - **State persistence**: tunnels.json updated atomically after each tunnel operation