Commit Graph
28 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 7b57ba4898 fix(keycloak): pin the issuer to the canonical OIDC URL
A bare KC_HOSTNAME combined with KC_HOSTNAME_STRICT=false lets Keycloak derive scheme and port from the incoming request. The browser reaches the realm through the proxy on port 80 while container-to-container calls reach it on keycloak:8080, so the same realm mints two different issuers and userinfo rejects the front-channel token with 'Invalid token issuer'.

OIDC.URL carries the scheme, which Keycloak uses verbatim. It is also the value group_vars/all/11_oidc.yml:19 already hands every client as the expected issuer, so server and clients now agree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 18:02:26 +02:00
kevinveenbirkenbachandClaude Opus 5 df97bf630f fix(keycloak): pin the JGroups bind address to the role's overlay
The swarm branch turns on clustered Infinispan but never constrains the JGroups
transport, so Keycloak falls back to SITE_LOCAL. Every keycloak task is attached
to four 192.168.x overlays plus the node-local docker_gwbridge, all of them
site-local, so SITE_LOCAL cannot disambiguate and each task publishes whichever
interface enumerates first.

In run 30586213932 two of the three replicas published a 172.18.x gwbridge
address into the jdbc-ping table. gwbridge is per-node and unreachable from a
peer, so those JOINs timed out: ISPN000196 "failed to recover cluster state after
the current node became the coordinator", 25 Infinispan TimeoutExceptions, 17 of
them through StateTransferLockImpl. The cluster split, one replica froze on an
old topology and answered HTTP 500 on the auth endpoint, and the Playwright
sign-out assertion saw "We are sorry... An internal server error has occurred"
instead of the login form. Eight tests failed across three roles, because
web-app-dashboard and web-app-prometheus authenticate against the same Keycloak.

The matcher comes from the subnet_address_regex lookup, so the role's declared
192.168.24.0/24 yields match-address:192\.168\.24\.\d+ - its own overlay address
matches, gwbridge and the sibling overlays do not. The line sits inside the
existing swarm guard, so compose mode is untouched.

This complements 72e275d41 rather than replacing it: that one makes a broken
replica detectable and evicts it from the VIP, this one keeps it from breaking.

Not verified by me: that Keycloak 26.7.0 spells the option
KC_CACHE_EMBEDDED_NETWORK_BIND_ADDRESS and evaluates match-address as a Java
regex. That is read from the upstream documentation, not executed, and it is the
one assumption this change rests on. If it is wrong the container fails to start,
loudly, on the first swarm run.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 02:13:19 +02:00
kevinveenbirkenbachandClaude Opus 4.8 15e7647d2f refactor(env): central TZ+LANG base included by every role env.j2
New roles/sys-svc-container/templates/env.j2 sets TZ={{ HOST_TIMEZONE }} and LANG=C.UTF-8. Every role env.j2 includes it at the top; it renders via stack_host_template, the same engine that resolves the includes in compose.yml.j2, so it works in both compose and swarm. TZ/LANG are removed from the individual role env.j2 so each value stays single-source.

New lint tests/lint/ansible/test_env_base_include.py verifies every role env.j2 includes the base and never re-sets a base-owned key (keys derived from the base file).

mattermost and gitea meta/volumes.yml drop the /etc/timezone host-path bind: swarm hard-rejects a task whose bind source is missing on the node (Debian-trixie nodes have no /etc/timezone). TZ now comes from the base env. /etc/localtime bind also dropped; the container timezone follows TZ.

Non-directive comments were removed from the touched env.j2 (banners, restatements, reference URLs, narration) so the changed files pass the comment-lint; only tool directives remain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 22:13:57 +02:00
kevinveenbirkenbachandClaude Opus 4.8 2f84fd4058 feat(keycloak): shared session cache for multi-replica (swarm)
Swarm: KC_CACHE=ispn + KC_CACHE_STACK=jdbc-ping so replicas share an Infinispan session/realm cache via JDBC_PING2 over the existing Postgres (no multicast, built-in + auto-table in 26.6.3). Compose: KC_CACHE=local (single node). Realm-import scale-back uses KEYCLOAK_REPLICAS/_WANT constants; DB network attached only when the DB is shared (KEYCLOAK_DB_NETWORK_ARG). Does NOT by itself fix the admin-console static-chunk 404 (that needs a shared gzip cache / sticky routing).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 01:04:08 +02:00
kevinveenbirkenbach 3bb8c0ce30 refactor(tls): rename tls_resolve lookup to tls
The TLS lookup has been renamed from `tls_resolve` to `tls` to better
reflect its responsibility as a strict TLS state resolver.

