@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,457 @@
1
+ # Three-VM E2E Test — Sequence Diagrams
2
+
3
+ ## Orchestration Flow
4
+
5
+ ```mermaid
6
+ sequenceDiagram
7
+ participant Mac as macOS (Developer)
8
+ participant H as Host VM
9
+ participant A as Agent VM
10
+ participant V as Visitor VM
11
+
12
+ rect rgb(40, 40, 60)
13
+ note over Mac: Phase 1 — Create VMs
14
+ Mac->>H: multipass launch 24.04
15
+ Mac->>A: multipass launch 24.04
16
+ Mac->>V: multipass launch 24.04
17
+ end
18
+
19
+ rect rgb(40, 60, 40)
20
+ note over Mac,H: Phase 2 — Setup
21
+ Mac->>Mac: npm pack create-lamaste
22
+ Mac->>H: transfer tarball
23
+ Mac->>H: npm install -g + create-lamaste --dev
24
+ Mac->>H: transfer test scripts
25
+ Mac->>A: transfer test scripts
26
+ Mac->>V: transfer test scripts
27
+ Mac->>H: setup-host.sh (dnsmasq, certbot shim, onboarding, test user, agent cert)
28
+ H-->>Mac: credentials JSON
29
+ Mac->>H: extract agent P12
30
+ H-->>Mac: client.p12
31
+ Mac->>A: transfer agent P12
32
+ Mac->>A: setup-agent.sh (/etc/hosts, chisel, extract PEM certs)
33
+ Mac->>V: setup-visitor.sh (curl, jq, oathtool, /etc/hosts)
34
+ end
35
+
36
+ rect rgb(60, 40, 40)
37
+ note over Mac,H: Phase 3 — Single-VM E2E
38
+ Mac->>H: run-all.sh (inside host)
39
+ H-->>Mac: test results + logs
40
+ end
41
+
42
+ rect rgb(60, 60, 40)
43
+ note over Mac,V: Phase 4 — Three-VM E2E
44
+ Mac->>Mac: run-all.sh (from macOS, multipass exec into VMs)
45
+ Mac->>H: tests 01–08 (via multipass exec)
46
+ Mac->>A: tests 02–06 (via multipass exec)
47
+ Mac->>V: tests 04, 06–08 (via multipass exec)
48
+ end
49
+
50
+ rect rgb(40, 40, 40)
51
+ note over Mac: Phase 5 — Summary + Cleanup
52
+ Mac->>Mac: collect logs, print results
53
+ Mac-->>H: multipass delete (if --cleanup)
54
+ Mac-->>A: multipass delete (if --cleanup)
55
+ Mac-->>V: multipass delete (if --cleanup)
56
+ end
57
+ ```
58
+
59
+ ## Test 01 — Onboarding Complete Verification
60
+
61
+ ```mermaid
62
+ sequenceDiagram
63
+ participant Mac as macOS (Test Runner)
64
+ participant H as Host VM
65
+ participant A as Agent VM
66
+ participant V as Visitor VM
67
+
68
+ Mac->>H: GET /api/onboarding/status (mTLS)
69
+ H-->>Mac: { status: COMPLETED }
70
+
71
+ Mac->>H: systemctl is-active nginx, chisel, authelia, lamalibre-lamaste-serverd
72
+ H-->>Mac: active (all 4 services)
73
+
74
+ Mac->>H: ls /etc/lamalibre/lamaste/pki/{ca.crt, client.crt, client.key}
75
+ H-->>Mac: files exist
76
+
77
+ Mac->>H: curl https://panel.TEST_DOMAIN (mTLS)
78
+ H-->>Mac: 200 OK (React app)
79
+
80
+ Mac->>H: dig TEST_DOMAIN @127.0.0.1
81
+ H-->>Mac: HOST_IP
82
+
83
+ Mac->>A: curl https://HOST_IP:9292 (no mTLS cert)
84
+ A-->>Mac: TLS handshake failure
85
+
86
+ Mac->>V: curl https://HOST_IP:9292 (no mTLS cert)
87
+ V-->>Mac: TLS handshake failure
88
+
89
+ Mac->>V: curl https://auth.TEST_DOMAIN/
90
+ V-->>Mac: 200 OK (Authelia portal)
91
+ ```
92
+
93
+ ## Test 02 — Tunnel Traffic
94
+
95
+ ```mermaid
96
+ sequenceDiagram
97
+ participant Mac as macOS (Test Runner)
98
+ participant H as Host VM
99
+ participant A as Agent VM
100
+
101
+ note over Mac,H: Setup
102
+ Mac->>H: POST /api/tunnels {subdomain: e2etraffic, port: 18080, agentLabel: test-agent} (mTLS)
103
+ H-->>Mac: { id, fqdn: e2etraffic.TEST_DOMAIN, agentLabel: test-agent }
104
+ Mac->>H: GET /api/tunnels/agent-config?agent=test-agent (mTLS)
105
+ H-->>Mac: tunnels include e2etraffic:18080
106
+ Mac->>H: read chisel-users (grant only, no password printed)
107
+ H-->>Mac: agent-test-agent grants ^R:127\.0\.0\.1:18080$
108
+
109
+ Mac->>A: echo marker > /tmp/e2e-tunnel-index.html
110
+ Mac->>A: python3 -m http.server 18080 --bind 127.0.0.1 &
111
+ Mac->>A: lamaste-agent update (rewrites + restarts the chisel user unit)
112
+
113
+ note over Mac,A: Wait for tunnel
114
+ loop Poll up to 15s
115
+ Mac->>H: curl http://127.0.0.1:18080/
116
+ H-->>Mac: 200 (tunnel established)
117
+ end
118
+
119
+ note over Mac,H: Authenticate with Authelia
120
+ Mac->>H: POST /api/users/testuser/reset-totp (mTLS)
121
+ H-->>Mac: { otpauth URI, TOTP secret }
122
+ Mac->>Mac: oathtool --totp secret
123
+ Mac->>H: POST https://auth.TEST_DOMAIN/api/firstfactor
124
+ H-->>Mac: session cookie
125
+ Mac->>H: POST https://auth.TEST_DOMAIN/api/secondfactor/totp
126
+ H-->>Mac: authenticated session
127
+
128
+ note over Mac,H: Verify traffic
129
+ Mac->>H: curl http://127.0.0.1:18080/e2e-tunnel-index.html (direct)
130
+ H-->>Mac: 200 + marker content
131
+
132
+ Mac->>H: curl https://e2etraffic.TEST_DOMAIN/ -b session (via nginx)
133
+ H-->>Mac: 200 + marker content
134
+
135
+ note over Mac,A: Agent chisel client hygiene
136
+ Mac->>A: inspect unit + chisel.env + running argv
137
+ A-->>Mac: EnvironmentFile=chisel.env (0600), https://tunnel.TEST_DOMAIN:443, no --auth / password / --tls-skip-verify
138
+
139
+ note over Mac,H: Request body limit
140
+ Mac->>H: POST 2 MB body via nginx
141
+ H-->>Mac: not 413 (default limit 10 MB)
142
+ Mac->>H: POST 11 MB body via nginx
143
+ H-->>Mac: 413
144
+
145
+ note over Mac,A: Cleanup
146
+ Mac->>A: pkill python3
147
+ Mac->>H: DELETE /api/tunnels/{id} (mTLS)
148
+ Mac->>A: lamaste-agent update
149
+ ```
150
+
151
+ ## Test 03 — Tunnel Toggle
152
+
153
+ ```mermaid
154
+ sequenceDiagram
155
+ participant Mac as macOS (Test Runner)
156
+ participant H as Host VM
157
+ participant A as Agent VM
158
+
159
+ Mac->>H: POST /api/tunnels {subdomain: e2etoggle, port: 18081, agentLabel: test-agent} (mTLS)
160
+ H-->>Mac: { id, fqdn, agentLabel: test-agent }
161
+
162
+ Mac->>A: start HTTP server + lamaste-agent update
163
+
164
+ note over Mac,H: Verify initial traffic
165
+ Mac->>H: curl http://127.0.0.1:18081/
166
+ H-->>Mac: 200 + marker
167
+
168
+ note over Mac,H: Disable tunnel
169
+ Mac->>H: PATCH /api/tunnels/{id} {enabled: false} (mTLS)
170
+ H-->>Mac: OK
171
+ Mac->>H: read chisel-users grants
172
+ H-->>Mac: test-agent no longer granted ^R:127\.0\.0\.1:18081$
173
+ Mac->>H: ls /etc/nginx/sites-enabled/lamalibre-lamaste-app-e2etoggle
174
+ H-->>Mac: not found (vhost symlink removed)
175
+ Mac->>H: curl https://FQDN/
176
+ H-->>Mac: marker NOT present
177
+
178
+ note over Mac,H: Re-enable tunnel
179
+ Mac->>H: PATCH /api/tunnels/{id} {enabled: true} (mTLS)
180
+ H-->>Mac: OK (grant restored)
181
+ Mac->>H: curl http://127.0.0.1:18081/
182
+ H-->>Mac: 200 + marker
183
+
184
+ note over Mac,H: Reassign to a second agent
185
+ Mac->>H: POST /api/certs/agent (second agent, no chisel client)
186
+ Mac->>H: PATCH /api/tunnels/{id} {agentLabel: <second agent>} (mTLS)
187
+ H-->>Mac: grant moved; test-agent's agent-config no longer lists the tunnel
188
+ Mac->>H: poll 127.0.0.1:18081 for 15s
189
+ H-->>Mac: stays closed (test-agent's client may no longer bind it)
190
+ Mac->>H: PATCH /api/tunnels/{id} {agentLabel: test-agent} (mTLS)
191
+ Mac->>A: lamaste-agent update
192
+ Mac->>H: curl http://127.0.0.1:18081/
193
+ H-->>Mac: 200 + marker
194
+
195
+ note over Mac,H: Authenticated access
196
+ Mac->>H: Authelia first + second factor
197
+ Mac->>H: curl https://FQDN/ -b session
198
+ H-->>Mac: 200 + marker
199
+
200
+ Mac->>A: pkill python3
201
+ Mac->>H: DELETE /api/tunnels/{id} (mTLS)
202
+ ```
203
+
204
+ ## Test 04 — Authelia Authentication (from Visitor)
205
+
206
+ ```mermaid
207
+ sequenceDiagram
208
+ participant Mac as macOS (Test Runner)
209
+ participant H as Host VM
210
+ participant A as Agent VM
211
+ participant V as Visitor VM
212
+
213
+ note over Mac,A: Setup tunnel + HTTP server
214
+ Mac->>H: POST /api/tunnels {subdomain: e2eauth, port: 18082, agentLabel: test-agent} (mTLS)
215
+ Mac->>H: POST /api/users/testuser/reset-totp (mTLS)
216
+ H-->>Mac: TOTP secret
217
+ Mac->>A: start HTTP server + lamaste-agent update
218
+
219
+ note over Mac,V: Unauthenticated access
220
+ Mac->>V: curl https://FQDN/ (no session)
221
+ V->>H: HTTPS request (port 443)
222
+ H-->>V: 302 redirect → auth.TEST_DOMAIN
223
+ V-->>Mac: redirect URL contains auth.TEST_DOMAIN
224
+
225
+ note over Mac,V: Authenticate
226
+ Mac->>V: POST https://auth.TEST_DOMAIN/api/firstfactor
227
+ V->>H: username + password
228
+ H-->>V: session cookie
229
+ V-->>Mac: cookie saved
230
+
231
+ Mac->>V: oathtool --totp secret
232
+ Mac->>V: POST https://auth.TEST_DOMAIN/api/secondfactor/totp
233
+ V->>H: TOTP code + session
234
+ H-->>V: authenticated
235
+ V-->>Mac: OK
236
+
237
+ note over Mac,V: Authenticated access
238
+ Mac->>V: curl https://FQDN/ -b session
239
+ V->>H: request with Authelia session
240
+ H->>H: nginx forward auth → Authelia OK
241
+ H->>H: proxy to chisel → agent HTTP server
242
+ H-->>V: 200 + marker content
243
+ V-->>Mac: marker verified
244
+
245
+ note over Mac,V: Invalid session
246
+ Mac->>V: curl https://FQDN/ -b fake_cookie
247
+ V->>H: request with invalid session
248
+ H-->>V: 302/401 (rejected)
249
+ V-->>Mac: marker NOT present
250
+
251
+ Mac->>A: pkill python3
252
+ Mac->>H: DELETE /api/tunnels/{id}
253
+ ```
254
+
255
+ ## Test 05 — Admin Journey (Panel CRUD)
256
+
257
+ ```mermaid
258
+ sequenceDiagram
259
+ participant Mac as macOS (Test Runner)
260
+ participant H as Host VM
261
+
262
+ note over Mac,H: Panel accessibility
263
+ Mac->>H: GET https://127.0.0.1:9292/ (mTLS)
264
+ H-->>Mac: 200 HTML with <div id="root">
265
+ Mac->>H: GET https://127.0.0.1:9292/ (NO mTLS)
266
+ H-->>Mac: TLS handshake failure
267
+
268
+ note over Mac,H: System endpoints
269
+ Mac->>H: GET /api/health (mTLS)
270
+ H-->>Mac: { status: ok }
271
+ Mac->>H: GET /api/system/stats (mTLS)
272
+ H-->>Mac: { cpu, memory, disk }
273
+
274
+ note over Mac,H: Tunnel CRUD
275
+ Mac->>H: POST /api/tunnels {subdomain, port, agentLabel: test-agent}
276
+ H-->>Mac: { id, agentLabel }
277
+ Mac->>H: GET /api/tunnels
278
+ H-->>Mac: tunnel in list
279
+ Mac->>H: PATCH /api/tunnels/{id} {enabled: false}
280
+ Mac->>H: PATCH /api/tunnels/{id} {enabled: true}
281
+ Mac->>H: DELETE /api/tunnels/{id}
282
+ Mac->>H: GET /api/tunnels
283
+ H-->>Mac: tunnel gone
284
+
285
+ note over Mac,H: User CRUD
286
+ Mac->>H: POST /api/users {username, password, ...}
287
+ H-->>Mac: created
288
+ Mac->>H: GET /api/users
289
+ H-->>Mac: user in list
290
+ Mac->>H: PUT /api/users/{username} {displayname}
291
+ Mac->>H: POST /api/users/{username}/reset-totp
292
+ H-->>Mac: { otpauth URI }
293
+ Mac->>H: DELETE /api/users/{username}
294
+
295
+ note over Mac,H: Services + Certs
296
+ Mac->>H: GET /api/services
297
+ H-->>Mac: [nginx, chisel, authelia, lamalibre-lamaste-serverd]
298
+ Mac->>H: GET /api/certs
299
+ H-->>Mac: certificate info
300
+ ```
301
+
302
+ ## Test 06 — Tunnel User Journey (Full 2FA from Visitor)
303
+
304
+ ```mermaid
305
+ sequenceDiagram
306
+ participant Mac as macOS (Test Runner)
307
+ participant H as Host VM
308
+ participant A as Agent VM
309
+ participant V as Visitor VM
310
+
311
+ Mac->>H: POST /api/tunnels {subdomain: e2ejourney, port: 18090, agentLabel: test-agent} (mTLS)
312
+ Mac->>H: POST /api/users/testuser/reset-totp (mTLS)
313
+ H-->>Mac: TOTP secret
314
+
315
+ Mac->>A: write marker + start HTTP server + lamaste-agent update
316
+
317
+ note over Mac,V: Step 1 — Unauthenticated
318
+ Mac->>V: curl https://FQDN/
319
+ V->>H: request (no session)
320
+ H-->>V: 302 → auth.TEST_DOMAIN
321
+ V-->>Mac: redirected, marker NOT present
322
+
323
+ note over Mac,V: Step 2 — First factor
324
+ Mac->>V: POST /api/firstfactor {username, password}
325
+ V->>H: credentials
326
+ H-->>V: session cookie
327
+
328
+ note over Mac,V: Step 3 — Second factor
329
+ Mac->>V: oathtool → TOTP code
330
+ Mac->>V: POST /api/secondfactor/totp {token}
331
+ V->>H: TOTP + session
332
+ H-->>V: authenticated
333
+
334
+ note over Mac,V: Step 4 — Access tunneled app
335
+ Mac->>V: curl https://FQDN/ -b session
336
+ V->>H: authenticated request
337
+ H->>A: chisel reverse tunnel
338
+ A-->>H: HTTP response (marker)
339
+ H-->>V: 200 + marker
340
+ V-->>Mac: verified
341
+
342
+ note over Mac,V: Step 5 — Session persistence
343
+ Mac->>V: curl https://FQDN/ -b session (again)
344
+ V-->>Mac: 200 + marker (still valid)
345
+
346
+ note over Mac,V: Step 6 — Invalid session
347
+ Mac->>V: curl https://FQDN/ -b fake_cookie
348
+ V-->>Mac: 302/401, marker NOT present
349
+
350
+ Mac->>A: cleanup (pkill, rm)
351
+ Mac->>H: DELETE /api/tunnels/{id}
352
+ ```
353
+
354
+ ## Test 07 — Static Site Visitor Journey
355
+
356
+ ```mermaid
357
+ sequenceDiagram
358
+ participant Mac as macOS (Test Runner)
359
+ participant H as Host VM
360
+ participant V as Visitor VM
361
+
362
+ Mac->>H: POST /api/sites {subdomain: e2eblog, autheliaProtected: true} (mTLS)
363
+ H-->>Mac: { id, fqdn }
364
+ Mac->>H: write marker HTML to /var/www/lamaste/{id}/index.html
365
+ Mac->>H: POST /api/users/testuser/reset-totp (mTLS)
366
+ H-->>Mac: TOTP secret
367
+
368
+ note over Mac,V: Protected — no auth
369
+ Mac->>V: curl https://FQDN/
370
+ V->>H: request (no session)
371
+ H-->>V: 302 → auth.TEST_DOMAIN
372
+ V-->>Mac: redirected
373
+
374
+ note over Mac,V: Protected — with auth
375
+ Mac->>V: Authelia first factor + second factor (TOTP)
376
+ Mac->>V: curl https://FQDN/ -b session
377
+ V->>H: authenticated
378
+ H-->>V: 200 + marker
379
+ V-->>Mac: verified
380
+
381
+ note over Mac,H: Disable Authelia protection
382
+ Mac->>H: PATCH /api/sites/{id} {autheliaProtected: false} (mTLS)
383
+ Mac->>Mac: sleep 2
384
+
385
+ note over Mac,V: Unprotected — no auth needed
386
+ Mac->>V: curl https://FQDN/ (no session)
387
+ V->>H: request
388
+ H-->>V: 200 + marker (public access)
389
+ V-->>Mac: verified
390
+
391
+ note over Mac,H: Re-enable Authelia protection
392
+ Mac->>H: PATCH /api/sites/{id} {autheliaProtected: true} (mTLS)
393
+ Mac->>Mac: sleep 2
394
+
395
+ note over Mac,V: Protected again — no auth
396
+ Mac->>V: curl https://FQDN/ (no session)
397
+ V-->>Mac: 302/401 (enforced again)
398
+
399
+ Mac->>H: DELETE /api/sites/{id} (mTLS)
400
+ ```
401
+
402
+ ## Test 08 — Invitation Journey
403
+
404
+ ```mermaid
405
+ sequenceDiagram
406
+ participant Mac as macOS (Test Runner)
407
+ participant H as Host VM
408
+ participant V as Visitor VM
409
+
410
+ note over Mac,H: Create invitation
411
+ Mac->>H: POST /api/invitations {username: inviteduser, email} (mTLS)
412
+ H-->>Mac: { id, token, inviteUrl }
413
+ Mac->>H: GET /api/invitations (mTLS)
414
+ H-->>Mac: invitation in list
415
+
416
+ note over Mac,V: Accept invitation (public endpoints, no mTLS)
417
+ Mac->>V: GET https://auth.TEST_DOMAIN/api/invite/{token}
418
+ V->>H: public request
419
+ H-->>V: { username, email, expiresAt }
420
+ V-->>Mac: invitation details
421
+
422
+ Mac->>V: POST https://auth.TEST_DOMAIN/api/invite/{token}/accept {password}
423
+ V->>H: accept with password
424
+ H-->>V: user created
425
+ V-->>Mac: OK
426
+
427
+ note over Mac,H: Verify user created
428
+ Mac->>H: GET /api/users (mTLS)
429
+ H-->>Mac: inviteduser in list
430
+
431
+ note over Mac,V: Authenticate as invited user
432
+ Mac->>H: POST /api/users/inviteduser/reset-totp (mTLS)
433
+ H-->>Mac: TOTP secret
434
+ Mac->>V: POST /api/firstfactor {inviteduser, password}
435
+ V->>H: credentials
436
+ H-->>V: session cookie
437
+ Mac->>V: oathtool → TOTP code
438
+ Mac->>V: POST /api/secondfactor/totp
439
+ V->>H: TOTP + session
440
+ H-->>V: authenticated
441
+
442
+ Mac->>V: GET /api/verify -b session
443
+ V->>H: verify session
444
+ H-->>V: 200 (valid)
445
+
446
+ note over Mac,V: Token reuse prevention
447
+ Mac->>V: GET /api/invite/{token}
448
+ V->>H: reuse token
449
+ H-->>V: 410 Gone
450
+
451
+ Mac->>V: POST /api/invite/{token}/accept
452
+ V->>H: reuse token
453
+ H-->>V: 410 Gone
454
+
455
+ Mac->>H: DELETE /api/users/inviteduser (mTLS)
456
+ Mac->>H: DELETE /api/invitations/{id} (mTLS)
457
+ ```
@@ -0,0 +1,151 @@
1
+ # Installer Flow
2
+
3
+ ## What `npx @lamalibre/create-lamaste@4.0.0` Does
4
+
5
+ The installer is a **zero-prompt, fire-and-forget** command. It assumes:
6
+
7
+ - Fresh Ubuntu 24.04 droplet
8
+ - Running as root (or with sudo)
9
+ - Internet connectivity
10
+
11
+ It requires **no user input**. All configuration happens later through the browser UI.
12
+
13
+ ## Execution Flow
14
+
15
+ ```
16
+ $ npx @lamalibre/create-lamaste@4.0.0
17
+
18
+ Lamaste Installer v1.0.0
19
+
20
+ ✔ Detecting environment
21
+ ✔ Hardening OS
22
+ ├─ Creating 1GB swap
23
+ ├─ Configuring UFW firewall (22, 443, 9292)
24
+ ├─ Installing fail2ban
25
+ ├─ Hardening SSH (no password auth)
26
+ └─ Installing dependencies (curl, openssl, nginx, certbot)
27
+ ✔ Installing Node.js 20 LTS
28
+ ✔ Generating mTLS certificates
29
+ ├─ CA certificate (10yr validity)
30
+ ├─ Client certificate (2yr validity)
31
+ └─ Browser bundle (client.p12)
32
+ ✔ Configuring nginx
33
+ ├─ Self-signed TLS for IP:9292
34
+ ├─ mTLS enforcement
35
+ └─ Proxy to panel backend
36
+ ✔ Deploying Lamaste Panel
37
+ ├─ Creating system user and root-owned install directory
38
+ ├─ Installing chisel and Authelia (pinned, SHA-256 verified)
39
+ ├─ Installing lamalibre-lamaste-serverd, CLI, UI, docs
40
+ ├─ Configuring systemd service
41
+ ├─ Installing lamaste-priv and sudoers wrappers
42
+ ├─ Writing sudoers rules (visudo-checked)
43
+ └─ Starting panel service
44
+ ✔ Deploying Gatekeeper
45
+ ✔ Verifying installation
46
+
47
+ ══════════════════════════════════════════════════════════
48
+ ✔ Lamaste installed successfully!
49
+
50
+ 1. Download your certificate:
51
+ scp root@<droplet-ip>:/etc/lamalibre/lamaste/pki/client.p12 ~/Downloads/
52
+
53
+ 2. Import certificate into your browser:
54
+ - macOS: Double-click client.p12 → Keychain Access → Always Trust
55
+ - Password: <generated-p12-password>
56
+
57
+ 3. Open the management panel:
58
+ https://<droplet-ip>:9292
59
+
60
+ 4. You can now disconnect from SSH.
61
+ Everything else is managed through the browser.
62
+ ══════════════════════════════════════════════════════════
63
+ ```
64
+
65
+ ## Tasks Breakdown
66
+
67
+ ### 1. Environment Detection
68
+
69
+ - Verify Ubuntu 24.04
70
+ - Verify root or sudo access
71
+ - Detect droplet IP address (from metadata API or hostname -I)
72
+ - Check available RAM and disk
73
+
74
+ ### 2. OS Hardening
75
+
76
+ - Create 1GB swap file
77
+ - Configure UFW: allow 22, 443, 9292; deny all else
78
+ - Install and configure fail2ban (SSH + nginx jails)
79
+ - Harden SSH: `PasswordAuthentication no`, `PermitRootLogin prohibit-password`
80
+ - Install system packages: curl, openssl, nginx, certbot, python3-certbot-nginx
81
+
82
+ ### 3. Node.js Installation
83
+
84
+ - Install Node.js 20 LTS via NodeSource repository
85
+ - Verify node and npm are available
86
+
87
+ ### 4. mTLS Certificate Generation
88
+
89
+ - Generate CA key + self-signed CA cert (10yr)
90
+ - Generate client key + CSR → sign with CA (2yr)
91
+ - Create PKCS12 bundle with random password
92
+ - Set file permissions (600 for keys, 644 for certs)
93
+ - Store everything under `/etc/lamalibre/lamaste/pki/`
94
+
95
+ ### 5. nginx Configuration
96
+
97
+ - Generate self-signed TLS cert for IP-based access
98
+ - Write mTLS snippet (`ssl_verify_client on`, `ssl_client_certificate ca.crt`)
99
+ - Write IP:9292 vhost with mTLS + proxy to 127.0.0.1:3100
100
+ - Test config (`nginx -t`) and reload
101
+
102
+ ### 6. Panel Deployment
103
+
104
+ - Create the `lamaste` system user
105
+ - Create `/opt/lamalibre/lamaste/` **root-owned** (read-only for `lamaste`; a tree owned by anyone else is moved aside and replaced) and write the certificate help page into it
106
+ - Create the `lamaste-chisel` group and the `lamaste-authelia` account; install Chisel 1.12.0 and Authelia 4.39.28 to `/usr/local/bin` (fixed release URLs, SHA-256 verified before unpacking; a newer Authelia is kept); write `chisel.service` and `authelia.service`; set ownership of `/var/www/lamaste` (`lamaste:www-data`), `/etc/authelia` (`lamaste:lamaste-authelia`) and `/var/log/authelia` (`lamaste-authelia`). The services are started by onboarding
107
+ - Deploy lamalibre-lamaste-serverd from bundled `vendor/lamaste-serverd/` directory + npm install, the `lamaste-server` CLI, and lamaste-server-ui from bundled `vendor/lamaste-server-ui/dist/` (pre-built, avoids Vite build on low-RAM VPS)
108
+ - Write `/etc/lamalibre/lamaste/panel.json` with droplet IP and paths
109
+ - Write systemd unit file for panel service
110
+ - Install the root-owned programs `/usr/local/sbin/lamaste-priv`, `lamaste-certbot` and `lamaste-cert-info`
111
+ - Write `/etc/sudoers.d/lamaste` — fixed `systemctl` lines, `nginx -t`, and the three programs; no wildcards — staged, checked with `visudo -c`, then renamed into place
112
+ - Enable and start the service
113
+
114
+ ### 6b. Gatekeeper Deployment
115
+
116
+ - Deploy the gatekeeper into `/opt/lamalibre/lamaste/gatekeeper` (root-owned), create its state files, write its unit and start it
117
+
118
+ ### 7. Verification
119
+
120
+ - HTTP health check to 127.0.0.1:3100/api/health
121
+ - Verify nginx is proxying correctly
122
+ - Verify mTLS is enforced (curl without cert should fail)
123
+
124
+ ### 8. Summary Output
125
+
126
+ - Print scp command for certificate download
127
+ - Print p12 password
128
+ - Print panel URL
129
+ - Print disconnect instruction
130
+
131
+ ## Design Decisions
132
+
133
+ ### Why zero-prompt?
134
+
135
+ The installer doesn't need domain, email, or ports — all of that is configured through the onboarding UI. This eliminates user error during SSH and makes the installer idempotent and scriptable.
136
+
137
+ ### Why not Docker?
138
+
139
+ 512MB RAM. Docker itself consumes ~100MB, which doesn't leave room for the services. Native systemd services are lighter and simpler to manage.
140
+
141
+ ### Why self-signed TLS for IP access?
142
+
143
+ There's no domain yet during initial setup. The browser will show a certificate warning, but the mTLS client cert still protects the connection. Once onboarding adds a domain, Let's Encrypt provides a real cert for the domain-based access.
144
+
145
+ ### What happens when re-running on an existing installation?
146
+
147
+ If an existing Lamaste installation is detected (`/etc/lamalibre/lamaste/panel.json` exists), the installer enters **redeploy mode** by default. This redeploys the panel, CLI, UI, docs and gatekeeper into a root-owned install directory, merges configuration, re-checks the pinned Chisel and Authelia installs, their units and the directory ownership, rewrites the root-owned programs and the sudoers rules, and restarts what changed -- skipping OS hardening, mTLS certificates, and the panel's nginx vhosts. See [Upgrades](../05-operations/upgrades.md). Use `--force-full` to run the complete installation instead.
148
+
149
+ ### Why not use the lamalibre-lamaste-serverd directly on port 9292?
150
+
151
+ nginx handles TLS termination and mTLS verification at the connection level. The lamalibre-lamaste-serverd never sees unauthenticated traffic. This is more secure than implementing TLS in Node.js.