docs/architecture/security.md
Simon Bärlocher 345cf4b319
docs: add architecture section and overhaul top-level README
- Move Simon's architecture documentation into architecture/
  (setup, variables, topology, dns, deploy, security, operations
  plus index and glossary). All cross-repo references point at
  https://git.digitalboard.ch/Digitalboard/{reference-ansible,dns-zones}
  via absolute URLs so the docs remain navigable from any context.
- Rewrite README.md as a documentation hub: introduction, platform
  Mermaid overview, comparison of the three repos
  (docs / digitalboard.core / reference-ansible) and a full table of
  contents covering architecture, contributing, infrastructure,
  keycloak, ms-entra and troubleshooting.

Addresses the open items from the WKS PoC review (2026-05-26):
docs README begrüssungstext + Übersichtsgrafik + Verlinkung der
beiden anderen Repos, sowie das Verschieben der Architektur-Doku.
2026-05-28 14:25:27 +02:00

3.7 KiB

Security and demo-only defaults

← Back to Architecture index

This repo is explicitly designed for demo setups. All default values in the roles are insecure and are overridden in demo-* inventories via Bao lookups or host_vars. For production deployments the hardening block further down also applies.

Secret pattern (Bao lookup)

# group_vars/.../<service>.yml or host_vars/.../<service>.yml
authentik_secret_key: "{{ lookup('community.hashi_vault.hashi_vault',
    vault_mount + '/data/authentik:secret_key',
    url=vault_addr) }}"
  • vault_mount and vault_addr come from group_vars/all/vault.yml.
  • KV-v2 paths require an explicit /data/ segment — Ansible does not resolve this automatically.
  • vault_mount is unique per inventory (demo-gymburgdorf, demo-phbern, …) → tenant isolation in Bao via mount + policy.

Demo-only defaults — override required

These defaults in digitalboard.core are insecure. In any production-grade deployment they must be overridden via Bao lookup or host_var:

Variable Default Where to override
keycloak_admin_password changeme host_vars keycloak_servers
keycloak_postgres_password changeme same
authentik_secret_key changeme-generate-a-random-string host_vars/application/authentik.yml
authentik_postgres_password changeme same
nextcloud_admin_password admin host_vars/application/nextcloud.yml
nextcloud_postgres_password changeme same
nextcloud_s3_key / nextcloud_s3_secret changeme / changeme same
garage_webui_password admin host_vars/storage/garage.yml
garage_rpc_secret 0123…cdef (64-hex constant) same
garage_admin_token identical to rpc_secret same
garage_metrics_token identical to rpc_secret same

Convention: every value listed above must have a Bao lookup in demo-*/host_vars/.../...yml before the inventory is considered deploy-ready.

Threat boundaries (current demo state)

Boundary Status Notes
DMZ ↔ Backend (172.16.9 ↔ 172.16.19) Plaintext HTTP Auth bearers, OIDC codes, session cookies travel unencrypted. Fine for demo; for prod use mTLS or a WireGuard overlay.
Host firewall missing The base role does not install UFW/nftables. Segmentation relies on the hypervisor/VLAN.
SSH ansible_user: root No bastion, no jump host. Key distribution out-of-band.
Authentik SPOF accepted IdP and SP services share the same host (application). An Authentik outage means a login outage including the LDAP outpost. No break-glass path.
ACME TSIG key Bao lookup (in Ansible), plaintext in knot.conf on ns1 side One TSIG key per demo tenant, scoped via Knot ACL update-owner-name to the tenant's ACME sub-tree. Rotation is manual and must be done on both sides simultaneously (Bao + knot.conf + knotc zone-reload).
Backup / DR out of scope Garage replication_factor: 1 (default), no Postgres backup job, no Bao snapshot cron.

To adapt for production, add

  • Host firewall (extend the base role or add a dedicated firewall role).
  • mTLS or WireGuard between DMZ and backend.
  • Authentik on a separate host with a recovery admin token.
  • Bao policies per inventory mount (read-only for the deploy token, write-only for the bootstrap job).
  • Backup cron for Postgres + Garage + Bao.
  • SSH bastion + key rotation.