Access control policy
How we grant, protect, review and remove access to company and customer information and systems. It applies to every employee and external collaborator with an account, and to the accounts that applications and automation use.
Annex A controls: 5.15, 5.16, 5.17, 5.18, 8.2, 8.3, 8.4, 8.5, 8.18.
Access control rules (5.15)
Section titled “Access control rules (5.15)”- Access follows need-to-know and least privilege: people get the access their role and their current project need.
- Access is granted to groups and roles, not to individual people, so a team change is one membership update.
- Every application that supports it signs in through our single sign-on (SSO), Keycloak, directly or through GitLab.
- Access is granted during onboarding, adjusted when someone changes role, and revoked during offboarding.
| Application | Who gets access | How access is protected |
|---|---|---|
| Keycloak (SSO) | Every employee | Personal password and 2FA |
| Email and calendar | Every employee | SSO for webmail, a separate revocable app password per device for mail apps |
| GitLab | Employees, external collaborators per project | SSO for employees, 2FA for every account, a role per group or project |
| Mattermost | Employees, guests in private channels | Sign-in through GitLab for employees, invitation per channel for guests |
| Vaultwarden (password manager) | Every employee | SSO plus master password, collections per company and sensitivity, office network or VPN only |
| Nextcloud, Grafana, Sentry, Kimai, Jitsi, Penpot and other tools | Employees | SSO |
| Coolify (hosting platform) | Members of the team that runs the project | SSO, one team per company |
| OpenBao (application secrets) | CI jobs, applications and automation | Short-lived credentials scoped to one project |
| cuda-dev containers | Developers | Personal SSH key, office network or VPN only |
| Servers, hosting and DNS providers | Infrastructure | SSH keys only on servers, 2FA on provider accounts |
| Company VPN | Employees who need internal services | One WireGuard key per device |
Identity management (5.16)
Section titled “Identity management (5.16)”- Every person has one personal identity in Keycloak,
<name>@d-centralize.nl. Personal accounts are never shared. - The list of people and their groups is kept in version control and changed through merge requests. The onboarding sync tool creates, changes and disables the accounts in the connected services from that list, and a nightly job checks Keycloak against it.
- Applications and automation use separate service accounts or tokens named after their purpose, never a person’s account. Test identities are marked as such in the list.
- A shared account is used only where a service has no personal accounts. Its credentials are in Vaultwarden, and role accounts use the role’s address, so the account stays with the role when people change.
- Offboarding disables the identity in Keycloak after the accounts that depend on it. Mailboxes of departed people are deleted once they have been disabled and unused for a year.
Authentication information (5.17)
Section titled “Authentication information (5.17)”- New employees receive a one-time temporary password in their private inbox. At the first sign-in they set their own password and enrol 2FA.
- Passwords and 2FA devices are personal and never shared.
- Shared secrets are stored in Vaultwarden, in the collection that matches the company and the sensitivity, as described in Bitwarden collections. Private SSH keys are Vaultwarden SSH key items, not files on disk.
- Secrets for applications and pipelines live in OpenBao, protected CI/CD variables or the hosting platform’s environment variables, never in source code.
- Secrets are handed over through Vaultwarden or an expiring Bitwarden Send, never in plain email or chat.
- Tokens for automation get the lowest role and the fewest scopes that work, expire within a year and are rotated as described in token rotation.
- Whoever lost both their password and their 2FA device contacts Infrastructure. A secret that may be compromised is changed at once and reported as an incident.
Access rights (5.18)
Section titled “Access rights (5.18)”- The owner decides on access: Infrastructure for company services, the Project lead for a product’s repositories, hosting team and production secrets.
- Office & HR tells Infrastructure about joiners, role changes and leavers. Infrastructure provisions and revokes the accounts with the onboarding sync tool.
- A role change adjusts the person’s groups to the new role and is handled as a big change under the change management policy.
- Offboarding revokes all accounts in one run on or before the last working day, and removes the person from the Vaultwarden groups.
- Every six months the Information Security Officer reviews the access rights: Keycloak accounts and groups against the staff list, GitLab members and administrators, Vaultwarden groups, Coolify teams, external collaborators and privileged accounts. The review and its corrections are recorded in a GitLab issue.
Privileged access rights (8.2)
Section titled “Privileged access rights (8.2)”- Administrator rights on Keycloak, GitLab, Vaultwarden, OpenBao, Coolify, servers and hosting and DNS providers are limited to Infrastructure and the few people who need them for their role. Coolify administrators can reach the servers and the secrets they run, so Coolify administration counts as privileged access.
- Production secrets are limited to a few trusted engineers per company.
- Administrators use their personal account with 2FA. Where a system needs a shared administrator or break-glass account, its credentials and 2FA secret are in a restricted Vaultwarden collection.
- The Keycloak administrator console requires 2FA.
- Automation that holds instance administrator rights is kept in a restricted GitLab group whose members alone can change it.
- Privileged accounts are part of the six-monthly access review.
- Developers may be local administrator on their own laptop and have root access in their own cuda-dev container. This gives no rights on shared systems.
Information access restriction (8.3)
Section titled “Information access restriction (8.3)”- GitLab groups and projects are private, except projects we publish as open source. Access is a project or group membership.
- Vaultwarden collections separate companies and sensitivity: non-production secrets for that company’s developers, production secrets for a few trusted engineers, and client collections for the developers on that client.
- Nextcloud shared folders are granted per group. Personal folders stay personal.
- Hosting resources are separated in Coolify teams, and OpenBao gives each CI job or automation only the secrets of its own project.
- Applications authorize on Keycloak groups and roles.
- Internal services, including the password manager, are reachable only from the office network or through the company VPN.
Access to source code (8.4)
Section titled “Access to source code (8.4)”- Source code lives in GitLab: our self-hosted instance, and gitlab.com for the open-source Appsemble projects.
- Write access, and read access to private projects, is a GitLab membership with the lowest role that works. External collaborators are members of their own project only.
- Every GitLab account signs in with 2FA, through SSO for employees.
- Default branches are protected. Changes reach them through merge requests that someone else reviews, as described in the GitLab workflow and the secure development policy.
- CI and deploy tokens are project or group tokens with the lowest role and the fewest scopes that work.
- Offboarding blocks the person’s GitLab account.
Secure authentication (8.5)
Section titled “Secure authentication (8.5)”- Keycloak passwords have at least 12 characters and differ from the username and email address. Every account uses time-based one-time passwords (TOTP) as second factor, enforced after a short grace period at onboarding.
- Keycloak has brute-force protection, and its sessions expire after inactivity and after a maximum lifetime.
- Login pages are served over HTTPS only.
- Servers accept SSH keys only, no passwords.
- Vaultwarden requires the master password on top of SSO, because the vault is encrypted with it.
- A service without SSO gets a unique generated password stored in Vaultwarden, and 2FA where the service offers it.
Use of privileged utility programs (8.18)
Section titled “Use of privileged utility programs (8.18)”- Privileged utility programs are the tools that can bypass system and application controls: root shells and
sudoon servers, container shells, database consoles, the GitLab Rails console, the Coolify terminal, and the administrator command line tools of Keycloak and OpenBao. - On shared systems only Infrastructure and the members of a product’s hosting team use them, through SSH keys kept in a restricted Vaultwarden collection or through their own Coolify account.
- Changes to infrastructure go through infrastructure as code in GitLab where possible. A manual change made with these tools is recorded in its GitLab issue and carried into the code.
Responsibilities
Section titled “Responsibilities”- The Information Security Officer owns this policy and runs the six-monthly access review.
- Infrastructure runs the identity and secrets services, provisions and revokes accounts, and holds the privileged accounts.
- Each Project lead decides who gets access to their product’s repositories, hosting team and production secrets.
- Office & HR reports joiners, role changes and leavers to Infrastructure in time.
- Employees protect their credentials and report suspected compromise.
Review: yearly by the Information Security Officer.
