@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.
- package/LICENSE.md +118 -0
- package/README.md +114 -0
- package/bin/create-lamaste.js +15 -0
- package/package.json +54 -0
- package/scripts/bundle-vendor.js +110 -0
- package/scripts/lamaste-cert-info +62 -0
- package/scripts/lamaste-certbot +96 -0
- package/scripts/lamaste-priv +693 -0
- package/src/index.js +646 -0
- package/src/lib/accounts.js +86 -0
- package/src/lib/binaries.js +137 -0
- package/src/lib/cert-help-page.js +160 -0
- package/src/lib/env.js +132 -0
- package/src/lib/http-redirect.js +38 -0
- package/src/lib/ownership.js +231 -0
- package/src/lib/relay-services.js +103 -0
- package/src/lib/secrets.js +19 -0
- package/src/lib/service-config.js +311 -0
- package/src/lib/summary.js +131 -0
- package/src/lib/wrappers.js +63 -0
- package/src/tasks/gatekeeper.js +233 -0
- package/src/tasks/harden.js +293 -0
- package/src/tasks/mtls.js +193 -0
- package/src/tasks/nginx.js +265 -0
- package/src/tasks/node.js +110 -0
- package/src/tasks/panel.js +408 -0
- package/src/tasks/redeploy.js +438 -0
- package/vendor/docs/00-introduction/how-it-works.md +447 -0
- package/vendor/docs/00-introduction/quickstart.md +472 -0
- package/vendor/docs/00-introduction/what-is-lamaste.md +112 -0
- package/vendor/docs/01-concepts/authentication.md +464 -0
- package/vendor/docs/01-concepts/authorization.md +242 -0
- package/vendor/docs/01-concepts/certificates.md +452 -0
- package/vendor/docs/01-concepts/dns-and-domains.md +343 -0
- package/vendor/docs/01-concepts/mtls.md +490 -0
- package/vendor/docs/01-concepts/nginx-reverse-proxy.md +540 -0
- package/vendor/docs/01-concepts/security-model.md +600 -0
- package/vendor/docs/01-concepts/tickets.md +414 -0
- package/vendor/docs/01-concepts/tunneling.md +367 -0
- package/vendor/docs/02-guides/agent-setup.md +194 -0
- package/vendor/docs/02-guides/certificate-management.md +341 -0
- package/vendor/docs/02-guides/cloud-provisioning.md +406 -0
- package/vendor/docs/02-guides/desktop-app-setup.md +226 -0
- package/vendor/docs/02-guides/disaster-recovery.md +464 -0
- package/vendor/docs/02-guides/first-tunnel.md +230 -0
- package/vendor/docs/02-guides/installation.md +393 -0
- package/vendor/docs/02-guides/managing-users.md +255 -0
- package/vendor/docs/02-guides/onboarding.md +244 -0
- package/vendor/docs/02-guides/standalone-plugin-with-tickets.md +375 -0
- package/vendor/docs/02-guides/static-sites.md +364 -0
- package/vendor/docs/03-architecture/e2e-three-vm-sequences.md +457 -0
- package/vendor/docs/03-architecture/installer-flow.md +151 -0
- package/vendor/docs/03-architecture/installer.md +445 -0
- package/vendor/docs/03-architecture/management-flow.md +288 -0
- package/vendor/docs/03-architecture/nginx-configuration.md +830 -0
- package/vendor/docs/03-architecture/onboarding-flow.md +164 -0
- package/vendor/docs/03-architecture/overview.md +541 -0
- package/vendor/docs/03-architecture/panel-client.md +416 -0
- package/vendor/docs/03-architecture/panel-server.md +695 -0
- package/vendor/docs/03-architecture/state-management.md +529 -0
- package/vendor/docs/03-architecture/system-overview.md +167 -0
- package/vendor/docs/04-api-reference/certificates.md +1141 -0
- package/vendor/docs/04-api-reference/gatekeeper.md +592 -0
- package/vendor/docs/04-api-reference/onboarding.md +473 -0
- package/vendor/docs/04-api-reference/overview.md +404 -0
- package/vendor/docs/04-api-reference/services.md +267 -0
- package/vendor/docs/04-api-reference/settings.md +343 -0
- package/vendor/docs/04-api-reference/sites.md +716 -0
- package/vendor/docs/04-api-reference/system.md +268 -0
- package/vendor/docs/04-api-reference/tickets.md +618 -0
- package/vendor/docs/04-api-reference/tunnels.md +417 -0
- package/vendor/docs/04-api-reference/users.md +333 -0
- package/vendor/docs/05-operations/backup-and-restore.md +342 -0
- package/vendor/docs/05-operations/monitoring.md +285 -0
- package/vendor/docs/05-operations/uninstalling.md +344 -0
- package/vendor/docs/05-operations/upgrades.md +270 -0
- package/vendor/docs/06-reference/config-files.md +1080 -0
- package/vendor/docs/06-reference/glossary.md +528 -0
- package/vendor/docs/06-reference/installer-flags.md +260 -0
- package/vendor/docs/06-reference/ports-and-services.md +244 -0
- package/vendor/docs/06-reference/troubleshooting.md +665 -0
- package/vendor/docs/_index.json +233 -0
- package/vendor/docs/gatekeeper-design.md +953 -0
- package/vendor/docs/package.json +15 -0
- package/vendor/docs/todo/lib-cli-desktop-refactor.md +641 -0
- package/vendor/gatekeeper/dist/boot.d.ts +1 -0
- package/vendor/gatekeeper/dist/boot.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/boot.js +17 -0
- package/vendor/gatekeeper/dist/boot.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/access.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/access.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/access.js +33 -0
- package/vendor/gatekeeper/dist/cli/commands/access.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.js +110 -0
- package/vendor/gatekeeper/dist/cli/commands/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.d.ts +2 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.js +98 -0
- package/vendor/gatekeeper/dist/cli/commands/groups.js.map +1 -0
- package/vendor/gatekeeper/dist/cli/index.d.ts +3 -0
- package/vendor/gatekeeper/dist/cli/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/cli/index.js +45 -0
- package/vendor/gatekeeper/dist/cli/index.js.map +1 -0
- package/vendor/gatekeeper/dist/index.d.ts +9 -0
- package/vendor/gatekeeper/dist/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/index.js +13 -0
- package/vendor/gatekeeper/dist/index.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts +16 -0
- package/vendor/gatekeeper/dist/lib/authz.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/authz.js +42 -0
- package/vendor/gatekeeper/dist/lib/authz.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.d.ts +15 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.js +19 -0
- package/vendor/gatekeeper/dist/lib/cache-bust.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/constants.d.ts +82 -0
- package/vendor/gatekeeper/dist/lib/constants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/constants.js +79 -0
- package/vendor/gatekeeper/dist/lib/constants.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts +32 -0
- package/vendor/gatekeeper/dist/lib/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/grants.js +314 -0
- package/vendor/gatekeeper/dist/lib/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/groups.d.ts +10 -0
- package/vendor/gatekeeper/dist/lib/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/groups.js +247 -0
- package/vendor/gatekeeper/dist/lib/groups.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/migration.d.ts +17 -0
- package/vendor/gatekeeper/dist/lib/migration.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/migration.js +79 -0
- package/vendor/gatekeeper/dist/lib/migration.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0001_groups.sql +7 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0002_access_grants.sql +14 -0
- package/vendor/gatekeeper/dist/lib/migrations/gatekeeper/0003_access_request_log.sql +9 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0001_groups.sql +7 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0002_access_grants.sql +14 -0
- package/vendor/gatekeeper/dist/lib/migrations/migrations/gatekeeper/0003_access_request_log.sql +9 -0
- package/vendor/gatekeeper/dist/lib/state-db.d.ts +16 -0
- package/vendor/gatekeeper/dist/lib/state-db.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/state-db.js +154 -0
- package/vendor/gatekeeper/dist/lib/state-db.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts +21 -0
- package/vendor/gatekeeper/dist/lib/templates.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/templates.js +151 -0
- package/vendor/gatekeeper/dist/lib/templates.js.map +1 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts +178 -0
- package/vendor/gatekeeper/dist/lib/types.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/lib/types.js +2 -0
- package/vendor/gatekeeper/dist/lib/types.js.map +1 -0
- package/vendor/gatekeeper/dist/server/index.d.ts +15 -0
- package/vendor/gatekeeper/dist/server/index.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/index.js +251 -0
- package/vendor/gatekeeper/dist/server/index.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.d.ts +7 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.js +17 -0
- package/vendor/gatekeeper/dist/server/routes/access-request.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/authz.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/authz.js +279 -0
- package/vendor/gatekeeper/dist/server/routes/authz.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts +13 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js +249 -0
- package/vendor/gatekeeper/dist/server/routes/diagnostic.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/grants.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/grants.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/grants.js +112 -0
- package/vendor/gatekeeper/dist/server/routes/grants.js.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/groups.d.ts +3 -0
- package/vendor/gatekeeper/dist/server/routes/groups.d.ts.map +1 -0
- package/vendor/gatekeeper/dist/server/routes/groups.js +139 -0
- package/vendor/gatekeeper/dist/server/routes/groups.js.map +1 -0
- package/vendor/gatekeeper/package.json +49 -0
- package/vendor/server/bin/lamaste-server.js +204 -0
- package/vendor/server/package.json +31 -0
- package/vendor/server/src/commands/certs.js +224 -0
- package/vendor/server/src/commands/chisel.js +132 -0
- package/vendor/server/src/commands/logs.js +49 -0
- package/vendor/server/src/commands/plugins.js +321 -0
- package/vendor/server/src/commands/reset-admin.js +478 -0
- package/vendor/server/src/commands/restart.js +94 -0
- package/vendor/server/src/commands/sites.js +257 -0
- package/vendor/server/src/commands/status.js +158 -0
- package/vendor/server/src/commands/tunnels.js +365 -0
- package/vendor/server/src/commands/uninstall.js +326 -0
- package/vendor/server/src/config.js +38 -0
- package/vendor/server/src/exec.js +26 -0
- package/vendor/server/src/logger.js +39 -0
- package/vendor/server/src/ndjson.js +56 -0
- package/vendor/server/src/panel-api.js +85 -0
- package/vendor/server/src/state.js +45 -0
- package/vendor/server-ui/dist/assets/index-B0nWuUyL.js +257 -0
- package/vendor/server-ui/dist/assets/index-BqWWFlTU.css +1 -0
- package/vendor/server-ui/dist/index.html +13 -0
- package/vendor/serverd/package.json +44 -0
- package/vendor/serverd/src/boot.js +13 -0
- package/vendor/serverd/src/index.js +191 -0
- package/vendor/serverd/src/lib/app-error.js +14 -0
- package/vendor/serverd/src/lib/authelia.js +85 -0
- package/vendor/serverd/src/lib/certbot.js +74 -0
- package/vendor/serverd/src/lib/chisel-args.js +6 -0
- package/vendor/serverd/src/lib/chisel-reconcile.js +232 -0
- package/vendor/serverd/src/lib/chisel-runtime.js +46 -0
- package/vendor/serverd/src/lib/chisel-users.js +109 -0
- package/vendor/serverd/src/lib/chisel.js +81 -0
- package/vendor/serverd/src/lib/config.js +190 -0
- package/vendor/serverd/src/lib/constants.js +8 -0
- package/vendor/serverd/src/lib/csr-signing.js +331 -0
- package/vendor/serverd/src/lib/enrollment.js +302 -0
- package/vendor/serverd/src/lib/files.js +19 -0
- package/vendor/serverd/src/lib/gatekeeper-client.js +135 -0
- package/vendor/serverd/src/lib/invite-page.js +281 -0
- package/vendor/serverd/src/lib/ip-utils.js +79 -0
- package/vendor/serverd/src/lib/migrations/state/0001_enrollment_tokens.sql +17 -0
- package/vendor/serverd/src/lib/migrations/state/0002_tickets.sql +70 -0
- package/vendor/serverd/src/lib/migrations/state/0003_plugins.sql +15 -0
- package/vendor/serverd/src/lib/migrations/state/0004_agents.sql +19 -0
- package/vendor/serverd/src/lib/mtls.js +795 -0
- package/vendor/serverd/src/lib/nginx.js +1090 -0
- package/vendor/serverd/src/lib/pki-paths.js +41 -0
- package/vendor/serverd/src/lib/pki-sign.js +103 -0
- package/vendor/serverd/src/lib/plugins.js +538 -0
- package/vendor/serverd/src/lib/push-install.js +390 -0
- package/vendor/serverd/src/lib/revocation.js +112 -0
- package/vendor/serverd/src/lib/services.js +131 -0
- package/vendor/serverd/src/lib/session.js +151 -0
- package/vendor/serverd/src/lib/state-db.js +130 -0
- package/vendor/serverd/src/lib/state.js +140 -0
- package/vendor/serverd/src/lib/storage.js +63 -0
- package/vendor/serverd/src/lib/system-stats.js +58 -0
- package/vendor/serverd/src/lib/tickets.js +1556 -0
- package/vendor/serverd/src/lib/totp.js +76 -0
- package/vendor/serverd/src/lib/tunnel-deps.js +41 -0
- package/vendor/serverd/src/lib/user-access-session.js +142 -0
- package/vendor/serverd/src/lib/user-access.js +52 -0
- package/vendor/serverd/src/middleware/errors.js +63 -0
- package/vendor/serverd/src/middleware/mtls.js +120 -0
- package/vendor/serverd/src/middleware/onboarding-guard.js +30 -0
- package/vendor/serverd/src/middleware/role-guard.js +58 -0
- package/vendor/serverd/src/middleware/twofa-session.js +65 -0
- package/vendor/serverd/src/middleware/user-access-session.js +52 -0
- package/vendor/serverd/src/routes/enrollment.js +120 -0
- package/vendor/serverd/src/routes/health.js +22 -0
- package/vendor/serverd/src/routes/invite.js +163 -0
- package/vendor/serverd/src/routes/management/agents.js +182 -0
- package/vendor/serverd/src/routes/management/certs.js +911 -0
- package/vendor/serverd/src/routes/management/gatekeeper-proxy.js +160 -0
- package/vendor/serverd/src/routes/management/identity.js +107 -0
- package/vendor/serverd/src/routes/management/invitations.js +166 -0
- package/vendor/serverd/src/routes/management/logs.js +218 -0
- package/vendor/serverd/src/routes/management/plugins.js +560 -0
- package/vendor/serverd/src/routes/management/services.js +63 -0
- package/vendor/serverd/src/routes/management/settings.js +325 -0
- package/vendor/serverd/src/routes/management/sites.js +522 -0
- package/vendor/serverd/src/routes/management/storage.js +192 -0
- package/vendor/serverd/src/routes/management/system.js +201 -0
- package/vendor/serverd/src/routes/management/tickets.js +457 -0
- package/vendor/serverd/src/routes/management/tunnels.js +709 -0
- package/vendor/serverd/src/routes/management/users.js +377 -0
- package/vendor/serverd/src/routes/management.js +36 -0
- package/vendor/serverd/src/routes/onboarding/dns.js +101 -0
- package/vendor/serverd/src/routes/onboarding/domain.js +42 -0
- package/vendor/serverd/src/routes/onboarding/index.js +18 -0
- package/vendor/serverd/src/routes/onboarding/provision.js +327 -0
- package/vendor/serverd/src/routes/onboarding/status.js +12 -0
- package/vendor/serverd/src/routes/plugin-router.js +79 -0
- package/vendor/serverd/src/routes/user-access.js +389 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# Authorization (Gatekeeper)
|
|
2
|
+
|
|
3
|
+
> Gatekeeper is a lightweight Fastify service on `127.0.0.1:9294` that sits between Authelia (authentication) and tunnel backends, acting as an nginx `auth_request` target for fine-grained access control. Authelia determines WHO you are; Gatekeeper determines WHAT you can access.
|
|
4
|
+
|
|
5
|
+
## In Plain English
|
|
6
|
+
|
|
7
|
+
Lamaste already has a front door guard (Authelia) who checks your ID and lets you into the building. Gatekeeper is the hallway guard who checks whether you are allowed into a specific room.
|
|
8
|
+
|
|
9
|
+
Without Gatekeeper, every authenticated user can access every tunneled app. That is fine when all your users are trusted, but once you expose apps to different teams, clients, or the public, you need to control who sees what. Gatekeeper adds that control without replacing Authelia — the two work together.
|
|
10
|
+
|
|
11
|
+
When a visitor requests a tunneled app, nginx first asks Authelia "is this person logged in?" and then asks Gatekeeper "is this person allowed to access this specific tunnel?" Only if both answer yes does nginx proxy the request through.
|
|
12
|
+
|
|
13
|
+
There are three access modes for tunnels:
|
|
14
|
+
|
|
15
|
+
- **Public** — no authentication at all. nginx proxies directly to the backend.
|
|
16
|
+
- **Authenticated** — Authelia login required. Any authenticated user passes through.
|
|
17
|
+
- **Restricted** — Authelia login required, then Gatekeeper checks for a specific grant. If the user does not have one, they see a friendly 403 page with pre-filled message templates to request access.
|
|
18
|
+
|
|
19
|
+
## For Users
|
|
20
|
+
|
|
21
|
+
### Dual group system
|
|
22
|
+
|
|
23
|
+
Lamaste has two separate group systems that serve different purposes:
|
|
24
|
+
|
|
25
|
+
**Authelia groups** are identity-tier groups stored in `users.yml` and managed through the Users page. These are broad categories that describe who a user is:
|
|
26
|
+
|
|
27
|
+
| Group | Purpose |
|
|
28
|
+
| ---------- | ------------------------------------------ |
|
|
29
|
+
| `admins` | Server administrators |
|
|
30
|
+
| `internal` | Internal team members |
|
|
31
|
+
| `external` | External collaborators, clients, or guests |
|
|
32
|
+
|
|
33
|
+
**Lamaste groups** are access-control groups stored in `groups.json` and managed through the Gatekeeper dashboard. These are project-oriented groups that describe what a user can access:
|
|
34
|
+
|
|
35
|
+
| Example group | Members |
|
|
36
|
+
| -------------- | ----------------- |
|
|
37
|
+
| `developers` | alice, bob |
|
|
38
|
+
| `design-team` | carol, dave |
|
|
39
|
+
| `beta-testers` | alice, carol, eve |
|
|
40
|
+
|
|
41
|
+
The distinction matters because identity rarely maps cleanly to access. Alice might be an `internal` team member (Authelia group) who is on both the `developers` and `beta-testers` groups (Lamaste groups). Bob might be `external` but still in the `developers` group for a specific project.
|
|
42
|
+
|
|
43
|
+
Authelia groups are used for broad policy (e.g., all internal users can reach the intranet). Lamaste groups are used for fine-grained access control (e.g., only the design-team can reach the Figma proxy).
|
|
44
|
+
|
|
45
|
+
### Grants
|
|
46
|
+
|
|
47
|
+
Access is controlled through grants. A grant connects a principal (a user or a group) to a resource (a tunnel, a plugin, or any custom resource type).
|
|
48
|
+
|
|
49
|
+
For example:
|
|
50
|
+
|
|
51
|
+
- "User `alice` can access tunnel `staging-app`"
|
|
52
|
+
- "Group `developers` can access tunnel `api-docs`"
|
|
53
|
+
- "User `bob` can access plugin `herd`"
|
|
54
|
+
|
|
55
|
+
When a group is the principal, the grant expands to all members of that group at check time. If you add a new member to the `developers` group, they immediately gain access to everything granted to `developers` — no need to create individual grants.
|
|
56
|
+
|
|
57
|
+
Grants are not tunnel-specific. The resource model is generic: each grant has a resource type (e.g., `tunnel`, `plugin`) and a resource identifier. This means the same grant system works for tunnels, plugins, and any future resource types.
|
|
58
|
+
|
|
59
|
+
### Access modes for tunnels
|
|
60
|
+
|
|
61
|
+
Each tunnel can be configured with one of three access modes:
|
|
62
|
+
|
|
63
|
+
**Public.** No authentication. nginx proxies requests directly to the backend without involving Authelia or Gatekeeper. Use this for public-facing services like a marketing site or a public API.
|
|
64
|
+
|
|
65
|
+
**Authenticated.** Authelia login required, but no grant check. Any user who can log in through Authelia can access the tunnel. Use this for internal services where everyone on the team should have access.
|
|
66
|
+
|
|
67
|
+
**Restricted.** Authelia login required, and Gatekeeper checks for a matching grant. If the user has a grant (directly or through a group), the request passes through. If not, the user sees a 403 access request page. Use this for sensitive services that only specific people or teams should reach.
|
|
68
|
+
|
|
69
|
+
### Access request pages
|
|
70
|
+
|
|
71
|
+
When a user hits a restricted tunnel without a grant, they do not see a generic "403 Forbidden" error. Instead, Gatekeeper returns a user-friendly HTML page that explains they do not have access and offers pre-filled message templates for requesting it:
|
|
72
|
+
|
|
73
|
+
- **Email** — a mailto link with a pre-filled subject and body addressed to the admin
|
|
74
|
+
- **Slack** — a copy-ready message formatted for Slack
|
|
75
|
+
- **Teams** — a copy-ready message formatted for Microsoft Teams
|
|
76
|
+
- **WhatsApp** — a copy-ready message formatted for WhatsApp
|
|
77
|
+
- **Generic** — a plain-text message suitable for any other channel
|
|
78
|
+
|
|
79
|
+
The templates include the user's name, the resource they tried to access, and a timestamp, so the admin receives all the context needed to create a grant.
|
|
80
|
+
|
|
81
|
+
### Managing groups and grants
|
|
82
|
+
|
|
83
|
+
From the Gatekeeper dashboard in the admin panel:
|
|
84
|
+
|
|
85
|
+
1. **Groups** — create Lamaste groups and add members (by Authelia username)
|
|
86
|
+
2. **Grants** — create grants connecting users or groups to resources
|
|
87
|
+
3. **Access Requests** — review incoming access requests from users who hit 403 pages
|
|
88
|
+
4. **Settings** — configure default access modes and other Gatekeeper behavior
|
|
89
|
+
|
|
90
|
+
### How changes take effect
|
|
91
|
+
|
|
92
|
+
Gatekeeper watches its state files (`groups.json`, `access-grants.json`) for changes. When you create a group, add a member, or create a grant through the admin panel, the change takes effect immediately — no service restart required.
|
|
93
|
+
|
|
94
|
+
## For Developers
|
|
95
|
+
|
|
96
|
+
### Architecture
|
|
97
|
+
|
|
98
|
+
Gatekeeper runs as an independent Fastify service on `127.0.0.1:9294`. nginx uses `auth_request` to delegate authorization decisions to it, similar to how Authelia handles authentication via the same pattern.
|
|
99
|
+
|
|
100
|
+
The request flow for a restricted tunnel:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
1. Visitor requests staging.example.com
|
|
104
|
+
2. nginx sends auth_request to Authelia (127.0.0.1:9091)
|
|
105
|
+
3. Authelia validates session cookie:
|
|
106
|
+
a. No valid session -> 401 -> nginx redirects to auth.example.com
|
|
107
|
+
b. Valid session -> 200 with Remote-User/Remote-Groups headers
|
|
108
|
+
4. nginx sends auth_request to Gatekeeper (127.0.0.1:9294)
|
|
109
|
+
- Forwards Remote-User, Remote-Groups, and Host headers
|
|
110
|
+
5. Gatekeeper checks for a matching grant:
|
|
111
|
+
a. Grant exists (user or group match) -> 200
|
|
112
|
+
b. No grant -> 403 with access request HTML page
|
|
113
|
+
6. If both return 200: nginx proxies to the tunnel backend
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For public tunnels, nginx skips both auth_request directives. For authenticated tunnels, nginx uses only the Authelia auth_request and skips Gatekeeper.
|
|
117
|
+
|
|
118
|
+
### Grant model
|
|
119
|
+
|
|
120
|
+
The grant model is generic, not tunnel-specific:
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
{
|
|
124
|
+
grantId: 'g_abc123', // unique identifier
|
|
125
|
+
principalType: 'user', // 'user' or 'group'
|
|
126
|
+
principalId: 'alice', // username or group name
|
|
127
|
+
resourceType: 'tunnel', // 'tunnel', 'plugin', or custom
|
|
128
|
+
resourceId: 'staging-app', // resource identifier
|
|
129
|
+
context: {}, // optional metadata
|
|
130
|
+
used: false, // whether grant has been consumed
|
|
131
|
+
createdAt: '2026-04-01T...',
|
|
132
|
+
usedAt: null // consumption timestamp, or null
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
At authorization check time, Gatekeeper resolves the request in two steps:
|
|
137
|
+
|
|
138
|
+
1. **Direct match** — is there a grant where `principalType === 'user'` and `principalId` matches the `Remote-User` header?
|
|
139
|
+
2. **Group expansion** — for each Lamaste group the user belongs to, is there a grant where `principalType === 'group'` and `principalId` matches the group name?
|
|
140
|
+
|
|
141
|
+
If either step finds a matching grant for the requested resource, the check passes.
|
|
142
|
+
|
|
143
|
+
### Session caching
|
|
144
|
+
|
|
145
|
+
Authorization checks happen on every request to a restricted tunnel. A page load can trigger dozens or hundreds of subrequests (HTML, CSS, JS, images, API calls). Without caching, each subrequest would hit Authelia and Gatekeeper, creating unnecessary load.
|
|
146
|
+
|
|
147
|
+
Gatekeeper uses an in-memory session cache to solve this:
|
|
148
|
+
|
|
149
|
+
**Gatekeeper in-memory session cache.** When Gatekeeper receives a request, it extracts the user identity from the Authelia session. Validated sessions are cached in memory for 30 seconds (configurable via `sessionCacheTtlMs` in `gatekeeper.json`), keyed by the session cookie value. This means repeated Gatekeeper calls for the same session do not re-validate against Authelia.
|
|
150
|
+
|
|
151
|
+
> **Note:** The installer also writes an nginx `proxy_cache_path` snippet (`/etc/nginx/snippets/lamalibre-lamaste-authz-cache.conf`) for optional nginx-level caching, but the generated vhosts do not currently include `proxy_cache` directives. All authorization caching relies on the Gatekeeper's in-memory session cache.
|
|
152
|
+
|
|
153
|
+
**Effect:** On a warm cache, repeated subrequests for the same session are resolved from the in-memory cache without re-validating against Authelia. The 30-second default TTL ensures that revoked grants and expired sessions take effect within half a minute.
|
|
154
|
+
|
|
155
|
+
### File watching
|
|
156
|
+
|
|
157
|
+
Gatekeeper watches its state files using `fs.watch`:
|
|
158
|
+
|
|
159
|
+
| File | Contains |
|
|
160
|
+
| -------------------- | -------------------------------- |
|
|
161
|
+
| `groups.json` | Lamaste groups and their members |
|
|
162
|
+
| `access-grants.json` | All grants (user and group) |
|
|
163
|
+
|
|
164
|
+
When a file changes, Gatekeeper reloads its in-memory state and invalidates the session cache. This means changes made through the admin panel API (which writes to these files atomically) take effect immediately without restarting the Gatekeeper service.
|
|
165
|
+
|
|
166
|
+
State files use the same atomic write pattern as the rest of Lamaste (temp file with `O_EXCL` + mode `0600` -> `fsync` -> rename).
|
|
167
|
+
|
|
168
|
+
### Access request page generation
|
|
169
|
+
|
|
170
|
+
When Gatekeeper denies a request (no matching grant), it returns a 403 response with an HTML page instead of a bare status code. The page is generated from templates in `packages/lamaste-gatekeeper/src/lib/templates.ts` and includes:
|
|
171
|
+
|
|
172
|
+
- The username (from `Remote-User` header)
|
|
173
|
+
- The resource they attempted to access (from `Host` header)
|
|
174
|
+
- A human-readable timestamp
|
|
175
|
+
- Pre-filled message templates for email (mailto link), Slack, Teams, WhatsApp, and a generic plain-text format
|
|
176
|
+
|
|
177
|
+
The HTML is self-contained (inline CSS, no external dependencies) so it renders correctly even when all other assets are blocked by the 403.
|
|
178
|
+
|
|
179
|
+
### State files
|
|
180
|
+
|
|
181
|
+
| File | Purpose | Format |
|
|
182
|
+
| ------------------------------------------- | -------------------------- | ------ |
|
|
183
|
+
| `/etc/lamalibre/lamaste/groups.json` | Lamaste groups and members | JSON |
|
|
184
|
+
| `/etc/lamalibre/lamaste/access-grants.json` | All grants | JSON |
|
|
185
|
+
|
|
186
|
+
### Source files
|
|
187
|
+
|
|
188
|
+
| File | Purpose |
|
|
189
|
+
| -------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
190
|
+
| `packages/lamaste-gatekeeper/src/server/index.ts` | Fastify server setup, file watching |
|
|
191
|
+
| `packages/lamaste-gatekeeper/src/server/routes/authz.ts` | Authorization check endpoint (nginx auth_request) |
|
|
192
|
+
| `packages/lamaste-gatekeeper/src/server/routes/grants.ts` | Grant CRUD API |
|
|
193
|
+
| `packages/lamaste-gatekeeper/src/server/routes/groups.ts` | Group CRUD API |
|
|
194
|
+
| `packages/lamaste-gatekeeper/src/server/routes/access-request.ts` | Access request submission and listing |
|
|
195
|
+
| `packages/lamaste-gatekeeper/src/lib/authz.ts` | Authorization logic (grant matching, group expansion) |
|
|
196
|
+
| `packages/lamaste-gatekeeper/src/lib/grants.ts` | Grant storage and atomic writes |
|
|
197
|
+
| `packages/lamaste-gatekeeper/src/lib/groups.ts` | Group storage and atomic writes |
|
|
198
|
+
| `packages/lamaste-gatekeeper/src/lib/templates.ts` | Access request HTML page generation |
|
|
199
|
+
| `packages/lamaste-serverd/src/routes/management/gatekeeper-proxy.js` | Admin panel proxy to Gatekeeper API |
|
|
200
|
+
| `packages/lamaste-serverd/src/lib/nginx.js` | Vhost generation with Gatekeeper auth_request block |
|
|
201
|
+
|
|
202
|
+
## Quick Reference
|
|
203
|
+
|
|
204
|
+
### Service
|
|
205
|
+
|
|
206
|
+
| Property | Value |
|
|
207
|
+
| ----------- | ---------------------------------------------------------------- |
|
|
208
|
+
| Listen | `127.0.0.1:9294` |
|
|
209
|
+
| Runtime | Fastify (TypeScript) |
|
|
210
|
+
| State files | `groups.json`, `access-grants.json` in `/etc/lamalibre/lamaste/` |
|
|
211
|
+
| RAM usage | Minimal (in-process) |
|
|
212
|
+
|
|
213
|
+
### Access modes
|
|
214
|
+
|
|
215
|
+
| Mode | Authelia | Gatekeeper | Who can access |
|
|
216
|
+
| ------------- | -------- | ---------- | --------------------------- |
|
|
217
|
+
| Public | No | No | Anyone on the internet |
|
|
218
|
+
| Authenticated | Yes | No | Any logged-in Authelia user |
|
|
219
|
+
| Restricted | Yes | Yes | Users with a matching grant |
|
|
220
|
+
|
|
221
|
+
### Cache TTLs
|
|
222
|
+
|
|
223
|
+
| Layer | TTL | Key |
|
|
224
|
+
| ---------------------------- | --- | -------------------- |
|
|
225
|
+
| Gatekeeper in-memory session | 30s | Session cookie value |
|
|
226
|
+
|
|
227
|
+
### Group comparison
|
|
228
|
+
|
|
229
|
+
| Property | Authelia groups | Lamaste groups |
|
|
230
|
+
| ----------- | -------------------------------- | -------------------------------------- |
|
|
231
|
+
| Purpose | Identity classification | Access control |
|
|
232
|
+
| Storage | `users.yml` | `groups.json` |
|
|
233
|
+
| Managed by | Authelia (via panel Users page) | Gatekeeper (via panel Gatekeeper page) |
|
|
234
|
+
| Examples | `admins`, `internal`, `external` | `developers`, `design-team` |
|
|
235
|
+
| Granularity | Broad (who you are) | Fine (what you access) |
|
|
236
|
+
|
|
237
|
+
### Related documentation
|
|
238
|
+
|
|
239
|
+
- [Authentication](authentication.md) — Authelia TOTP 2FA and the forward-auth pattern that Gatekeeper builds upon
|
|
240
|
+
- [nginx Reverse Proxy](nginx-reverse-proxy.md) — auth_request configuration and vhost generation
|
|
241
|
+
- [Security Model](security-model.md) — authorization as part of defense-in-depth
|
|
242
|
+
- [Tunneling](tunneling.md) — tunnel types and access modes
|