This refactor updates all usages across the codebase, including:
- lookup plugins and internal helpers
- roles, vars, tasks, and templates
- tests, stubs, and error messages
- documentation and changelog references

Behavior, lookup API, and semantics remain unchanged.

https://chatgpt.com/share/6985e635-5a94-800f-b794-937e566ee308
2026-02-06 14:01:32 +01:00
kevinveenbirkenbach 5e33e70892 refactor(database lookup usage): switch conditionals to enabled flag
Replace indirect type!='' checks with explicit database.enabled lookups
to improve semantics, readability, and alignment with strict lookup API.

https://chatgpt.com/share/6985d642-b40c-800f-9cdf-ed54fc484a92
2026-02-06 13:25:37 +01:00
kevinveenbirkenbach 8fe6b92e63 refactor(lookups): migrate nginx_paths, tls_resolve and cert_plan to strict positional want-path API
- Replace legacy want= keyword usage with mandatory positional want-path
- Align all nginx_paths, tls_resolve and cert_plan lookups to strict API
- Keep behavior unchanged while enforcing consistent lookup semantics

https://chatgpt.com/share/6985d642-b40c-800f-9cdf-ed54fc484a92
2026-02-06 13:06:09 +01:00
kevinveenbirkenbach f6f96a11ac Refactor: use database lookup helper everywhere
https://chatgpt.com/share/6983bcf6-85bc-800f-a0fc-5684b9078469
2026-02-04 22:52:08 +01:00
kevinveenbirkenbach 8b1ae03e77 fix(env): prevent dotenv_quote double-quoting in env.j2 templates
- Replace `"{{ ... | dotenv_quote }}"` with `{{ ... | dotenv_quote }}` across roles
- Update integration test to enforce pure Jinja + dotenv_quote and forbid wrapped quotes

https://chatgpt.com/share/6974e6c6-51b8-800f-80a1-a76f885cf57e
2026-01-24 16:35:27 +01:00
kevinveenbirkenbach fdb2683ddb test(env): enforce dotenv_quote + double quotes for password vars in env.j2 templates
https://chatgpt.com/share/6974cbac-023c-800f-8198-fd85df2aa7bc
2026-01-24 15:32:33 +01:00
kevinveenbirkenbach aa7d0c642c feat(dotenv): add dotenv_quote filter and enforce quoted password vars in env.j2
https://chatgpt.com/share/6974cbac-023c-800f-8198-fd85df2aa7bc
2026-01-24 15:22:19 +01:00
kevinveenbirkenbach ffb470877c fix(keycloak): make kcadm JSON parsing robust against noisy stdout and harden create/update logic
Handle JVM/cgroup warnings mixed into stdout by scanning and validating JSON segments,
replace fragile query-based lookups with list+filter resolution, and fix create-path
control flow to exit deterministically after successful creation.

https://chatgpt.com/share/69742b27-7980-800f-a142-4ffcf379386c
2026-01-24 03:14:56 +01:00
kevinveenbirkenbach 0b9f71463c refactor(tls): replace legacy tls filters with strict tls_resolve lookup
- Remove deprecated filter_plugins/tls.py and all dependent filters
- Introduce strict lookup plugin lookup_plugins/tls_resolve.py as single TLS authority
- Migrate all roles, templates, vars, and tasks to use tls_resolve (protocols, ports, URLs, cert paths)
- Enforce explicit TLS context (domains, applications, TLS_ENABLED, TLS_MODE)
- Support letsencrypt and self_signed with SAN handling and per-app overrides
- Update TLS provider roles to assert resolver state instead of setting facts
- Add comprehensive unit tests for tls_resolve lookup

https://chatgpt.com/share/6972b49b-b074-800f-a323-dd9fe69d02eb
2026-01-23 00:36:46 +01:00
kevinveenbirkenbach 9fdb0cddd0 Replace global WEB_PROTOCOL / WEB_PORT / WEBSOCKET_PROTOCOL logic
with explicit per-application TLS resolution.

