Access model
This part gives the persons and the components that have access to the state of the system, and the limits of that access.
The tables that have the label "generated" come from the code at each build of the documentation (core/docs/md/technical-design/access-model.nix).
The threats and the controls are in the threat model.
Actors
| Actor | Definition | Where the identity is |
|---|---|---|
| Hosting provider | The organization that runs the software of this repository for its customers (Actors). | It has no account of its own. Its persons are staff and administrators. |
| Staff | A person of the hosting provider who reads the telemetry. | A user in the lldap of the hosting provider, with the group fediversity-staff. |
| Administrator | A person of the hosting provider who can administer the nodes and the shared services. | A user in the lldap of the hosting provider, with the group fediversity-admins. The person logs in to the shared account admin with a short-lived SSH certificate. When no certificate is available, the holder of the offline key of ADMIN_EMERGENCY can log in to the account emergency (core/setups/nixos/users.nix). |
| Panel superuser | An account of the panel that can see and assign the domains of all operators. | A User of the panel with is_superuser. Each SSO login sets this flag and is_staff from the groups claim: a member of fediversity-admins gets them, a different user loses them (superuserGroups in panel/nix/component/oidc.nix, sync_superuser in panel/src/panel/oidc.py). A password login does not change them. |
| Deployer | A program or a person that applies a configuration to the nodes: the CD workflows, an administrator on a workstation, and the front end (the api and Windmill), which deploys the deployments of the operators. | An OpenBao token with the policy fediversity-deployer (CD and workstation) or fediversity-operator-deployer (front end), and a user of the state backend: cd, workstation-<person> or operator (core/components/hosting-provider/terraform-backend/front.nix). |
| Operator | A customer of the hosting provider, who configures and deploys applications through the panel. | A User in the database of the panel. The log-in is with a local password, or with OpenID Connect when the hosting provider sets the OIDC_* settings (panel/src/panel/settings.py). |
| Tenant | One deployment of an operator, as an owner of names in a shared service. The code calls the name of a tenant the namespace of the deployment. | The namespace is in the name of each node of the deployment and in the certificate that SPIRE gives the node. |
| Application user | A person who uses an application of an operator. | An account in the application. Each deployment has its own lldap and authelia nodes for single sign-on (core/setups/groups/operator.nix). |
| Node | A machine of the hosting provider or of a deployment. | A certificate (SVID) from SPIRE. OpenBao gives the node the policy host-<name> (core/components/hosting-provider/openbao/spire-auth.nix). |
Permissions of each role
In the panel
The panel has three levels of access.
- A visitor without an account can read the public pages.
- An operator can read and change only the deployments for which
Deployment.operatoris the account of the operator (panel/src/panel/models.py). The views filter on this field. - A superuser has the access of an operator.
A superuser can also list, claim and assign domains for all operators, and can read the audit history of each account (
reads_all_historyand_AUTHZ_SUPERUSER_PROCEDURESinpanel/src/panel/views.py).
The admin site of Django (/admin/) shows only the User model (panel/src/panel/admin.py).
The views of the panel do not use is_staff.
The directory groups fediversity-staff and fediversity-admins give no permission in the panel.
In the api
The api does not keep accounts and does not decide on access.
For each request, the api sends the name of the procedure, the scope and the headers to the authorization callback of the panel (authorize in api/src/fediversity_api/authz.py, AuthzCallback in panel/src/panel/views.py).
The callback accepts a request only with the callback token of the api (AUTHZ_CALLBACK_TOKEN), when that token is set.
The panel identifies the requester from a bearer token that the panel signed, which stays valid for API_TOKEN_TTL seconds (panel/src/panel/tokens.py).
| Requester | Procedures that the callback permits |
|---|---|
| No account | AUTHZ_PUBLIC_PROCEDURES: the schema, the list of applications and their icons, the configuration sections and the domain terms. |
| Operator | The procedures of AUTHZ_PROCEDURE_RULES, only for its own deployments, its own domain contact and its own audit events. |
| Superuser | The same, and domain_assign. domain_list and domain_claim apply to the deployments of all operators. |
| Service token | A request with the service token of the api (API_SERVICE_TOKEN) is an internal call. The callback then decides for the user that the request names. domain_terms_notice accepts only such a call (api/src/fediversity_api/routes/domains.py). |
The callback denies a procedure that is not in AUTHZ_PROCEDURE_RULES.
Without a callback URL, the api starts only when API_AUTHZ_ALLOW_ALL is set, and then it permits each request.
Directory groups of the hosting provider
The groups are in the lldap of the hosting provider. The section Manage users and groups of the hosting-provider guide tells how to give a group to a user.
| Service | fediversity-staff |
fediversity-admins |
Source |
|---|---|---|---|
| Grafana of the hosting provider | The Viewer role. Grafana has one organization, thus a viewer can read the telemetry of all deployments. |
The Admin role. |
core/components/hosting-provider/telemetry/ |
| OpenBao | None. | The policy fediversity-admins: read of the full KV. With ADMIN_UI_WRITE=1, also write and delete. |
core/components/hosting-provider/openbao/oidc.nix |
| OpenBao, deploy token | None. | A token with the policy fediversity-deployer. |
core/components/hosting-provider/openbao/oidc.nix |
| SSH to the nodes | None. | A certificate for the shared account admin, which is in wheel. Each node accepts the certificate when ADMIN_SSH_CA_KEYS is set. |
core/components/hosting-provider/openbao/ssh-certificates.nix, core/setups/nixos/users.nix |
| Incus | None. | Administrator of all containers. The authorization scriptlet of Incus refuses an OIDC user outside the group. | core/components/hosting-provider/incus/default.nix |
| Windmill | None. | The UI, from which a person starts and cancels deployments. | core/components/hosting-provider/windmill/default.nix |
pgweb |
None. | The UI, which connects as the postgres superuser. A member can read the databases of all deployments. |
core/components/hosting-provider/postgresql/default.nix |
| UI of Valkey | None. | The UI. | core/components/shared/valkey/default.nix |
| UI of Garage | None. | The UI, only when ADMIN_UI_WRITE=1. |
core/components/hosting-provider/garage/default.nix |
When ADMIN_SOURCES is set, the firewall of each node accepts the administrative ports (port 22 by default) only from those addresses (core/resources/firewall/default.nix).
An operator gets no shell access to the nodes of its deployment.
The persons who can read each log, trace and audit channel are in Logs, traces and audit records.
Application roles
Each deployment of an operator has its own lldap, with the same group names.
The lldap of a deployment has the groups application-admins and application-moderators (core/resources/ldap/application-role-groups.nix), and the groups of each application.
Each application gives a role to the members of a group at log-in.
The Grafana of a deployment accepts the members of fediversity-admins in the lldap of that deployment (core/components/operator/grafana/oidc.nix).
Generated from the role-groups.nix file of each application in core/components/operator/:
| Application | Directory group | Role in the application | The first administrator is a member |
|---|---|---|---|
mastodon |
mastodon-owners |
Owner |
yes |
mastodon |
application-admins |
Admin |
yes |
mastodon |
mastodon-admins |
Admin |
no |
mastodon |
application-moderators |
Moderator |
no |
mastodon |
mastodon-moderators |
Moderator |
no |
peertube |
application-admins |
0 |
yes |
peertube |
peertube-admins |
0 |
no |
peertube |
application-moderators |
1 |
no |
peertube |
peertube-moderators |
1 |
no |
pixelfed |
application-admins |
admin |
yes |
pixelfed |
pixelfed-admins |
admin |
no |
Access of each component to each store
The tables in this section are generated from the configuration of the nodes, with the groups of core/testers/groups.nix.
That evaluation knows no deployment.
Thus <own deployment> shows where a name has the namespace of the deployment of the node, and <each deployment> shows a path that applies to all deployments.
Secrets in the KV of OpenBao
Each node logs in to OpenBao with its SPIRE certificate and gets the policy host-<name>.
The entries of the hosting provider are below secret/data/vars/.
The entries of a deployment are below secret/data/vars/operator-deployments/<namespace>/.
Each entry has a public half and a secret half.
The credentials register gives the lifetime and the rotation of each credential.
The table gives the name of the entry when a policy has the same capabilities on the two halves, and <half>/<entry> when it has them on one half.
The table gives a grant on secret/metadata/ only when the policy has no grant on the data of the same entry.
| Policy | Scope | Capabilities | Entries |
|---|---|---|---|
fediversity-admins |
not in vars |
read | * |
fediversity-deployer |
hosting provider | create, read, update | secret/deployer/adminSources, secret/deployer/dnsApiToken, secret/deployer/netboxApiToken, secret/deployer/openproviderPassword, secret/deployer/openproviderUsername, secret/deployer/zonesManagerToken, secret/smarthost-upstream |
fediversity-deployer |
hosting provider | read | secret/incus-store, secret/netbox, secret/octodns, public/* |
fediversity-operator-deployer |
<each deployment> |
create, read, update, delete, list | authelia-backups-s3, secret/authelia-operator-secrets, desec-zone, domain-claims, lldap-backups-s3, mastodon-backups-s3, secret/mastodon-operator-secrets, mastodon-s3, migration, operator-authelia-cache-backups-s3, operator-mastodon-cache-backups-s3, operator-peertube-cache-backups-s3, operator-pixelfed-cache-backups-s3, operator-valkey-cache-backups-s3, peertube-backups-s3, peertube-s3, pixelfed-backups-s3, secret/pixelfed-operator-secrets, pixelfed-s3 |
fediversity-operator-deployer |
<each deployment> |
deny | secret/authelia-backups-restic, secret/ldap-key-operator, secret/lldap-backups-restic, secret/mastodon-backups-restic, secret/mastodon-keys, secret/mastodon-media-backup, secret/operator-authelia-cache-backups-restic, secret/operator-authelia-oidc, secret/operator-mastodon-cache-backups-restic, secret/operator-peertube-cache-backups-restic, secret/operator-pixelfed-cache-backups-restic, secret/operator-valkey-cache-backups-restic, secret/peertube-backups-restic, secret/peertube-media-backup, secret/peertube-secret, secret/pixelfed-app, secret/pixelfed-backups-restic, secret/pixelfed-media-backup, secret/pixelfed-passport |
fediversity-operator-deployer |
<each deployment> |
metadata only: list, delete | * |
fediversity-operator-deployer |
<each deployment> |
read | public/* |
fediversity-operator-deployer |
hosting provider | create, read, update, delete, list | authelia-backups-s3, desec-zone, domain-claims, lldap-backups-s3, mastodon-backups-s3, mastodon-s3, operator-authelia-cache-backups-s3, operator-mastodon-cache-backups-s3, operator-peertube-cache-backups-s3, operator-pixelfed-cache-backups-s3, operator-valkey-cache-backups-s3, peertube-backups-s3, peertube-s3, pixelfed-backups-s3, pixelfed-s3 |
fediversity-operator-deployer |
hosting provider | metadata only: read | secret/smarthost-upstream |
fediversity-operator-deployer |
hosting provider | read | secret/netbox, secret/postgresql-admin, public/* |
fediversity-operator-deployer |
not in vars |
metadata only: create | retained-backups/* |
host-authelia |
hosting provider | create, read, update, delete, list | authelia-backups-restic, authelia-oidc, authelia-session |
host-authelia |
hosting provider | read | authelia-backups-s3, secret/smtp |
host-bind |
hosting provider | create, read, update, delete, list | acme-dns, bind-backups-restic, dnssec, octodns, operator-dns |
host-bind |
hosting provider | read | secret/authelia-oidc, bind-backups-s3 |
host-garage |
<each deployment> |
metadata only: read, list, delete | authelia-backups-restic, ldap-key-operator, lldap-backups-restic, mastodon-backups-restic, mastodon-keys, mastodon-media-backup, operator-authelia-cache-backups-restic, operator-authelia-oidc, operator-mastodon-cache-backups-restic, operator-peertube-cache-backups-restic, operator-pixelfed-cache-backups-restic, operator-valkey-cache-backups-restic, peertube-backups-restic, peertube-media-backup, peertube-secret, pixelfed-app, pixelfed-backups-restic, pixelfed-media-backup, pixelfed-passport |
host-garage |
hosting provider | create, read, update, delete, list | authelia-backups-s3, bind-backups-s3, garage-admin, grafana-backups-s3, hosting-provider-authelia-cache-backups-s3, hosting-provider-valkey-cache-backups-s3, lldap-backups-s3, netbox-backups-s3, openbao-backups-s3, postgresql-backups-s3, terraform-backend-backups-s3, windmill-backups-s3 |
host-garage |
hosting provider | read | secret/acme-dns, secret/authelia-oidc, telemetry-s3 |
host-garage |
not in vars |
metadata only: read, list, delete | retained-backups/* |
host-incus |
hosting provider | create, read, update, delete, list | incus-deploy, incus-store |
host-incus |
hosting provider | read | secret/authelia-oidc |
host-lldap |
hosting provider | create, read, update, delete, list | ldap-bind-hosting-provider, ldap-jwt-hosting-provider, ldap-key-hosting-provider, lldap-backups-restic |
host-lldap |
hosting provider | read | secret/authelia-oidc, lldap-backups-s3, secret/smtp |
host-netbox |
hosting provider | create, read, update, delete, list | netbox, netbox-backups-restic |
host-netbox |
hosting provider | read | secret/authelia-oidc, netbox-backups-s3, secret/smtp |
host-openbao |
hosting provider | read | secret/authelia-oidc, openbao-backups-s3, secret/postgresql-admin |
host-operator-authelia |
<own deployment> |
create, read, update, delete, list | authelia-backups-restic, authelia-session, operator-authelia-oidc |
host-operator-authelia |
<own deployment> |
read | authelia-backups-s3, secret/authelia-operator-secrets, secret/node-telemetry, secret/operator-smtp |
host-operator-grafana |
<own deployment> |
create, read, update, delete, list | grafana-secret, metrics-query, node-telemetry |
host-operator-grafana |
<own deployment> |
read | secret/operator-authelia-oidc |
host-operator-lldap |
<own deployment> |
create, read, update, delete, list | ldap-bind-operator, ldap-jwt-operator, ldap-key-operator, ldap-roles-operator, lldap-backups-restic |
host-operator-lldap |
<own deployment> |
read | lldap-backups-s3, secret/node-telemetry, secret/operator-authelia-oidc, secret/operator-smtp |
host-operator-mastodon |
<own deployment> |
create, read, update, delete, list | mastodon-backups-restic, mastodon-keys, mastodon-media-backup, metrics |
host-operator-mastodon |
<own deployment> |
read | secret/ldap-roles-operator, mastodon-backups-s3, secret/mastodon-operator-secrets, mastodon-s3, secret/node-telemetry, secret/operator-authelia-oidc, secret/operator-smtp |
host-operator-peertube |
<own deployment> |
create, read, update, delete, list | metrics, peertube-backups-restic, peertube-media-backup, peertube-secret |
host-operator-peertube |
<own deployment> |
read | secret/ldap-roles-operator, secret/node-telemetry, secret/operator-authelia-oidc, secret/operator-smtp, peertube-backups-s3, peertube-s3 |
host-operator-pixelfed |
<own deployment> |
create, read, update, delete, list | metrics, pixelfed-app, pixelfed-app-previous, pixelfed-backups-restic, pixelfed-media-backup, pixelfed-passport |
host-operator-pixelfed |
<own deployment> |
read | secret/ldap-roles-operator, secret/node-telemetry, secret/operator-authelia-oidc, secret/operator-smtp, pixelfed-backups-s3, secret/pixelfed-operator-secrets, pixelfed-s3 |
host-operator-smtp |
<own deployment> |
create, read, update, delete, list | operator-smtp, operator-smtp-dkim |
host-operator-smtp |
<own deployment> |
read | secret/node-telemetry, secret/operator-authelia-oidc |
host-operator-smtp |
hosting provider | read | secret/smarthost-upstream |
host-operator-valkey |
<own deployment> |
create, read, update, delete, list | operator-authelia-cache-backups-restic, operator-mastodon-cache-backups-restic, operator-peertube-cache-backups-restic, operator-pixelfed-cache-backups-restic, operator-valkey-cache-backups-restic, valkey-operator-authelia, valkey-operator-mastodon, valkey-operator-peertube, valkey-operator-pixelfed, valkey-operator-valkey |
host-operator-valkey |
<own deployment> |
read | secret/node-telemetry, operator-authelia-cache-backups-s3, secret/operator-authelia-oidc, operator-mastodon-cache-backups-s3, operator-peertube-cache-backups-s3, operator-pixelfed-cache-backups-s3, operator-valkey-cache-backups-s3 |
host-otel-collector |
metadata only: list | `` | |
host-otel-collector |
<each deployment> |
read | public/metrics |
host-otel-collector |
hosting provider | read | secret/authelia-oidc, secret/telemetry-ingest |
host-postgresql |
hosting provider | create, read, update, delete, list | postgresql-admin, postgresql-backups-restic |
host-postgresql |
hosting provider | read | secret/authelia-oidc, postgresql-backups-s3 |
host-smtp |
hosting provider | create, read, update, delete, list | smtp, smtp-dkim |
host-smtp |
hosting provider | read | secret/authelia-oidc, secret/smarthost-upstream |
host-telemetry |
metadata only: list | `` | |
host-telemetry |
<each deployment> |
read | public/metrics-query/htpasswd, public/node-telemetry/htpasswd |
host-telemetry |
hosting provider | create, read, update, delete, list | audit-ingest-api, grafana-backups-restic, telemetry-grafana, telemetry-grafana-previous, telemetry-ingest, telemetry-s3 |
host-telemetry |
hosting provider | read | secret/authelia-oidc, grafana-backups-s3, secret/smtp |
host-terraform-backend |
hosting provider | create, read, update, delete, list | terraform-backend-operator |
host-terraform-backend |
hosting provider | read | secret/authelia-oidc, terraform-backend-backups-s3 |
host-valkey |
hosting provider | create, read, update, delete, list | hosting-provider-authelia-cache-backups-restic, hosting-provider-valkey-cache-backups-restic, valkey-hosting-provider-authelia, valkey-hosting-provider-valkey |
host-valkey |
hosting provider | read | secret/authelia-oidc, hosting-provider-authelia-cache-backups-s3, hosting-provider-valkey-cache-backups-s3 |
host-windmill |
hosting provider | create, read, update, delete, list | windmill, windmill-backups-restic, windmill-superadmin |
host-windmill |
hosting provider | read | secret/authelia-oidc, public/domain-claims, secret/incus-deploy, secret/incus-store, secret/operator-dns, secret/deployer/adminSources, secret/deployer/dnsApiToken, secret/deployer/netboxApiToken, secret/deployer/openbaoToken, secret/deployer/openproviderPassword, secret/deployer/openproviderUsername, secret/garage-admin/adminToken, secret/terraform-backend-operator/password, secret/smtp, windmill-backups-s3 |
The policy fediversity-admins in this table is that of the evaluation, where ADMIN_UI_WRITE is not set.
Other paths in OpenBao
These paths give certificates (pki), database passwords (database, postgresql), directory passwords (ldap, ldap-operator) and child tokens.
| Policy | Path | Capabilities |
|---|---|---|
fediversity-admins |
identity/* |
read, list |
fediversity-admins |
sys/auth |
read |
fediversity-admins |
sys/mounts |
read |
fediversity-admins |
sys/policies/acl |
read, list |
fediversity-admins |
sys/policies/acl/* |
read |
fediversity-deployer |
auth/token/create |
update |
fediversity-operator-deployer |
postgresql/static-roles/operator-authelia-* |
create, read, update, delete |
fediversity-operator-deployer |
postgresql/static-roles/operator-lldap-* |
create, read, update, delete |
fediversity-operator-deployer |
postgresql/static-roles/operator-mastodon-* |
create, read, update, delete |
fediversity-operator-deployer |
postgresql/static-roles/operator-peertube-* |
create, read, update, delete |
fediversity-operator-deployer |
postgresql/static-roles/operator-pixelfed-* |
create, read, update, delete |
fediversity-operator-deployer |
ldap-operator/<each deployment>/rotate-role/authelia-bind |
update |
fediversity-operator-deployer |
auth/token/create |
update |
host-authelia |
pki/issue/internal |
update |
host-authelia |
database/static-creds/hosting-provider-authelia |
read |
host-authelia |
ldap/static-cred/authelia-bind |
read |
host-authelia |
postgresql/static-creds/hosting-provider-authelia |
read |
host-bind |
pki/issue/internal |
update |
host-garage |
pki/issue/internal |
update |
host-incus |
pki/issue/internal |
update |
host-lldap |
pki/issue/internal |
update |
host-lldap |
postgresql/static-creds/hosting-provider-lldap |
read |
host-netbox |
pki/issue/internal |
update |
host-netbox |
postgresql/static-creds/hosting-provider-netbox |
read |
host-openbao |
pki/issue/internal |
update |
host-operator-authelia |
pki/issue/internal |
update |
host-operator-authelia |
database/static-creds/operator-authelia-<own deployment> |
read |
host-operator-authelia |
ldap-operator/<own deployment>/static-cred/authelia-bind |
read |
host-operator-authelia |
postgresql/static-creds/operator-authelia-<own deployment> |
read |
host-operator-grafana |
pki/issue/internal |
update |
host-operator-lldap |
pki/issue/internal |
update |
host-operator-lldap |
postgresql/static-creds/operator-lldap-<own deployment> |
read |
host-operator-mastodon |
pki/issue/internal |
update |
host-operator-mastodon |
database/static-creds/operator-mastodon-<own deployment> |
read |
host-operator-mastodon |
postgresql/static-creds/operator-mastodon-<own deployment> |
read |
host-operator-peertube |
pki/issue/internal |
update |
host-operator-peertube |
database/static-creds/operator-peertube-<own deployment> |
read |
host-operator-peertube |
postgresql/static-creds/operator-peertube-<own deployment> |
read |
host-operator-pixelfed |
pki/issue/internal |
update |
host-operator-pixelfed |
database/static-creds/operator-pixelfed-<own deployment> |
read |
host-operator-pixelfed |
postgresql/static-creds/operator-pixelfed-<own deployment> |
read |
host-operator-smtp |
pki/issue/internal |
update |
host-operator-valkey |
pki/issue/internal |
update |
host-operator-valkey |
database/static-creds/operator-valkey-<own deployment> |
read |
host-operator-valkey |
database/static-creds/operator-authelia-<own deployment> |
read |
host-operator-valkey |
database/static-creds/operator-mastodon-<own deployment> |
read |
host-operator-valkey |
database/static-creds/operator-peertube-<own deployment> |
read |
host-operator-valkey |
database/static-creds/operator-pixelfed-<own deployment> |
read |
host-otel-collector |
pki/issue/internal |
update |
host-postgresql |
pki/issue/internal |
update |
host-smtp |
pki/issue/internal |
update |
host-telemetry |
pki/issue/internal |
update |
host-terraform-backend |
pki/issue/internal |
update |
host-valkey |
pki/issue/internal |
update |
host-valkey |
database/static-creds/hosting-provider-valkey |
read |
host-valkey |
database/static-creds/hosting-provider-authelia |
read |
host-windmill |
pki/issue/internal |
update |
host-windmill |
postgresql/static-creds/hosting-provider-windmill |
read |
PostgreSQL
The database engine of OpenBao owns the password of each role and changes it at the interval in the table.
A node reads the password of its role from OpenBao (core/setups/wiring/postgresql-roster.nix).
The database and the role of a deployment have the namespace of the deployment as a suffix, and the OpenTofu graph of the deployment creates and drops them (core/effects/tf/incus/operator/postgresql.tf).
| Nodes that read the password | Role | Database | Scope | Credential |
|---|---|---|---|---|
authelia |
hosting-provider-authelia |
hosting-provider-authelia |
hosting provider | rotating, 24h |
lldap |
hosting-provider-lldap |
hosting-provider-lldap |
hosting provider | rotating, 24h |
netbox |
hosting-provider-netbox |
hosting-provider-netbox |
hosting provider | rotating, 24h |
windmill |
hosting-provider-windmill |
hosting-provider-windmill |
hosting provider | rotating, 24h |
operator-authelia |
operator-authelia-<own deployment> |
operator-authelia-<own deployment> |
each operator deployment | rotating, 24h |
operator-lldap |
operator-lldap-<own deployment> |
operator-lldap-<own deployment> |
each operator deployment | rotating, 24h |
operator-mastodon |
operator-mastodon-<own deployment> |
operator-mastodon-<own deployment> |
each operator deployment | rotating, 24h |
operator-peertube |
operator-peertube-<own deployment> |
operator-peertube-<own deployment> |
each operator deployment | rotating, 24h |
operator-pixelfed |
operator-pixelfed-<own deployment> |
operator-pixelfed-<own deployment> |
each operator deployment | rotating, 24h |
The postgresql node also has these group roles:
| Group role | Members | Privileges on the database | Privileges on the objects | Bypasses row-level security |
|---|---|---|---|---|
windmill_admin |
hosting-provider-windmill |
each sequence of hosting-provider-windmill: ALL; each table of hosting-provider-windmill: ALL |
yes | |
windmill_user |
windmill_admin |
hosting-provider-windmill: CONNECT, CREATE, TEMPORARY |
each sequence of hosting-provider-windmill: ALL; each table of hosting-provider-windmill: ALL |
no |
Two actors have access to all databases of the node: the front-end deployer, which reads the password of the postgres superuser (the entry secret/postgresql-admin in the KV table), and a member of fediversity-admins through pgweb.
Buckets in Garage
Each row is one ensureAccess entry of a key that a node requests.
owner lets the key change the configuration of the bucket.
| Group | Node | Key | Bucket | Access |
|---|---|---|---|---|
hosting-provider |
authelia |
hosting-provider-authelia-backups |
hosting-provider-authelia-backups |
read, write, owner |
hosting-provider |
authelia |
hosting-provider-authelia-cache-backups |
hosting-provider-authelia-cache-backups |
read, write, owner |
hosting-provider |
bind |
hosting-provider-bind-backups |
hosting-provider-bind-backups |
read, write, owner |
hosting-provider |
lldap |
hosting-provider-lldap-backups |
hosting-provider-lldap-backups |
read, write, owner |
hosting-provider |
netbox |
hosting-provider-netbox-backups |
hosting-provider-netbox-backups |
read, write, owner |
hosting-provider |
openbao |
hosting-provider-openbao-backups |
hosting-provider-openbao-backups |
read, write, owner |
hosting-provider |
postgresql |
hosting-provider-postgresql-backups |
hosting-provider-postgresql-backups |
read, write, owner |
hosting-provider |
telemetry |
hosting-provider-grafana-backups |
hosting-provider-grafana-backups |
read, write, owner |
hosting-provider |
telemetry |
hosting-provider-telemetry |
hosting-provider-loki |
read, write, owner |
hosting-provider |
telemetry |
hosting-provider-telemetry |
hosting-provider-mimir |
read, write, owner |
hosting-provider |
telemetry |
hosting-provider-telemetry |
hosting-provider-tempo |
read, write, owner |
hosting-provider |
terraform-backend |
hosting-provider-terraform-backend-backups |
hosting-provider-terraform-backend-backups |
read, write, owner |
hosting-provider |
valkey |
hosting-provider-valkey-cache-backups |
hosting-provider-valkey-cache-backups |
read, write, owner |
hosting-provider |
windmill |
hosting-provider-windmill-backups |
hosting-provider-windmill-backups |
read, write, owner |
operator |
authelia |
<own deployment>-authelia-backups |
<own deployment>-authelia-backups |
read, write, owner |
operator |
authelia |
<own deployment>-authelia-cache-backups |
<own deployment>-authelia-cache-backups |
read, write, owner |
operator |
lldap |
<own deployment>-lldap-backups |
<own deployment>-lldap-backups |
read, write, owner |
operator |
mastodon |
<own deployment>-mastodon |
<own deployment>-mastodon |
read, write, owner |
operator |
mastodon |
<own deployment>-mastodon-backups |
<own deployment>-mastodon |
read |
operator |
mastodon |
<own deployment>-mastodon-backups |
<own deployment>-mastodon-backups |
read, write, owner |
operator |
mastodon |
<own deployment>-mastodon-cache-backups |
<own deployment>-mastodon-cache-backups |
read, write, owner |
operator |
peertube |
<own deployment>-peertube |
<own deployment>-peertube-playlists |
read, write, owner |
operator |
peertube |
<own deployment>-peertube |
<own deployment>-peertube-videos |
read, write, owner |
operator |
peertube |
<own deployment>-peertube-backups |
<own deployment>-peertube-backups |
read, write, owner |
operator |
peertube |
<own deployment>-peertube-backups |
<own deployment>-peertube-playlists |
read |
operator |
peertube |
<own deployment>-peertube-backups |
<own deployment>-peertube-videos |
read |
operator |
peertube |
<own deployment>-peertube-cache-backups |
<own deployment>-peertube-cache-backups |
read, write, owner |
operator |
pixelfed |
<own deployment>-pixelfed |
<own deployment>-pixelfed |
read, write, owner |
operator |
pixelfed |
<own deployment>-pixelfed-backups |
<own deployment>-pixelfed |
read |
operator |
pixelfed |
<own deployment>-pixelfed-backups |
<own deployment>-pixelfed-backups |
read, write, owner |
operator |
pixelfed |
<own deployment>-pixelfed-cache-backups |
<own deployment>-pixelfed-cache-backups |
read, write, owner |
operator |
valkey |
<own deployment>-valkey-cache-backups |
<own deployment>-valkey-cache-backups |
read, write, owner |
How the system keeps the tenants apart
- Nodes. Each deployment has its own nodes for each application and for
valkey,authelia,smtp,lldapandgrafana(core/setups/groups/operator.nix). The users, the sessions and the cache of a deployment are thus not in a store that a different deployment uses. - Network. All nodes are on one Incus bridge.
Each deployment gets a
/28of its own, and an Incus network ACL on each NIC drops the traffic to and from the other deployments (core/effects/tf/incus/operator/bridge-isolation.tf). The Incus host declares the ACL of each/28(core/components/hosting-provider/incus-bridge-acls.nix), thus the certificate of a deploy runner is restricted to the Incus project of the deployments and cannot change an ACL. Each NIC has MAC and IP address filtering (core/effects/tf/incus/instance.tf). A second ACL and the firewall of each node of the hosting provider permit only the ports that a deployment uses (core/components/hosting-provider/operator-reach.nix). The second ACL holds only the IPv4 addresses of the nodes of the hosting provider. The bridge has no IPv6 subnet (ipv6.address = noneincore/components/hosting-provider/incus.nix), thus Incus drops all IPv6 oneth0. A node of a deployment sends IPv6 only on its publiceth1, which has no NAT, thus the firewall of the destination node sees the real source address and applies the port limit. - Secrets. The policy of a node of a deployment names the KV paths with a template that OpenBao replaces with the namespace from the certificate of the node.
Thus a node reads only the entries of its own deployment (
core/components/hosting-provider/openbao/spire-auth.nix). - Databases. All deployments use the PostgreSQL node of the hosting provider. Each deployment has its own database and role for each application, and a node can read only the password of the role that has its own namespace.
- Buckets. All deployments use the Garage cluster of the hosting provider.
Each bucket and key has the namespace of the deployment as a prefix (
tenantincore/resources/garage/default.nix), and a key has access only to the buckets in the table above. - Metrics. The query path for the metrics of an application adds the
deployment_idlabel to each query (core/components/hosting-provider/metrics-query.nix). - Panel and api. An operator gets only the deployments that it owns (see In the panel).
These components are common to all tenants, and the separation there is weaker:
- The front-end deployer is one identity for all deployments.
Its OpenBao policy can write the entries of each deployment that the KV table gives, and it can read the password of the
postgressuperuser. The state backend has one useroperatorfor the states of all deployments (core/components/hosting-provider/terraform-backend/front.nix). - The Grafana of the hosting provider has one organization, thus
fediversity-staffandfediversity-adminscan read the telemetry of all deployments. - A member of
fediversity-adminscan read the secrets, the databases and the containers of all deployments.