Merge pull request #196 from guidograzioli/172_vaults

Keystore based vault SPI
This commit is contained in:
Guido Grazioli 2024-04-19 09:06:38 +02:00 committed by GitHub
commit 9a961f743b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 77 additions and 14 deletions

View file

@ -7,10 +7,14 @@
keycloak_realm: TestRealm keycloak_realm: TestRealm
keycloak_quarkus_host: instance keycloak_quarkus_host: instance
keycloak_quarkus_log: file keycloak_quarkus_log: file
keycloak_quarkus_https_key_file_enabled: True keycloak_quarkus_log_level: debug
keycloak_quarkus_https_key_file_enabled: true
keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem" keycloak_quarkus_key_file: "/opt/keycloak/certs/key.pem"
keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem" keycloak_quarkus_cert_file: "/opt/keycloak/certs/cert.pem"
keycloak_quarkus_log_target: /tmp/keycloak keycloak_quarkus_log_target: /tmp/keycloak
keycloak_quarkus_ks_vault_enabled: true
keycloak_quarkus_ks_vault_file: "/opt/keycloak/certs/keystore.p12"
keycloak_quarkus_ks_vault_pass: keystorepassword
roles: roles:
- role: keycloak_quarkus - role: keycloak_quarkus
- role: keycloak_realm - role: keycloak_realm

View file

@ -21,7 +21,12 @@
path: "/opt/keycloak/certs/" path: "/opt/keycloak/certs/"
mode: 0755 mode: 0755
- name: Copy certificates - name: Create vault keystore
ansible.builtin.command: keytool -importpass -alias TestRealm_testalias -keystore keystore.p12 -storepass keystorepassword
delegate_to: localhost
changed_when: False
- name: Copy certificates and vault
become: yes become: yes
ansible.builtin.copy: ansible.builtin.copy:
src: "{{ item }}" src: "{{ item }}"
@ -30,3 +35,4 @@
loop: loop:
- cert.pem - cert.pem
- key.pem - key.pem
- keystore.p12

View file

@ -10,6 +10,7 @@
that: that:
- ansible_facts.services["keycloak.service"]["state"] == "running" - ansible_facts.services["keycloak.service"]["state"] == "running"
- ansible_facts.services["keycloak.service"]["status"] == "enabled" - ansible_facts.services["keycloak.service"]["status"] == "enabled"
fail_msg: "Service not running"
- name: Set internal envvar - name: Set internal envvar
ansible.builtin.set_fact: ansible.builtin.set_fact:
@ -40,7 +41,7 @@
- name: Check log folder - name: Check log folder
ansible.builtin.stat: ansible.builtin.stat:
path: "/tmp/keycloak" path: /tmp/keycloak
register: keycloak_log_folder register: keycloak_log_folder
- name: Check that keycloak log folder exists and is a link - name: Check that keycloak log folder exists and is a link
@ -49,11 +50,12 @@
- keycloak_log_folder.stat.exists - keycloak_log_folder.stat.exists
- not keycloak_log_folder.stat.isdir - not keycloak_log_folder.stat.isdir
- keycloak_log_folder.stat.islnk - keycloak_log_folder.stat.islnk
fail_msg: "Service log symlink not correctly created"
- name: Check log file - name: Check log file
become: yes become: yes
ansible.builtin.stat: ansible.builtin.stat:
path: "/tmp/keycloak/keycloak.log" path: /tmp/keycloak/keycloak.log
register: keycloak_log_file register: keycloak_log_file
- name: Check if keycloak file exists - name: Check if keycloak file exists
@ -65,7 +67,7 @@
- name: Check default log folder - name: Check default log folder
become: yes become: yes
ansible.builtin.stat: ansible.builtin.stat:
path: "/var/log/keycloak" path: /var/log/keycloak
register: keycloak_default_log_folder register: keycloak_default_log_folder
failed_when: false failed_when: false
@ -73,3 +75,11 @@
ansible.builtin.assert: ansible.builtin.assert:
that: that:
- not keycloak_default_log_folder.stat.exists - not keycloak_default_log_folder.stat.exists
- name: Verify vault SPI in logfile
ansible.builtin.shell: |
set -o pipefail
zgrep 'Configured KeystoreVaultProviderFactory with the keystore file' /opt/keycloak/keycloak-*/data/log/keycloak.log*zip
changed_when: false
failed_when: slurped_log.rc != 0
register: slurped_log

View file