Key changes:
- Introduce sys-front-tls-layer as the single TLS abstraction
- Centralize certificate paths via TLS_CERT_FILE / TLS_KEY_FILE / TLS_CA_FILE
- Replace sys-svc-letsencrypt SSL templates with generic TLS layer includes
- Add tls_* Jinja filters (enabled, mode, protocol, port, websocket)
- Resolve TLS mode per application (letsencrypt | self_signed | off)
- Remove implicit defaults and WEB_* globals to fail fast on misconfiguration
- Support self-signed certificates with SAN awareness
- Make TLS behavior explicit and consistent across all roles

This decouples application logic from certificate providers and
allows switching TLS flavor without touching app roles.

https://chatgpt.com/share/69727c61-8e68-800f-a267-473a7e627978
2026-01-22 20:36:49 +01:00
kevinveenbirkenbach 7c10cb6fe5 fix(openldap,keycloak): allow user binds and enable LDAP debug logging
- allow simple bind for normal LDAP users (userPassword access rules)
- relax generic read access for directory browsing
- enable Keycloak LDAP and LDAPSDK debug logging
- normalize database config formatting

https://chatgpt.com/share/696cefa5-e308-800f-aef6-fc71cc9a811e
2026-01-18 15:35:10 +01:00
kevinveenbirkenbach 5fc951dc88 fix(proxy,keycloak): make X-Forwarded-Ssl conditional and enable proxy headers
- Set X-Forwarded-Ssl dynamically based on TLS_ENABLED
- Enable KC_PROXY_HEADERS=xforwarded for proper reverse proxy support
- Ensure correct protocol handling for HTTP and HTTPS environments

https://chatgpt.com/share/696bbbed-5514-800f-8281-b8485d77cac7
2026-01-17 17:42:14 +01:00
kevinveenbirkenbach 12c72d4fc3 web-app-keycloak: disable strict hostname and https checks in non-TLS environments
https://chatgpt.com/share/696955f3-31c4-800f-ae52-dc86524d1759
2026-01-15 22:02:06 +01:00
kevinveenbirkenbach eed04764fe fix(keycloak): separate public domain from container hostname and fix env formatting
- Use KEYCLOAK_DOMAIN for KC_HOSTNAME (public FQDN)
- Introduce KEYCLOAK_CONTAINER_HOSTNAME for internal container hostname
- Fix .env formatting (remove alignment spaces)
- Build KEYCLOAK_REALM_URL from base URL + realm
- Replace deprecated desktop client auth with client auth
- Add RBAC root group and wire LDAP group path
- Disable Trusted Hosts component

https://chatgpt.com/share/69651e95-9548-800f-a9c9-811c0fe48f82
2026-01-12 17:16:47 +01:00
kevinveenbirkenbach aae463b602 Optimized keycloak setup procedures 2025-10-11 00:20:27 +02:00
kevinveenbirkenbach bb50551533 Restrucutred keycloak accounts 2025-10-10 23:40:58 +02:00
kevinveenbirkenbach 5f0762e4f6 Finished implementation of oauth2 import 2025-08-17 21:59:58 +02:00
kevinveenbirkenbach 5c9ca20e04 Optimized keycloak variables 2025-08-17 11:40:15 +02:00
kevinveenbirkenbach 3ac9bd9f90 Optimized variable typos 2025-08-15 18:43:42 +02:00
kevinveenbirkenbach 022800425d THE HUGE REFACTORING CALENDER WEEK 33; Optimized Matrix and during this updated variables, and implemented better reset and cleanup mode handling, also solved some initial setup bugs 2025-08-15 15:15:48 +02:00
kevinveenbirkenbach db0e030900 Renamed general and mode constants and implemented a check to verify that constants are just defined ones over the whole repository 2025-08-13 19:11:14 +02:00
kevinveenbirkenbach 1240d3bfdf Added debugging option to keycloak 2025-07-25 20:14:04 +02:00
kevinveenbirkenbach 756597668c Semi bsr for applications[] to prevent heavy to debug bugs in j2 - part 1 2025-07-13 15:11:38 +02:00
kevinveenbirkenbach 563d5fd528 Huge role refactoring/cleanup. Other commits will propably follow. Because some bugs will exist. Still important for longrun and also for auto docs/help/slideshow generation 2025-07-08 23:43:13 +02:00