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

This commit is contained in:
2025-07-08 23:43:13 +02:00
parent 6b87a049d4
commit 563d5fd528
1242 changed files with 2301 additions and 1355 deletions

View File

@@ -0,0 +1,33 @@
# Keycloak
## Description
Step into a secure future with Keycloak! This opensource identity and access management solution offers powerful single sign-on (SSO), multi-factor authentication, and user federation capabilities. With support for industry standards such as SAML and OpenID Connect, Keycloak helps you protect and streamline access to your applications.
## Overview
This role deploys Keycloak in a Docker environment, integrating it with a PostgreSQL database and enabling operation behind a reverse proxy such as NGINX. It manages container orchestration and configuration via Docker Compose and environment variable templates, ensuring a secure and scalable identity management solution.
## Features
- **Comprehensive Identity Management:** Manage users, roles, and permissions across your applications with robust SSO and user federation.
- **Advanced Security Options:** Benefit from multi-factor authentication, configurable password policies, and secure session management.
- **Standards Support:** Seamlessly integrate with SAML, OpenID Connect, and OAuth2 to support various authentication flows.
- **Scalable and Customizable:** Easily tailor settings and scale your Keycloak instance to meet growing demands.
## Further Resources
- [Keycloak Official Website](https://www.keycloak.org/)
- [Official Keycloak Documentation](https://www.keycloak.org/documentation.html)
- [Keycloak GitHub Repository](https://github.com/keycloak/keycloak)
- [Setting up Keycloak behind a Reverse Proxy](https://www.keycloak.org/server/reverseproxy)
- [Wikipedia](https://en.wikipedia.org/wiki/Keycloak)
- [Youtube Tutorial](https://www.youtube.com/watch?v=fvxQ8bW0vO8)
## Credits
Developed and maintained by **Kevin Veen-Birkenbach**.
Learn more at [veen.world](https://www.veen.world).
Part of the [CyMaIS Project](https://github.com/kevinveenbirkenbach/cymais)
Licensed under [CyMaIS NonCommercial License (CNCL)](https://s.veen.world/cncl).

View File

@@ -0,0 +1,24 @@
---
galaxy_info:
author: "Kevin Veen-Birkenbach"
description: "Step into a secure future with Keycloak! Our dynamic identity and access management solution offers streamlined SSO capabilities, robust security measures, and an intuitive user experience that propels your applications to unprecedented heights of performance and reliability."
license: "CyMaIS NonCommercial License (CNCL)"
license_url: "https://s.veen.world/cncl"
company: |
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
https://www.veen.world
galaxy_tags:
- keycloak
- docker
- identity management
- sso
- self-hosted
repository: https://s.veen.world/cymais
issue_tracker_url: https://s.veen.world/cymaisissues
documentation: https://s.veen.world/cymais
logo:
class: "fa-solid fa-lock"
run_after:
- web-app-matomo
- service-openldap

View File

@@ -0,0 +1,5 @@
credentials:
administrator_password:
description: "Password for the Keycloak administrator user (used in bootstrap and CLI access)"
algorithm: "sha256"
validation: "^[a-f0-9]{64}$"

View File

@@ -0,0 +1,3 @@
users:
administrator:
username: "administrator"

View File

@@ -0,0 +1,82 @@
- name: "Wait until Keycloak is reachable at {{ keycloak_server_host_url }}"
uri:
url: "{{ keycloak_server_host_url }}/realms/master"
method: GET
status_code: 200
validate_certs: false
register: keycloak_check
retries: 30
delay: 5
until: keycloak_check.status == 200
# Configure Credentials
- name: Ensure Keycloak CLI credentials are configured
shell: |
{{ keycloak_kcadm_path }} config credentials \
--server {{ keycloak_server_internal_url }} \
--realm master \
--user {{ keycloak_administrator_username }} \
--password {{ keycloak_administrator_password }}
# LDAP Source
- name: Get ID of LDAP storage provider
shell: |
{{ keycloak_kcadm_path }} get components \
-r {{ keycloak_realm }} \
--query 'providerId=ldap' \
--fields id,name \
--format json
register: ldap_components
- name: Extract LDAP component ID
set_fact:
ldap_component_id: "{{ (ldap_components.stdout | from_json)[0].id }}"
- name: Ensure {{ ldap.user.attributes.ssh_public_key }} LDAP Mapper exists
shell: |
docker exec -i keycloak_application bash -c '
/opt/keycloak/bin/kcadm.sh get components -r {{ keycloak_realm }} \
| grep -q "\"name\" : \"{{ ldap.user.attributes.ssh_public_key }}\"" \
|| printf "%s\n" "{
\"name\": \"{{ ldap.user.attributes.ssh_public_key }}\",
\"parentId\": \"{{ ldap_component_id }}\",
\"providerId\": \"user-attribute-ldap-mapper\",
\"providerType\": \"org.keycloak.storage.ldap.mappers.LDAPStorageMapper\",
\"config\": {
\"user.model.attribute\": [\"{{ ldap.user.attributes.ssh_public_key }}\"],
\"ldap.attribute\": [\"{{ ldap.user.attributes.ssh_public_key }}\"],
\"read.only\": [\"false\"],
\"write.only\": [\"true\"],
\"always.read.value.from.ldap\": [\"false\"],
\"multivalued\": [\"true\"]
}
}" | /opt/keycloak/bin/kcadm.sh create components -r {{ keycloak_realm }} -f -'
register: mapper_create
changed_when: mapper_create.rc == 0 and mapper_create.stdout != ""
# GUI
- name: Enable user profile in realm
shell: >
{{ keycloak_kcadm_path }} update realms/{{ keycloak_realm }}
-s 'attributes.userProfileEnabled=true'
- name: Re-authenticate to Keycloak after enabling user profile
shell: |
{{ keycloak_kcadm_path }} config credentials \
--server {{ keycloak_server_internal_url }} \
--realm master \
--user {{ keycloak_administrator_username }} \
--password {{ keycloak_administrator_password }}
- name: Render user-profile JSON for SSH key
template:
src: import/user-profile.json.j2
dest: "{{ import_directory_host }}/user-profile.json"
mode: '0644'
notify: docker compose up
- name: Apply SSH Public Key to user-profile via kcadm
shell: |
docker exec -i {{ container_name }} \
/opt/keycloak/bin/kcadm.sh update realms/{{ keycloak_realm }} -f {{ import_directory_docker }}user-profile.json

View File

@@ -0,0 +1,29 @@
---
- name: "include service-rdbms-central"
include_role:
name: service-rdbms-central
- name: "include role webserver-proxy-domain for {{application_id}}"
include_role:
name: webserver-proxy-domain
vars:
domain: "{{ domains | get_domain(application_id) }}"
http_port: "{{ ports.localhost.http[application_id] }}"
- name: "create directory {{import_directory_host}}"
file:
path: "{{import_directory_host}}"
state: directory
mode: 0755
- name: "Copy import files to {{ import_directory_host }}"
template:
src: "{{ item }}"
dest: "{{ import_directory_host }}/{{ item | basename | regex_replace('\\.j2$', '') }}"
mode: '770'
loop: "{{ lookup('fileglob', '{{ role_path }}/templates/import/*.j2', wantlist=True) }}"
notify: docker compose up
# Deactivated temporary. Import now via realm.yml
#- name: Implement SSH Public Key Attribut
# include_tasks: attributes/ssh_public_key.yml

View File

@@ -0,0 +1,18 @@
{% include 'roles/docker-compose/templates/base.yml.j2' %}
application:
image: "{{ applications[application_id].images.keycloak }}"
container_name: {{container_name}}
command: start {% if applications[application_id].import_realm | bool %}--import-realm{% endif %}
{% include 'roles/docker-container/templates/base.yml.j2' %}
ports:
- "{{ keycloak_server_host }}:8080"
volumes:
- "{{import_directory_host}}:{{import_directory_docker}}"
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
{% include 'roles/docker-container/templates/networks.yml.j2' %}
{% set container_port = 9000 %}
{% set container_healthcheck = 'health/live' %}
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
{% include 'roles/docker-compose/templates/networks.yml.j2' %}

View File

@@ -0,0 +1,25 @@
# Environment File for Keycloak
# Documentation can be found here:
# @see https://www.keycloak.org/server/containers
KC_HOSTNAME= https://{{domains | get_domain(application_id)}}
KC_HTTP_ENABLED= true
# Health Checks
# @see https://quarkus.io/guides/smallrye-health
KC_HEALTH_ENABLED= true
KC_METRICS_ENABLED= true
# Administrator
KEYCLOAK_ADMIN= "{{applications[application_id].users.administrator.username}}"
KEYCLOAK_ADMIN_PASSWORD= "{{applications[application_id].credentials.administrator_password}}"
# Database
KC_DB= postgres
KC_DB_URL= {{database_url_jdbc}}
KC_DB_USERNAME= {{database_username}}
KC_DB_PASSWORD= {{database_password}}
# If the initial administrator already exists and the environment variables are still present at startup, an error message stating the failed creation of the initial administrator is shown in the logs. Keycloak ignores the values and starts up correctly.
KC_BOOTSTRAP_ADMIN_USERNAME= "{{applications[application_id].users.administrator.username}}"
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{applications[application_id].credentials.administrator_password}}"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
images:
keycloak: "quay.io/keycloak/keycloak:latest"
import_realm: True # If True realm will be imported. If false skip.
features:
matomo: true
css: false
portfolio_iframe: true
ldap: true
central_database: true
recaptcha: true
csp:
flags:
script-src-elem:
unsafe-inline: true
script-src:
unsafe-inline: true
style-src:
unsafe-inline: true
domains:
canonical:
- "auth.{{ primary_domain }}"
scopes:
rbac_roles: rbac_roles
nextcloud: nextcloud
rbac_groups: "/rbac"
docker:
services:
database:
enabled: true

View File

@@ -0,0 +1,14 @@
application_id: "keycloak"
database_type: "postgres"
container_name: "{{application_id}}_application"
import_directory_host: "{{docker_compose.directories.volumes}}import/" # Directory in which keycloack import files are placed on the host
import_directory_docker: "/opt/keycloak/data/import/" # Directory in which keycloack import files are placed in the running docker container
keycloak_realm: "{{ primary_domain}}" # This is the name of the default realm which is used by the applications
keycloak_administrator: "{{ applications[application_id].users.administrator }}" # Master Administrator
keycloak_administrator_username: "{{ keycloak_administrator.username}}" # Master Administrator Username
keycloak_administrator_password: "{{ keycloak_administrator.password}}" # Master Administrator Password
keycloak_kcadm_path: "docker exec -i {{ container_name }} /opt/keycloak/bin/kcadm.sh"
keycloak_server_internal_url: "http://127.0.0.1:8080"
keycloak_server_host: "127.0.0.1:{{ports.localhost.http[application_id]}}"
keycloak_server_host_url: "http://{{ keycloak_server_host }}"