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.
This commit is contained in:
parent
8c2ea8cc72
commit
345cf4b319
9 changed files with 742 additions and 27 deletions
71
architecture/security.md
Normal file
71
architecture/security.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<!-- markdownlint-disable MD013 MD060 MD051 -->
|
||||
# Security and demo-only defaults
|
||||
|
||||
← Back to [Architecture index](README.md)
|
||||
|
||||
> 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)
|
||||
|
||||
```yaml
|
||||
# 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](https://git.digitalboard.ch/Digitalboard/reference-ansible/src/branch/main/inventories/demo-gymburgdorf/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`](https://git.digitalboard.ch/Digitalboard/dns-zones/src/branch/main/knot/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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue