mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
The Keycloak vhost proxied every path to Keycloak, so the admin console and the admin REST API under /admin/realms answered any client on the internet (observed on auth.veen.world and auth.infinito.nexus), and sys-svc-proxy had no way to limit a path by source address. services.keycloak.admin.allowed_networks now takes the networks the operator declares in the inventory. When the list is non-empty, the vhost gets its own `location ^~ /admin`, rendered through the shared html.conf.j2 like `/`, with one `allow` per entry and `deny all`. The `^~` modifier keeps a regex location from taking an admin path over. The OIDC endpoints under /realms/ and the assets under /resources/ stay public. The role ships the list empty and adds no network of its own, so an inventory that declares nothing renders today's vhost unchanged. kc_admin_networks rejects anything but a list of addresses or CIDR blocks without host bits, so a typo fails the render instead of the nginx reload. The deploy's own admin calls do not cross the vhost: every kcadm.sh login, including web-app-opentalk's and web-app-mattermost's, runs inside the Keycloak container against a loopback URL, and a unit test now pins that. The README names the callers that do cross it (the OpenTalk controller's user search, onion visitors, the Playwright suites) and so need an entry. The TODO.md item is dropped. Closes #1121 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
129 lines
3.7 KiB
YAML
129 lines
3.7 KiB
YAML
---
|
|
# nocheck: seaweedfs-required — object storage not implemented for this role
|
|
# nocheck: dynamic-flag
|
|
# nocheck: logout
|
|
logout:
|
|
enabled: false
|
|
shared: false
|
|
# nocheck: dynamic-flag cluster-wide LDAP federation keys on inventory groups[]; host-scoped group_names is cross-host cache-poisoned for this destructive flag
|
|
ldap:
|
|
bond: 1
|
|
enabled: "{{ (groups['svc-db-openldap'] | default([]) | length) > 0 }}"
|
|
shared: "{{ (groups['svc-db-openldap'] | default([]) | length) > 0 }}"
|
|
connection_pooling: false
|
|
sync:
|
|
period:
|
|
changes: 900
|
|
full: 86400
|
|
dashboard:
|
|
bond: 1
|
|
enabled: "{{ 'web-app-dashboard' in group_names }}"
|
|
shared: "{{ 'web-app-dashboard' in group_names }}"
|
|
iframe: false
|
|
matomo:
|
|
bond: 1
|
|
enabled: "{{ 'web-app-matomo' in group_names }}"
|
|
shared: "{{ 'web-app-matomo' in group_names }}"
|
|
email:
|
|
bond: 1
|
|
enabled: "{{ MAIL_PROVIDER in group_names }}"
|
|
shared: "{{ MAIL_PROVIDER in group_names }}"
|
|
javascript:
|
|
bond: 1
|
|
enabled: "{{ 'web-svc-logout' in group_names }}"
|
|
shared: "{{ 'web-svc-logout' in group_names }}"
|
|
# nocheck: playwright-service-flag — self-provider
|
|
keycloak:
|
|
healthcheck:
|
|
flavor: http_status
|
|
path: health/ready
|
|
port_key: management
|
|
# nocheck: healthcheck-timing-override the management endpoint answers from the JVM, which does not reply inside the 5s default while the realm is still importing
|
|
timeout: 15s
|
|
retries: 5
|
|
modes:
|
|
compose:
|
|
enabled: true
|
|
swarm:
|
|
enabled: true
|
|
bond: 1
|
|
enabled: true # nocheck: dynamic-flag
|
|
shared: true
|
|
provides: sso
|
|
image: quay.io/keycloak/keycloak
|
|
version: "26.8.1"
|
|
name: keycloak
|
|
min_storage: 468MB
|
|
cpus: "2.0"
|
|
mem_reservation: 2g
|
|
mem_limit: 4g
|
|
pids_limit: 1024
|
|
realm:
|
|
import_enabled: true
|
|
totp_enabled: true
|
|
users:
|
|
emails_verified: true
|
|
scopes:
|
|
nextcloud: nextcloud
|
|
moodle: moodle
|
|
accounts:
|
|
bootstrap:
|
|
username: administrator
|
|
system:
|
|
username: "{{ SOFTWARE_NAME | replace('.', '_') | lower }}"
|
|
admin:
|
|
allowed_networks: []
|
|
ports:
|
|
local:
|
|
http: 8032
|
|
internal:
|
|
http: 8080
|
|
management: 9000
|
|
proxy:
|
|
service_key: keycloak
|
|
run_after:
|
|
- web-app-matomo
|
|
- web-app-stalwart
|
|
- web-app-mailu
|
|
lifecycle: beta
|
|
# Exception: sso-proxy sidecar; upstream artefact names (oauth2-proxy image, oauth2-proxy-keycloak.cfg) stay literal, project identifiers use the sso_proxy namespace
|
|
# nocheck: dynamic-flag — per-consumer fan-out
|
|
# nocheck: playwright-service-flag — sidecar shape, no probe-able surface flag
|
|
sso_proxy:
|
|
image: quay.io/oauth2-proxy/oauth2-proxy
|
|
version: "v7.15.5"
|
|
min_storage: 220MB
|
|
configuration_file: oauth2-proxy-keycloak.cfg
|
|
ports:
|
|
internal:
|
|
http: 4180
|
|
cpus: "0.25"
|
|
mem_reservation: "64m"
|
|
mem_limit: "128m"
|
|
pids_limit: 256
|
|
# nocheck: playwright-service-flag — DB engine, covered by role-local integration tests
|
|
postgres:
|
|
bond: 1
|
|
enabled: true # nocheck: dynamic-flag
|
|
shared: "{{ 'svc-db-postgres' in group_names }}"
|
|
# nocheck: playwright-service-flag — css consumer, no Playwright surface (provider: web-svc-css)
|
|
css:
|
|
bond: 1
|
|
enabled: "{{ 'web-svc-css' in group_names }}"
|
|
shared: "{{ 'web-svc-css' in group_names }}"
|
|
# nocheck: dynamic-flag
|
|
# nocheck: playwright-service-flag — captcha backend, infrastructural
|
|
recaptcha:
|
|
enabled: "{{ RECAPTCHA_ENABLED | bool }}"
|
|
prometheus:
|
|
bond: 1
|
|
enabled: "{{ 'web-app-prometheus' in group_names }}"
|
|
shared: "{{ 'web-app-prometheus' in group_names }}"
|
|
|
|
# nocheck: playwright-service-flag
|
|
# nocheck: variants-coverage — sso-variant-tor requires the onion on in every variant, so the false polarity has no variant left to live in
|
|
tor:
|
|
bond: 0.5
|
|
enabled: "{{ 'svc-net-tor' in group_names }}"
|
|
shared: true # nocheck: dynamic-flag
|