# ansible-role-dex Dedicated Kubernetes/Helm role extracted from ansible-role-eom's Dex task. Deploys Dex with local **Catppuccin Mocha / Latte** styles and an **eom.dev** wordmark, retaining Dex's shipped authentication and consent templates. ## Generic defaults and eom.dev workflow Role defaults now use example domains/DNs, blank credentials, a 10Gi optional database request, no implicit Matrix client and disabled eom.dev branding. Plaintext LDAP remains the default as requested; TLS remains opt-in. Use [playbooks/deploy-eom.yml](playbooks/deploy-eom.yml) for the actual eom.dev deployment. It calls this role and explicitly preserves the existing issuer, namespace/releases, database settings/256Gi sizing, plaintext LDAP host, legacy POSIX/group filter, `uid` subject mapping, Matrix callback, and Catppuccin logo. Provide these existing variables through controller inventory/group_vars or an Ansible Vault-encrypted vars file: - `dex_admin_password`: existing Dex PostgreSQL password. - `openldap_readonly_password`: existing LDAP search-account password. - `matrix_dex_oidc_client_id` and `matrix_dex_oidc_client_secret`: existing MAS client. - `postgresql_admin_password`: needed only if deliberately enabling DB management. - Optional `www_dex_client_secret`: enables the website client and its separate `www-ldap`/`entryUUID` connector, without changing legacy identities. It must match the website's `DEX_CLIENT_SECRET`. Leave absent to preserve Matrix-only behavior. Review and declare any other deployed clients before rollout. Run the playbook on the controller with its kubeconfig and this role available in `ANSIBLE_ROLES_PATH`. Load your encrypted variables with Ansible's `--extra-vars` file option and `--ask-vault-pass` or your existing Vault identity configuration; do not put plaintext credentials in this playbook or pass them on command lines. This is an Ansible playbook, not a CI provider workflow, and is not automatically triggered. The old EOM compatibility entry now uses generic defaults unless you explicitly pass these site settings; prefer the site playbook for migration. ## Migration from ansible-role-eom 1. Back up the Dex PostgreSQL database and record the installed Dex/PostgreSQL Helm release versions and current values in a secure location. Values contain credentials; do not paste them into tickets, chat or unencrypted git files. 2. Install this role under `ansible-role-dex` in your controller's role search path. Install [requirements.yml](requirements.yml) and the Kubernetes Python client; Helm 3 and an authorized kubeconfig are required. Tested with Ansible Core 2.18; role metadata minimum is 2.15. 3. Use the site workflow above or invoke `ansible-role-dex` with explicit site variables in the existing playbook. The old `ansible-role-eom/tasks/dex.yaml` is now a thin `include_role` compatibility entry point. Use one entry point, not both. No global eom dependency was added: its current main task only deploys Monero and remains unchanged. 4. Keep namespace `dex`, release `dex`, issuer **https://dex.eom.dev/** (including trailing slash), database host `postgresql`, user/database `dex` and existing credentials. A role extraction must not change OIDC issuer or existing client secrets/redirect URIs, connector IDs or user-ID mappings. 5. Review the pinned Dex chart `0.26.0` (app `v2.46.0`) against your installed release **before applying**. Override `dex_chart_version` and optionally `dex_image_tag` if staging a different supported release. This role does not discover/guess the installed version or perform a live migration by itself. 6. PostgreSQL management defaults to **false**: the existing release and PVC are left untouched. Do not uninstall the old release or delete its volumes. The extracted config corrects the old `databbase` typo to `database: dex`. The site playbook maps legacy inventory variables explicitly: | Old inventory variable | New role variable | | --- | --- | | `dex_admin_password` | `dex_postgres_password` (DB password, not a Dex UI admin) | | `postgresql_admin_password` | `dex_postgres_admin_password` | | `openldap_readonly_password` | `dex_ldap_bind_password` | | `matrix_dex_oidc_client_id` / `matrix_dex_oidc_client_secret` | Existing Matrix Auth Service client | The site playbook enables the existing Matrix client. Its original redirect URI is explicit in `dex_matrix_redirect_uris`; override to match your actual MAS configuration. Other clients previously added directly to Helm must be declared in `dex_static_clients` before running this role. Helm values are reset to this role's complete values: undeclared manual Helm customizations are not implicitly preserved. The role's authoritative values must be reviewed. ## Main variables See [defaults/main.yml](defaults/main.yml) for all options. | Variable | Default / behavior | | --- | --- | | `dex_namespace`, `dex_release_name` | `dex`, `dex` | | `dex_chart_version` | `0.26.0` (explicit, reviewed release) | | `dex_issuer`, `dex_hostname` | `https://{{ dex_hostname }}/`, `dex.example.com` | | `dex_ingress_class`, `dex_cluster_issuer` | `nginx`, `letsencrypt-prod` | | `dex_theme_enabled`, `dex_brand_name` | false, `Dex` (site playbook enables eom.dev theme) | | `dex_static_clients` | Additional Dex static client objects; default empty | | `dex_additional_connectors` | Additional complete connector objects; default empty | | `dex_env_secret_name` | Optional existing environment Secret in Dex namespace | | `dex_ca_secret_name` | Optional existing CA Secret mounted at `/etc/dex-ca` | | `dex_postgres_manage` | false; reuse existing DB without changing its release | | `dex_postgres_ssl_mode` | `disable`, preserving internal DB behavior | | `dex_image_pull_secrets` | Kubernetes imagePullSecrets list | | `dex_extra_volumes`, `dex_extra_volume_mounts` | Optional additional mounts | ### LDAP: plaintext is the default, TLS is opt-in As requested, default LDAP behavior remains `insecureNoSSL: true` against `ldap.example.com:389` (the site playbook uses `openldap.openldap.svc.cluster.local`). This exposes both service-bind and user passwords to network observers. Restrict it to the trusted internal network with your cluster's policies; no public LDAP exposure is created by this role. The generic connector uses `inetOrgPerson` and DN-based group matching. The site playbook retains ID `ldap`, `idAttr: uid`, its POSIX/group filter, and `userAttr: cn` group matching. For `uniqueMember` values containing full DNs, set `dex_ldap_group_user_attribute: DN` deliberately after testing. Changing connector ID or idAttr changes OIDC subjects and can detach existing accounts. For **StartTLS**, explicitly set `dex_ldap_insecure_no_ssl: false`, `dex_ldap_start_tls: true`, and a host/port supporting StartTLS. For **LDAPS**, set both flags false and use the server's TLS hostname with port 636. Certificate verification remains enabled; no `insecureSkipVerify` bypass is offered. For a private CA set `dex_ca_secret_name` and `dex_ldap_root_ca` to `/etc/dex-ca/`. Verify certificate hostname, validity, SHA-2 signature, strong keys and CA trust independently. Additional connectors have their own transport settings and must be configured separately. ### Credentials and clients Supply database and LDAP passwords from Vault/external lookups or the supported legacy secret variables. Helm deployment and validation tasks are `no_log` and diff-suppressed. Dex configuration is stored by the official chart in a Kubernetes **Secret**, never in the theme ConfigMap. Helm stores release values, including inline credentials, in its release Secrets: protect these with RBAC, encryption at rest and encrypted backups. This role does not generate or rotate passwords. Client `secretEnv` can refer to a key in `dex_env_secret_name`. LDAP connectors support `$ENV_NAME` references, such as `bindPW: $DEX_LDAP_BIND_PASSWORD`. The database password remains a protected Helm/Dex config value; it is not assumed to support the same connector substitution. Never commit actual secrets. [tests/example-vars.yml](tests/example-vars.yml) shows a www client and separate `www-ldap` connector using `entryUUID`, `inetOrgPerson` and DN group matching. This avoids breaking legacy subjects while supporting new free website users. The Secret's `WWW_DEX_CLIENT_SECRET` must match the website's `DEX_CLIENT_SECRET`; set the website's `DEX_CONNECTOR_ID=www-ldap` and exact matching issuer. No new client or connector is silently enabled by default. Verify that this connector's search base includes the website account OU before enabling public registration. ### Theme [files/styles.css](files/styles.css) implements responsive Mocha dark mode and Latte light mode using `prefers-color-scheme`, visible focus rings, local fonts, inputs, errors, connector buttons and consent panels. [files/logo.svg](files/logo.svg) extends the website's orbit mark into an eom.dev wordmark. Only `themes/light/styles.css` and `themes/light/logo.svg` are mounted read-only under the official image's `/srv/dex/web`; frontend selects that directory and `theme/logo.svg`. All other version-matched templates, icons and static assets come from the installed Dex image. No forms, OAuth parameters, redirects or approval/security logic are replaced. This deliberately retains the shipped favicon; logo/theme are local, with no third-party fonts or scripts. A checksum of public theme assets triggers a rollout when they change (subPath mounts do not hot-reload). Setting `dex_theme_enabled: false` restores Dex's default frontend; the unused ConfigMap is retained. Existing environment Secret or CA Secret rotations require a Dex rollout; the role does not expose or hash their contents. Inspect log privacy at any upstream proxies too: ingress access logs are disabled to avoid recording authorization codes and related URLs. ### Optional PostgreSQL management For a new install or an explicitly reviewed DB upgrade, set `dex_postgres_manage: true` and **pin `dex_postgres_chart_version`** to the intended Bitnami release. Defaults retain release `postgresql`, 256Gi and `volumeName: data` from the old task. Confirm existing PV/PVC binding, storage size, chart/image availability and schema compatibility first; do not use this to switch major database versions without a backup/restore plan. Changing Helm password values does not automatically rotate an existing database password. Managed DB transport is unchanged; configure external DB TLS/mesh separately if required. ## Validation [tests/Dockerfile](tests/Dockerfile) installs the declared collection and Helm, checks Ansible syntax, renders actual values and runs the pinned chart through Helm and strict Kubernetes schemas. Fixtures verify legacy plaintext/subjects, Matrix client, additional environment client, opt-in TLS, theme mounts, protected Dex config and disabled/minimal variants. No cluster is contacted by these tests. The theme was also exercised with the official Dex v2.46.0 image using isolated SQLite/mock authentication. Verify real LDAP, client redirects and database access in staging before rollout. Chart upgrades should repeat that image/theme compatibility test. No production deployments or database changes are performed as part of this extraction. The editor's scanner flags high-severity findings in the validation runner's upstream Python base image. That image is test-only and is not deployed by this role. Review/update approved CI base-image digests with your image scanner; these findings are not represented as resolved by the functional tests.