@ -7,14 +7,14 @@ Install [keycloak](https://keycloak.org/) >= 20.0.0 (quarkus) server configurati
Role Defaults Role Defaults
------------- -------------
* Installation options #### Installation options
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
|`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` | |`keycloak_quarkus_version`| keycloak.org package version | `24.0.3` |
* Service configuration #### Service configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@ -61,7 +61,7 @@ Role Defaults
|`keycloak_quarkus_config_key_store_password`| Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text | `""` | |`keycloak_quarkus_config_key_store_password`| Password of the configuration key store; if non-empty, `keycloak_quarkus_db_pass` will be saved to the key store at `keycloak_quarkus_config_key_store_file` (instead of being written to the configuration file in clear text | `""` |
* Hostname configuration #### Hostname configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@ -70,7 +70,7 @@ Role Defaults
|`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` | |`keycloak_quarkus_hostname_strict_backchannel`| By default backchannel URLs are dynamically resolved from request headers to allow internal and external applications. If all applications use the public URL this option should be enabled. | `false` |
* Database configuration #### Database configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@ -81,7 +81,7 @@ Role Defaults
|`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` | |`keycloak_quarkus_jdbc_driver_version` | Version for JDBC driver | `9.4.1212` |
* Remote caches configuration #### Remote caches configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@ -94,7 +94,7 @@ Role Defaults
|`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` | |`keycloak_quarkus_ispn_trust_store_password` | Password for infinispan certificate keystore | `changeit` |
* Install options #### Install options
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:---------| |:---------|:------------|:---------|
@ -105,7 +105,7 @@ Role Defaults
|`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` | |`keycloak_quarkus_configure_firewalld` | Ensure firewalld is running and configure keycloak ports | `False` |
* Miscellaneous configuration #### Miscellaneous configuration
| Variable | Description | Default | | Variable | Description | Default |
|:---------|:------------|:--------| |:---------|:------------|:--------|
@ -132,6 +132,16 @@ Role Defaults
|`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` | |`keycloak_quarkus_transaction_xa_enabled`| Whether to use XA transactions | `True` |
|`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` | |`keycloak_quarkus_spi_sticky_session_encoder_infinispan_should_attach_route`| If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies and we rely on the session affinity capabilities from reverse proxy | `True` |
#### Vault SPI
| Variable | Description | Default |
|:---------|:------------|:--------|
|`keycloak_quarkus_ks_vault_enabled`| Whether to enable the vault SPI | `false` |
|`keycloak_quarkus_ks_vault_file`| The keystore path for the vault SPI | `{{ keycloak_quarkus_config_dir }}/keystore.p12` |
|`keycloak_quarkus_ks_vault_type`| Type of the keystore used for the vault SPI | `PKCS12` |
Role Variables Role Variables
-------------- --------------
@ -140,6 +150,7 @@ Role Variables
|`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` | |`keycloak_quarkus_admin_pass`| Password of console admin account | `yes` |
|`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` | |`keycloak_quarkus_frontend_url`| Base URL for frontend URLs, including scheme, host, port and path | `no` |
|`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` | |`keycloak_quarkus_admin_url`| Base URL for accessing the administration console, including scheme, host, port and path | `no` |
|`keycloak_quarkus_ks_vault_pass`| The password for accessing the keystore vault SPI | `no` |
License License

View file

@ -135,3 +135,9 @@ keycloak_quarkus_log_target: /var/log/keycloak
keycloak_quarkus_log_max_file_size: 10M keycloak_quarkus_log_max_file_size: 10M
keycloak_quarkus_log_max_backup_index: 10 keycloak_quarkus_log_max_backup_index: 10
keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip' keycloak_quarkus_log_file_suffix: '.yyyy-MM-dd.zip'
# keystore-based vault
keycloak_quarkus_ks_vault_enabled: false
keycloak_quarkus_ks_vault_file: "{{ keycloak_quarkus_config_dir }}/keystore.p12"
keycloak_quarkus_ks_vault_type: PKCS12
keycloak_quarkus_ks_vault_pass:

View file

@ -3,11 +3,13 @@
- name: "Rebuild {{ keycloak.service_name }} config" - name: "Rebuild {{ keycloak.service_name }} config"
ansible.builtin.include_tasks: rebuild_config.yml ansible.builtin.include_tasks: rebuild_config.yml
listen: "rebuild keycloak config" listen: "rebuild keycloak config"
- name: "Restart {{ keycloak.service_name }}" - name: "Restart {{ keycloak.service_name }}"
ansible.builtin.include_tasks: restart.yml ansible.builtin.include_tasks: restart.yml
listen: "restart keycloak" listen: "restart keycloak"
- name: "Print deprecation warning" - name: "Print deprecation warning"
ansible.builtin.fail: ansible.builtin.fail:
msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade." msg: "Deprecation warning: you are using the deprecated variable '{{ deprecated_variable | d('NotSet') }}', check docs on how to upgrade."
ignore_errors: True ignore_errors: true
listen: "print deprecation warning" listen: "print deprecation warning"

View file

@ -338,6 +338,22 @@ argument_specs:
description: > description: >
If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies If the route should be attached to cookies to reflect the node that owns a particular session. If false, route is not attached to cookies
and we rely on the session affinity capabilities from reverse proxy and we rely on the session affinity capabilities from reverse proxy
keycloak_quarkus_ks_vault_enabled:
default: false
type: "bool"
description: "Whether to enable vault SPI"
keycloak_quarkus_ks_vault_file:
default: "{{ keycloak_quarkus_config_dir }}/keystore.p12"
type: "str"
description: "The keystore path for the vault SPI"
keycloak_quarkus_ks_vault_type:
default: "PKCS12"
type: "str"
description: "Type of the keystore used for the vault SPI"
keycloak_quarkus_ks_vault_pass:
required: false
type: "str"
description: "The password for accessing the keystore vault SPI"
downstream: downstream:
options: options:
rhbk_version: rhbk_version:

View file

@ -82,3 +82,11 @@ log={{ keycloak_quarkus_log }}
log-level={{ keycloak.log.level }} log-level={{ keycloak.log.level }}
log-file={{ keycloak.log.file }} log-file={{ keycloak.log.file }}
log-file-format={{ keycloak.log.format }} log-file-format={{ keycloak.log.format }}
# Vault
{% if keycloak_quarkus_ks_vault_enabled %}
vault=keystore
vault-file={{ keycloak_quarkus_ks_vault_file }}
vault-type={{ keycloak_quarkus_ks_vault_type }}
vault-pass={{ keycloak_quarkus_ks_vault_pass }}
{% endif %}