From 41d8ad8489c25959a5575a47559f1da41a885922 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Wed, 13 May 2026 12:47:15 +0200 Subject: [PATCH 01/46] Only one manage per access instance --- .../templates/serverapplication.yml.j2 | 50 ++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/roles/openaccess/templates/serverapplication.yml.j2 b/roles/openaccess/templates/serverapplication.yml.j2 index 80da77a94..06390f480 100644 --- a/roles/openaccess/templates/serverapplication.yml.j2 +++ b/roles/openaccess/templates/serverapplication.yml.j2 @@ -16,6 +16,8 @@ server: spring: main: banner-mode: "off" + cache: + type: simple session: jdbc: cleanup-cron: "-" @@ -108,6 +110,7 @@ config: sram: "https://{{ env }}.sram.surf.nl/" service_desk: "https://servicedesk.surf.nl/jira/plugins/servlet/desk/user/requests?reporter=all" feedback_widget_enabled: true + test_environment: {{ openconextaccess.test_environment }} # For other environments, move to group_vars identity_providers: - name: "SXS IdP" @@ -147,6 +150,8 @@ gui: feature: enable-performance-seed: False + statistics-enabled: False + stepup-required: False email: from: "{{ noreply_email }}" @@ -158,17 +163,10 @@ email: manage: enabled: True - activeManage: TEST - test: - url: {{ openconextaccess.managetest.url }} - user: {{ openconextaccess.managetest.user }} - password: {{ openconextaccess.managetest.password }} - defaultState: prodaccepted - prod: - url: {{ openconextaccess.manageprod.url }} - user: {{ openconextaccess.manageprod.user }} - password: {{ openconextaccess.managetest.password }} - defaultState: testaccepted + url: {{ openconextaccess.managetest.url }} + user: {{ openconextaccess.managetest.user }} + password: {{ openconextaccess.managetest.password }} + defaultState: testaccepted # If manage is disabled (e.g. enabled: False) the staticManageDirectory is the directory where the {metadata_type}.json files # are located. This can also be an absolute file path, e.g. file:///opt/openconext/invite/manage staticManageDirectory: classpath:/manage @@ -180,18 +178,36 @@ invite: user: {{ invite.access_user }} password: "{{ invite.access_secret }}" -s3storage: - url: {{ openconextaccess.s3_storage.url }} - key: {{ openconextaccess.s3_storage.key }} - secret: {{ openconextaccess.s3_storage.secret }} - bucket: {{ openconextaccess.s3_storage.bucket }} - statistics: enabled: {{ openconextaccess.statistics.enabled }} url: {{ openconextaccess.statistics.url }} user: {{ openconextaccess.statistics.user }} password: {{ openconextaccess.statistics.password }} +s3storage: + url: {{ openconextaccess.s3_storage.url }} + key: {{ openconextaccess.s3_storage.key }} + secret: {{ openconextaccess.s3_storage.secret }} + bucket: {{ openconextaccess.s3_storage.bucket }} + +ohdear: + apiKey: "test-token" + baseUrl: http://localhost:8089/api + enabled: false + +springdoc: + pathsToMatch: "/api/v1/**" + api-docs: + path: "/ui/api-docs" + enabled: false + swagger-ui: + path: "/ui/api-ui.html" + enabled: false + operationsSorter: method + oauth: + client-id: ${spring.security.oauth2.client.registration.oidcng.client-id} + client-secret: ${spring.security.oauth2.client.registration.oidcng.client-secret} + use-basic-authentication-with-access-code-grant: true management: health: From 9d49c90471bb85c18c3a68282b838fd07136bb27 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Fri, 15 May 2026 15:55:55 +0200 Subject: [PATCH 02/46] English IdP description --- roles/openaccess/templates/serverapplication.yml.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/openaccess/templates/serverapplication.yml.j2 b/roles/openaccess/templates/serverapplication.yml.j2 index 06390f480..9c29fe9b3 100644 --- a/roles/openaccess/templates/serverapplication.yml.j2 +++ b/roles/openaccess/templates/serverapplication.yml.j2 @@ -115,11 +115,11 @@ config: identity_providers: - name: "SXS IdP" entityid: "http://mock-idp" - descriptionEN: "Een test-IdP waarmee je zelf attributen-sets kunt simuleren. De metadata vind je hier" + descriptionEN: "A test IdP that allows you to simulate attribute sets yourself. You can find the metadata here" descriptionNL: "Een test-IdP waarmee je zelf attributen-sets kunt simuleren. De metadata vind je hier" - name: "SXS Dummy" entityid: "https://idp.diy.surfconext.nl" - descriptionEN: "Een test-IdP met fictieve gebruikersaccounts. De metadata vind je hier" + descriptionEN: "A test IdP with fictitious user accounts. You can find the metadata here" descriptionNL: "Een test-IdP met fictieve gebruikersaccounts. De metadata vind je hier" idp_proxy_meta_data: {{ openconextaccess.idp_proxy_meta_data }} minimal_stepup_acr_level: "http://{{ base_domain }}/assurance/loa2" From c1b124e14aa6c1384f7362be089a397564f4298c Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Fri, 15 May 2026 16:32:34 +0200 Subject: [PATCH 03/46] Fixed deployment openaccess --- roles/openaccess/templates/serverapplication.yml.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/openaccess/templates/serverapplication.yml.j2 b/roles/openaccess/templates/serverapplication.yml.j2 index 9c29fe9b3..f9dbf266a 100644 --- a/roles/openaccess/templates/serverapplication.yml.j2 +++ b/roles/openaccess/templates/serverapplication.yml.j2 @@ -163,9 +163,9 @@ email: manage: enabled: True - url: {{ openconextaccess.managetest.url }} - user: {{ openconextaccess.managetest.user }} - password: {{ openconextaccess.managetest.password }} + url: {{ openconextaccess.manage.url }} + user: {{ openconextaccess.manage.user }} + password: {{ openconextaccess.manage.password }} defaultState: testaccepted # If manage is disabled (e.g. enabled: False) the staticManageDirectory is the directory where the {metadata_type}.json files # are located. This can also be an absolute file path, e.g. file:///opt/openconext/invite/manage From f3c7410f42205a4b379609503ef50abbcd1e8d62 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Fri, 22 May 2026 10:07:40 +0200 Subject: [PATCH 04/46] Added OhDear configuration --- roles/openaccess/templates/serverapplication.yml.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/openaccess/templates/serverapplication.yml.j2 b/roles/openaccess/templates/serverapplication.yml.j2 index f9dbf266a..3286d5a79 100644 --- a/roles/openaccess/templates/serverapplication.yml.j2 +++ b/roles/openaccess/templates/serverapplication.yml.j2 @@ -191,9 +191,9 @@ s3storage: bucket: {{ openconextaccess.s3_storage.bucket }} ohdear: - apiKey: "test-token" - baseUrl: http://localhost:8089/api - enabled: false + apiKey: {{ openconextaccess_ohdear_apikey }} + baseUrl: "https://ohdear.app/api" + enabled: true springdoc: pathsToMatch: "/api/v1/**" From 91630d07125068b49394d2bfe136fd186a07398f Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Wed, 27 May 2026 07:29:28 +0200 Subject: [PATCH 05/46] Feature toggle for demo seed --- roles/openaccess/templates/serverapplication.yml.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/openaccess/templates/serverapplication.yml.j2 b/roles/openaccess/templates/serverapplication.yml.j2 index 3286d5a79..d0d6aacc6 100644 --- a/roles/openaccess/templates/serverapplication.yml.j2 +++ b/roles/openaccess/templates/serverapplication.yml.j2 @@ -110,6 +110,7 @@ config: sram: "https://{{ env }}.sram.surf.nl/" service_desk: "https://servicedesk.surf.nl/jira/plugins/servlet/desk/user/requests?reporter=all" feedback_widget_enabled: true + demo_seed_enabled: {{ openconextaccess.demo_seed_enabled }} test_environment: {{ openconextaccess.test_environment }} # For other environments, move to group_vars identity_providers: From a9b37ce3a045e3ab718164248ec01b9e10d425d1 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Wed, 27 May 2026 11:11:50 +0200 Subject: [PATCH 06/46] Configure cleanup cron for Spring sessions --- roles/openaccess/defaults/main.yml | 2 ++ roles/openaccess/templates/serverapplication.yml.j2 | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/roles/openaccess/defaults/main.yml b/roles/openaccess/defaults/main.yml index 888e97b36..acdfa9f0b 100644 --- a/roles/openaccess/defaults/main.yml +++ b/roles/openaccess/defaults/main.yml @@ -3,3 +3,5 @@ openaccess_server_restart_policy: always openaccess_server_restart_retries: 0 openaccess_docker_networks: - name: loadbalancer +openaccess_cronjobmaster: true + diff --git a/roles/openaccess/templates/serverapplication.yml.j2 b/roles/openaccess/templates/serverapplication.yml.j2 index d0d6aacc6..3286c53bb 100644 --- a/roles/openaccess/templates/serverapplication.yml.j2 +++ b/roles/openaccess/templates/serverapplication.yml.j2 @@ -20,8 +20,12 @@ spring: type: simple session: jdbc: + initialize-schema: never +{% if openaccess_cronjobmaster is defined and openaccess_cronjobmaster == false %} cleanup-cron: "-" - initialize-schema: always +{% else %} + cleanup-cron: "0 */5 * * * *" +{% endif %} flush-mode: on_save save-mode: on_set_attribute store-type: jdbc From a8b42e3a8d274df334ef4c250fdd83e24a3e4813 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Fri, 29 May 2026 08:56:11 +0200 Subject: [PATCH 07/46] Added - broken - stepup service_providers See https://github.com/OpenConext/OpenConext-manage/issues/690 --- roles/manage/templates/stepup_config.json.j2 | 69 ++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/roles/manage/templates/stepup_config.json.j2 b/roles/manage/templates/stepup_config.json.j2 index b44e34d77..2d95b1b28 100644 --- a/roles/manage/templates/stepup_config.json.j2 +++ b/roles/manage/templates/stepup_config.json.j2 @@ -40,5 +40,74 @@ "nl_NL": "

Beste {{ commonName }},

{% if isRevokedByRa %} Je SURFsecureID herstelmethode is verwijderd door een beheerder. {% else %} Je SURFsecureID herstelmethode is verwijderd. Neem direct contact op met de helpdesk van je instelling als je dit niet zelf gedaan hebt, omdat dit kan betekenen dat je account gecompromitteerd is. {% endif %}

Je kunt deze herstelmethode niet meer gebruiken om een SURFsecureID token te activeren.

Zorg er altijd voor dat je tenminste één herstelmethode beschikbaar hebt.

Met vriendelijke groet,

SURF

" } } + "service_providers": [ + {# START SP DEFINITIONS #} + {# The Stepup-RA SP + Required to allow the RA to authenticate to the SA-GW #} + { + "entity_id": "https://{{ ra_vhost_name }}/authentication/metadata", + "public_key": "{{ ra_saml_sp_publickey | depem }}", + "acs": [ + "https://{{ ra_vhost_name }}/authentication/consume-assertion" + ], + "loa": { + "__default__": "{{ stepup_uri_loa1 }}" + }, + "assertion_encryption_enabled": false, + "second_factor_only": false, + "second_factor_only_nameid_patterns": [], + "blacklisted_encryption_algorithms": [] + }, + {# The Stepup-SelfService SP + Required to allow the SS to authenticate to the SA-GW #} + { + "entity_id": "https://{{ selfservice_vhost_name }}/authentication/metadata", + "public_key": "{{ selfservice_saml_sp_publickey | depem }}", + "acs": [ + "https://{{ selfservice_vhost_name }}/authentication/consume-assertion" + ], + "loa": { + "__default__": "{{ stepup_uri_loa1 }}" + }, + "assertion_encryption_enabled": false, + "second_factor_only": false, + "second_factor_only_nameid_patterns": [], + "blacklisted_encryption_algorithms": [] + }, + + {# START: GSSP SPs for SS and RA + These entries are required for authentication and ragistration of GSSP tokens fromt the SP and + RA interfaces. #} + {% for key, value in stepup_enabled_generic_second_factors.items() %} + { + "entity_id": "https://{{ selfservice_vhost_name }}/registration/gssf/{{ key }}/metadata", + "public_key": "{{ selfservice_gssp_sp_publickey | depem }}", + "acs": [ + "https://{{ selfservice_vhost_name }}/registration/gssf/{{ key }}/consume-assertion" + ], + "loa": { + "__default__": "{{ stepup_uri_loa1 }}" + }, + "assertion_encryption_enabled": false, + "second_factor_only": false, + "second_factor_only_nameid_patterns": [], + "blacklisted_encryption_algorithms": [] + }, + { + "entity_id": "https://{{ ra_vhost_name }}/vetting-procedure/gssf/{{ key }}/metadata", + "public_key": "{{ ra_gssp_sp_publickey | depem }}", + "acs": [ + "https://{{ ra_vhost_name }}/vetting-procedure/gssf/{{ key }}/verify" + ], + "loa": { + "__default__": "{{ stepup_uri_loa1 }}" + }, + "assertion_encryption_enabled": false, + "second_factor_only": false, + "second_factor_only_nameid_patterns": [], + "blacklisted_encryption_algorithms": [] + }, + {% endfor %} + ] } {% endraw %} From 33f91a4158fabba74574d959042b33d3ee5a0839 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Fri, 29 May 2026 09:12:04 +0200 Subject: [PATCH 08/46] =?UTF-8?q?Replced=20raw=20fragment=20=F0=9F=A4=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- roles/manage/templates/stepup_config.json.j2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/roles/manage/templates/stepup_config.json.j2 b/roles/manage/templates/stepup_config.json.j2 index 2d95b1b28..048388e5e 100644 --- a/roles/manage/templates/stepup_config.json.j2 +++ b/roles/manage/templates/stepup_config.json.j2 @@ -40,6 +40,7 @@ "nl_NL": "

Beste {{ commonName }},

{% if isRevokedByRa %} Je SURFsecureID herstelmethode is verwijderd door een beheerder. {% else %} Je SURFsecureID herstelmethode is verwijderd. Neem direct contact op met de helpdesk van je instelling als je dit niet zelf gedaan hebt, omdat dit kan betekenen dat je account gecompromitteerd is. {% endif %}

Je kunt deze herstelmethode niet meer gebruiken om een SURFsecureID token te activeren.

Zorg er altijd voor dat je tenminste één herstelmethode beschikbaar hebt.

Met vriendelijke groet,

SURF

" } } + {% endraw %} "service_providers": [ {# START SP DEFINITIONS #} {# The Stepup-RA SP @@ -110,4 +111,4 @@ {% endfor %} ] } -{% endraw %} + From c6cb8ae70e48fea97bf0cab2659b8d6c85ec2cb9 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Fri, 29 May 2026 09:15:16 +0200 Subject: [PATCH 09/46] Fixed broken json --- roles/manage/templates/stepup_config.json.j2 | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/roles/manage/templates/stepup_config.json.j2 b/roles/manage/templates/stepup_config.json.j2 index 048388e5e..14dad1bc6 100644 --- a/roles/manage/templates/stepup_config.json.j2 +++ b/roles/manage/templates/stepup_config.json.j2 @@ -39,7 +39,7 @@ "en_GB": "

Dear {{ commonName }},

{% if isRevokedByRa %} Your SURFsecureID recovery method was removed by an administrator. {% else %} Your SURFsecureID recovery method has been removed. Please contact your institution's helpdesk immediately if you did not do this yourself, as this could mean that your account has been compromised. {% endif %}

You can no longer use this recovery method to activate a SURFsecureID token.

Always make sure you have at least one recovery method available.

Best regards,

SURF

", "nl_NL": "

Beste {{ commonName }},

{% if isRevokedByRa %} Je SURFsecureID herstelmethode is verwijderd door een beheerder. {% else %} Je SURFsecureID herstelmethode is verwijderd. Neem direct contact op met de helpdesk van je instelling als je dit niet zelf gedaan hebt, omdat dit kan betekenen dat je account gecompromitteerd is. {% endif %}

Je kunt deze herstelmethode niet meer gebruiken om een SURFsecureID token te activeren.

Zorg er altijd voor dat je tenminste één herstelmethode beschikbaar hebt.

Met vriendelijke groet,

SURF

" } - } + }, {% endraw %} "service_providers": [ {# START SP DEFINITIONS #} @@ -59,23 +59,6 @@ "second_factor_only_nameid_patterns": [], "blacklisted_encryption_algorithms": [] }, - {# The Stepup-SelfService SP - Required to allow the SS to authenticate to the SA-GW #} - { - "entity_id": "https://{{ selfservice_vhost_name }}/authentication/metadata", - "public_key": "{{ selfservice_saml_sp_publickey | depem }}", - "acs": [ - "https://{{ selfservice_vhost_name }}/authentication/consume-assertion" - ], - "loa": { - "__default__": "{{ stepup_uri_loa1 }}" - }, - "assertion_encryption_enabled": false, - "second_factor_only": false, - "second_factor_only_nameid_patterns": [], - "blacklisted_encryption_algorithms": [] - }, - {# START: GSSP SPs for SS and RA These entries are required for authentication and ragistration of GSSP tokens fromt the SP and RA interfaces. #} @@ -109,6 +92,23 @@ "blacklisted_encryption_algorithms": [] }, {% endfor %} + {# The Stepup-SelfService SP + Required to allow the SS to authenticate to the SA-GW #} + { + "entity_id": "https://{{ selfservice_vhost_name }}/authentication/metadata", + "public_key": "{{ selfservice_saml_sp_publickey | depem }}", + "acs": [ + "https://{{ selfservice_vhost_name }}/authentication/consume-assertion" + ], + "loa": { + "__default__": "{{ stepup_uri_loa1 }}" + }, + "assertion_encryption_enabled": false, + "second_factor_only": false, + "second_factor_only_nameid_patterns": [], + "blacklisted_encryption_algorithms": [] + } + ] } From 397ef0ff4b0281eb8096bb84f940a24c1108376e Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 10:24:18 +0200 Subject: [PATCH 10/46] Access: remove separate server and client versions --- roles/openaccess/tasks/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/openaccess/tasks/main.yml b/roles/openaccess/tasks/main.yml index 5f92ead18..fcc918dcb 100644 --- a/roles/openaccess/tasks/main.yml +++ b/roles/openaccess/tasks/main.yml @@ -37,7 +37,7 @@ name: accessserver env: TZ: "{{ timezone }}" - image: ghcr.io/openconext/openconext-access/accessserver:{{ openconextaccess_server_version }} + image: ghcr.io/openconext/openconext-access/accessserver:{{ openconextaccess_version }} pull: true restart_policy: "{{ openaccess_server_restart_policy }}" restart_retries: "{{ openaccess_server_restart_retries }}" # Only for restart policy on-failure @@ -72,7 +72,7 @@ - name: Create the access client container community.docker.docker_container: name: accessgui - image: ghcr.io/openconext/openconext-access/accessclient:{{ openconextaccess_client_version }} + image: ghcr.io/openconext/openconext-access/accessclient:{{ openconextaccess_version }} pull: true restart_policy: "always" state: started From 6e2239c82c025fb89a9a1b16e58a00e48b1a6fe9 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 10:32:18 +0200 Subject: [PATCH 11/46] yamllint --- roles/openaccess/handlers/main.yml | 4 ++-- roles/openaccess/tasks/main.yml | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/roles/openaccess/handlers/main.yml b/roles/openaccess/handlers/main.yml index e80525c30..02ce823ec 100644 --- a/roles/openaccess/handlers/main.yml +++ b/roles/openaccess/handlers/main.yml @@ -1,4 +1,4 @@ -- name: restart accessserver +- name: Restart accessserver community.docker.docker_container: name: accessserver state: started @@ -6,4 +6,4 @@ # avoid restarting it creates unexpected data loss according to docker_container_module notes comparisons: '*': ignore - when: accessservercontainer is success and accessservercontainer is not change \ No newline at end of file + when: accessservercontainer is success and accessservercontainer is not change diff --git a/roles/openaccess/tasks/main.yml b/roles/openaccess/tasks/main.yml index fcc918dcb..6d51a79ab 100644 --- a/roles/openaccess/tasks/main.yml +++ b/roles/openaccess/tasks/main.yml @@ -97,7 +97,7 @@ target: /var/www/favicon.ico type: bind env: - S3_STORAGE_URL : "{{ openconextaccess.s3_storage.url }}" - S3_STORAGE_KEY : "{{ openconextaccess.s3_storage.key }}" - S3_STORAGE_SECRET : "{{ openconextaccess.s3_storage.secret }}" - S3_STORAGE_BUCKET : "{{ openconextaccess.s3_storage.bucket }}" + S3_STORAGE_URL: "{{ openconextaccess.s3_storage.url }}" + S3_STORAGE_KEY: "{{ openconextaccess.s3_storage.key }}" + S3_STORAGE_SECRET: "{{ openconextaccess.s3_storage.secret }}" + S3_STORAGE_BUCKET: "{{ openconextaccess.s3_storage.bucket }}" From 75602e1803c1fd1388e6741c8459762545c03898 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 10:32:25 +0200 Subject: [PATCH 12/46] remove debugging --- roles/openaccess/tasks/main.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/roles/openaccess/tasks/main.yml b/roles/openaccess/tasks/main.yml index 6d51a79ab..5ac1b8035 100644 --- a/roles/openaccess/tasks/main.yml +++ b/roles/openaccess/tasks/main.yml @@ -19,12 +19,6 @@ - serverapplication.yml notify: restart accessserver - -- name: Debug mariadb_in_docker # Show with -vv - ansible.builtin.debug: - msg: "{{ mariadb_in_docker }}" - verbosity: 2 - - name: Add the MariaDB docker network to the list of networks when MariaDB runs in Docker ansible.builtin.set_fact: openaccess_docker_networks: From 70f464c17d3a035fe71cede87209e6e1575e5d33 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 10:32:39 +0200 Subject: [PATCH 13/46] yamllint --- .yamllint.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .yamllint.yaml diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 000000000..8824391dc --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,27 @@ +--- +extends: "default" + +rules: + # 80 chars should be enough, but don't fail if a line is longer + line-length: + max: 160 + level: "warning" + + quoted-strings: + quote-type: "any" + required: true + allow-quoted-quotes: false + check-keys: false + +# ansible-lint compatibility: + comments: + min-spaces-from-content: 1 + + comments-indentation: false + + braces: + max-spaces-inside: 1 + + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true From f9ec3721360f6bd53c7bf5b3c250c426c6abe946 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 11:37:17 +0200 Subject: [PATCH 14/46] yamllint --- roles/openaccess/defaults/main.yml | 4 +- roles/openaccess/handlers/main.yml | 11 ++-- roles/openaccess/tasks/main.yml | 96 +++++++++++++----------------- 3 files changed, 49 insertions(+), 62 deletions(-) diff --git a/roles/openaccess/defaults/main.yml b/roles/openaccess/defaults/main.yml index 888e97b36..f90321a31 100644 --- a/roles/openaccess/defaults/main.yml +++ b/roles/openaccess/defaults/main.yml @@ -1,5 +1,5 @@ --- -openaccess_server_restart_policy: always +openaccess_server_restart_policy: "always" openaccess_server_restart_retries: 0 openaccess_docker_networks: - - name: loadbalancer + - name: "loadbalancer" diff --git a/roles/openaccess/handlers/main.yml b/roles/openaccess/handlers/main.yml index 02ce823ec..0f5bd5880 100644 --- a/roles/openaccess/handlers/main.yml +++ b/roles/openaccess/handlers/main.yml @@ -1,9 +1,10 @@ -- name: Restart accessserver +--- +- name: "Restart accessserver" community.docker.docker_container: - name: accessserver - state: started + name: "accessserver" + state: "started" restart: true # avoid restarting it creates unexpected data loss according to docker_container_module notes comparisons: - '*': ignore - when: accessservercontainer is success and accessservercontainer is not change + '*': "ignore" + when: "accessservercontainer is success and accessservercontainer is not change" diff --git a/roles/openaccess/tasks/main.yml b/roles/openaccess/tasks/main.yml index 5ac1b8035..d56c44218 100644 --- a/roles/openaccess/tasks/main.yml +++ b/roles/openaccess/tasks/main.yml @@ -1,75 +1,61 @@ --- -- name: Create directory to keep configfile +- name: "Create directory to keep configfile" ansible.builtin.file: dest: "/opt/openconext/openaccess" - state: directory - owner: root - group: root + state: "directory" + owner: "root" + group: "root" mode: "0770" -- name: Place the serverapplication configfiles +- name: "Place the serverapplication configfiles" ansible.builtin.template: src: "{{ item }}.j2" - dest: /opt/openconext/openaccess/{{ item }} - owner: root - group: root + dest: "/opt/openconext/openaccess/{{ item }}" + owner: "root" + group: "root" mode: "0644" with_items: - - logback.xml - - serverapplication.yml - notify: restart accessserver + - "logback.xml" + - "serverapplication.yml" + notify: "Restart accessserver" -- name: Add the MariaDB docker network to the list of networks when MariaDB runs in Docker +- name: "Add the MariaDB docker network to the list of networks when MariaDB runs in Docker" ansible.builtin.set_fact: openaccess_docker_networks: - - name: loadbalancer - - name: openconext_mariadb - when: mariadb_in_docker | default(false) | bool + - name: "loadbalancer" + - name: "openconext_mariadb" + when: "mariadb_in_docker | default(false) | bool" -- name: Create and start the access server container +- name: "Create and start the access server container" community.docker.docker_container: - name: accessserver + name: "accessserver" env: TZ: "{{ timezone }}" - image: ghcr.io/openconext/openconext-access/accessserver:{{ openconextaccess_version }} + image: "ghcr.io/openconext/openconext-access/accessserver:{{ openconextaccess_version }}" pull: true restart_policy: "{{ openaccess_server_restart_policy }}" restart_retries: "{{ openaccess_server_restart_retries }}" # Only for restart policy on-failure - state: started + state: "started" networks: "{{ openaccess_docker_networks }}" mounts: - - source: /opt/openconext/openaccess/serverapplication.yml - target: /application.yml - type: bind - - source: /opt/openconext/openaccess/logback.xml - target: /logback.xml - type: bind + - source: "/opt/openconext/openaccess/serverapplication.yml" + target: "/application.yml" + type: "bind" + - source: "/opt/openconext/openaccess/logback.xml" + target: "/logback.xml" + type: "bind" command: "-Xmx512m --spring.config.location=./" etc_hosts: - host.docker.internal: host-gateway - healthcheck: - test: - [ - "CMD", - "wget", - "-no-verbose", - "--tries=1", - "--spider", - "http://localhost:8080/internal/health", - ] - interval: 10s - timeout: 10s - retries: 3 - start_period: 10s - register: accessservercontainer + host.docker.internal: "host-gateway" + register: "accessservercontainer" -- name: Create the access client container +- name: "Create the access client container" community.docker.docker_container: - name: accessgui - image: ghcr.io/openconext/openconext-access/accessclient:{{ openconextaccess_version }} + name: "accessgui" + image: "ghcr.io/openconext/openconext-access/accessclient:{{ openconextaccess_version }}" pull: true restart_policy: "always" - state: started + state: "started" networks: - name: "loadbalancer" labels: @@ -78,18 +64,18 @@ traefik.enable: "true" healthcheck: test: ["CMD", "curl", "--fail", "http://localhost/internal/health"] - interval: 10s - timeout: 10s + interval: "10s" + timeout: "10s" retries: 3 - start_period: 10s - hostname: access + start_period: "10s" + hostname: "access" mounts: - - source: /etc/localtime - target: /etc/localtime - type: bind - - source: /opt/openconext/common/favicon.ico - target: /var/www/favicon.ico - type: bind + - source: "/etc/localtime" + target: "/etc/localtime" + type: "bind" + - source: "/opt/openconext/common/favicon.ico" + target: "/var/www/favicon.ico" + type: "bind" env: S3_STORAGE_URL: "{{ openconextaccess.s3_storage.url }}" S3_STORAGE_KEY: "{{ openconextaccess.s3_storage.key }}" From d947045cb5223f02be181f9dc707349963830ede Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 13:49:14 +0200 Subject: [PATCH 15/46] rename openacces role --- provision.yml | 7 +++---- roles/{openaccess => access_dashboard}/defaults/main.yml | 0 roles/{openaccess => access_dashboard}/handlers/main.yml | 0 roles/{openaccess => access_dashboard}/tasks/main.yml | 0 .../templates/logback.xml.j2 | 0 .../templates/openaccess.conf.j2 | 0 .../templates/serverapplication.yml.j2 | 0 7 files changed, 3 insertions(+), 4 deletions(-) rename roles/{openaccess => access_dashboard}/defaults/main.yml (100%) rename roles/{openaccess => access_dashboard}/handlers/main.yml (100%) rename roles/{openaccess => access_dashboard}/tasks/main.yml (100%) rename roles/{openaccess => access_dashboard}/templates/logback.xml.j2 (100%) rename roles/{openaccess => access_dashboard}/templates/openaccess.conf.j2 (100%) rename roles/{openaccess => access_dashboard}/templates/serverapplication.yml.j2 (100%) diff --git a/provision.yml b/provision.yml index 815d62ee2..51b3565f2 100644 --- a/provision.yml +++ b/provision.yml @@ -199,12 +199,12 @@ - oidc-playground tags: ['oidc-playground'] -- name: Deploy openaccess app & server +- name: Deploy access_dashboard app & server hosts: docker_openaccess become: true roles: - - openaccess - tags: ['openaccess'] + - access_dashboard + tags: ['access_dashboard'] - name: Deploy pdp app hosts: docker_pdp @@ -302,4 +302,3 @@ roles: - { role: mariadbdocker, tags: ['mariadbdocker']} - { role: mongodbdocker, tags: ['mongodbdocker']} - diff --git a/roles/openaccess/defaults/main.yml b/roles/access_dashboard/defaults/main.yml similarity index 100% rename from roles/openaccess/defaults/main.yml rename to roles/access_dashboard/defaults/main.yml diff --git a/roles/openaccess/handlers/main.yml b/roles/access_dashboard/handlers/main.yml similarity index 100% rename from roles/openaccess/handlers/main.yml rename to roles/access_dashboard/handlers/main.yml diff --git a/roles/openaccess/tasks/main.yml b/roles/access_dashboard/tasks/main.yml similarity index 100% rename from roles/openaccess/tasks/main.yml rename to roles/access_dashboard/tasks/main.yml diff --git a/roles/openaccess/templates/logback.xml.j2 b/roles/access_dashboard/templates/logback.xml.j2 similarity index 100% rename from roles/openaccess/templates/logback.xml.j2 rename to roles/access_dashboard/templates/logback.xml.j2 diff --git a/roles/openaccess/templates/openaccess.conf.j2 b/roles/access_dashboard/templates/openaccess.conf.j2 similarity index 100% rename from roles/openaccess/templates/openaccess.conf.j2 rename to roles/access_dashboard/templates/openaccess.conf.j2 diff --git a/roles/openaccess/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 similarity index 100% rename from roles/openaccess/templates/serverapplication.yml.j2 rename to roles/access_dashboard/templates/serverapplication.yml.j2 From 1d1172cea11471c5f3694d547791028e5d36f636 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 14:36:15 +0200 Subject: [PATCH 16/46] linting --- roles/access_dashboard/defaults/main.yml | 2 +- roles/access_dashboard/tasks/main.yml | 8 +- .../access_dashboard/templates/logback.xml.j2 | 42 +++---- .../templates/openaccess.conf.j2 | 115 +++++++++--------- .../templates/serverapplication.yml.j2 | 95 ++++++++------- 5 files changed, 136 insertions(+), 126 deletions(-) diff --git a/roles/access_dashboard/defaults/main.yml b/roles/access_dashboard/defaults/main.yml index 888e97b36..23e66a727 100644 --- a/roles/access_dashboard/defaults/main.yml +++ b/roles/access_dashboard/defaults/main.yml @@ -2,4 +2,4 @@ openaccess_server_restart_policy: always openaccess_server_restart_retries: 0 openaccess_docker_networks: - - name: loadbalancer + - name: "loadbalancer" diff --git a/roles/access_dashboard/tasks/main.yml b/roles/access_dashboard/tasks/main.yml index d56c44218..252eddb02 100644 --- a/roles/access_dashboard/tasks/main.yml +++ b/roles/access_dashboard/tasks/main.yml @@ -28,22 +28,22 @@ - name: "Create and start the access server container" community.docker.docker_container: - name: "accessserver" + name: "access_dashboard_server" env: TZ: "{{ timezone }}" image: "ghcr.io/openconext/openconext-access/accessserver:{{ openconextaccess_version }}" pull: true - restart_policy: "{{ openaccess_server_restart_policy }}" - restart_retries: "{{ openaccess_server_restart_retries }}" # Only for restart policy on-failure state: "started" networks: "{{ openaccess_docker_networks }}" mounts: - source: "/opt/openconext/openaccess/serverapplication.yml" target: "/application.yml" type: "bind" + read_only: true - source: "/opt/openconext/openaccess/logback.xml" target: "/logback.xml" type: "bind" + read_only: true command: "-Xmx512m --spring.config.location=./" etc_hosts: host.docker.internal: "host-gateway" @@ -73,9 +73,11 @@ - source: "/etc/localtime" target: "/etc/localtime" type: "bind" + read_only: true - source: "/opt/openconext/common/favicon.ico" target: "/var/www/favicon.ico" type: "bind" + read_only: true env: S3_STORAGE_URL: "{{ openconextaccess.s3_storage.url }}" S3_STORAGE_KEY: "{{ openconextaccess.s3_storage.key }}" diff --git a/roles/access_dashboard/templates/logback.xml.j2 b/roles/access_dashboard/templates/logback.xml.j2 index f2d82cb6a..7e8d91749 100644 --- a/roles/access_dashboard/templates/logback.xml.j2 +++ b/roles/access_dashboard/templates/logback.xml.j2 @@ -2,28 +2,28 @@ - - - %d{ISO8601} %5p [%t] %logger{40}:%L - %m%n - - + + + %d{ISO8601} %5p [%t] %logger{40}:%L - %m%n + + - - {{ smtp_server }} - {{ noreply_email }} - {{ error_mail_to }} - {{ error_subject_prefix }}Unexpected error in surfaccess - + + {{ smtp_server }} + {{ noreply_email }} + {{ error_mail_to }} + {{ error_subject_prefix }}Unexpected error in surfaccess + - - ERROR - - + + ERROR + + - - - - - + + + + + - \ No newline at end of file + diff --git a/roles/access_dashboard/templates/openaccess.conf.j2 b/roles/access_dashboard/templates/openaccess.conf.j2 index c3236cf4f..886bd22a0 100644 --- a/roles/access_dashboard/templates/openaccess.conf.j2 +++ b/roles/access_dashboard/templates/openaccess.conf.j2 @@ -1,71 +1,70 @@ - # General setup for the virtual host, inherited from global configuration - ServerName https://access.{{ base_domain }} +# General setup for the virtual host, inherited from global configuration +ServerName https://{{ access_dashboard_base_domain }} - ErrorLog "|/usr/bin/logger -S 32k -p local3.err -t 'Apache-access'" - CustomLog "|/usr/bin/logger -S 32k -p local3.info -t 'Apache-access'" combined +ErrorLog "|/usr/bin/logger -S 32k -p local3.err -t 'Apache-access'" +CustomLog "|/usr/bin/logger -S 32k -p local3.info -t 'Apache-access'" combined - RewriteEngine on +RewriteEngine on - RewriteCond %{REQUEST_URI} !\.html$ - RewriteCond %{REQUEST_URI} !\.(js|css)(\.map)?$ - RewriteCond %{REQUEST_URI} !\.svg$ - RewriteCond %{REQUEST_URI} !\.png$ - RewriteCond %{REQUEST_URI} !\.ico$ - RewriteCond %{REQUEST_URI} !\.woff$ - RewriteCond %{REQUEST_URI} !\.woff2$ - RewriteCond %{REQUEST_URI} !\.ttf$ - RewriteCond %{REQUEST_URI} !\.eot$ - RewriteCond %{REQUEST_URI} !^/(asset-)?manifest.json$ - RewriteCond %{REQUEST_URI} !^/access - RewriteCond %{REQUEST_URI} !^/spDashboard - RewriteCond %{REQUEST_URI} !^/health - RewriteCond %{REQUEST_URI} !^/info - RewriteCond %{REQUEST_URI} !^/internal - RewriteCond %{REQUEST_URI} !^/login - RewriteCond %{REQUEST_URI} !^/startSSO - RewriteCond %{REQUEST_URI} !^/fonts - RewriteRule (.*) /index.html [L] +RewriteCond %{REQUEST_URI} !\.html$ +RewriteCond %{REQUEST_URI} !\.(js|css)(\.map)?$ +RewriteCond %{REQUEST_URI} !\.svg$ +RewriteCond %{REQUEST_URI} !\.png$ +RewriteCond %{REQUEST_URI} !\.ico$ +RewriteCond %{REQUEST_URI} !\.woff$ +RewriteCond %{REQUEST_URI} !\.woff2$ +RewriteCond %{REQUEST_URI} !\.ttf$ +RewriteCond %{REQUEST_URI} !\.eot$ +RewriteCond %{REQUEST_URI} !^/(asset-)?manifest.json$ +RewriteCond %{REQUEST_URI} !^/access +RewriteCond %{REQUEST_URI} !^/spDashboard +RewriteCond %{REQUEST_URI} !^/health +RewriteCond %{REQUEST_URI} !^/info +RewriteCond %{REQUEST_URI} !^/internal +RewriteCond %{REQUEST_URI} !^/login +RewriteCond %{REQUEST_URI} !^/startSSO +RewriteCond %{REQUEST_URI} !^/fonts +RewriteRule (.*) /index.html [L] - ProxyPreserveHost On - ProxyPass /Shibboleth.sso ! - ProxyPass /access/api http://accessserver:8080/access/api retry=0 - ProxyPassReverse /access/api http://accessserver:8080/access/api +ProxyPreserveHost On +ProxyPass /Shibboleth.sso ! +ProxyPass /access/api http://access_dashboard_server:8080/access/api retry=0 +ProxyPassReverse /access/api http://access_dashboard_server:8080/access/api - ProxyPass /health http://accessserver:8080/internal/health retry=0 - ProxyPass /info http://accessserver:8080/internal/info retry=0 - ProxyPass /login http://accessserver:8080/login retry=0 - ProxyPass /startSSO http://accessserver:8080/startSSO retry=0 +ProxyPass /health http://access_dashboard_server:8080/internal/health retry=0 +ProxyPass /info http://access_dashboard_server:8080/internal/info retry=0 +ProxyPass /login http://access_dashboard_server:8080/login retry=0 +ProxyPass /startSSO http://access_dashboard_server:8080/startSSO retry=0 - ProxyPass /internal http://accessserver:8080/internal retry=0 - ProxyPassReverse /internal http://accessserver:8080/internal +ProxyPass /internal http://access_dashboard_server:8080/internal retry=0 +ProxyPassReverse /internal http://access_dashboard_server:8080/internal - - AuthType shibboleth - ShibUseHeaders On - ShibRequireSession On - ShibRequestSetting REMOTE_ADDR X-Forwarded-For - Require valid-user - + + AuthType shibboleth + ShibUseHeaders On + ShibRequireSession On + ShibRequestSetting REMOTE_ADDR X-Forwarded-For + Require valid-user + - DocumentRoot "/var/www/" +DocumentRoot "/var/www/" - - Require all granted - + + Require all granted + - - Require all granted - + + Require all granted + - - Require all granted - + + Require all granted + - - Require all granted - - - Header always set X-Frame-Options "DENY" - Header always set Referrer-Policy "strict-origin-when-cross-origin" - Header always set X-Content-Type-Options "nosniff" + + Require all granted + +Header always set X-Frame-Options "DENY" +Header always set Referrer-Policy "strict-origin-when-cross-origin" +Header always set X-Content-Type-Options "nosniff" diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 3286c53bb..8bb47955b 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -6,8 +6,8 @@ server: port: 8080 error: path: "/error" - include-message: always - forward-headers-strategy: framework + include-message: "always" + forward-headers-strategy: "framework" servlet: session: cookie: @@ -26,10 +26,10 @@ spring: {% else %} cleanup-cron: "0 */5 * * * *" {% endif %} - flush-mode: on_save - save-mode: on_set_attribute - store-type: jdbc - timeout: 8h + flush-mode: "on_save" + save-mode: "on_set_attribute" + store-type: "jdbc" + timeout: "8h" mvc: log-request-details: false security: @@ -41,40 +41,41 @@ spring: client-secret: {{ openconextaccess.oidcng.secret }} redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" authorization-grant-type: "authorization_code" - scope: openid + scope: "openid" provider: oidcng: authorization-uri: {{ openconextaccess.oidcng.authorization_uri }} token-uri: {{ openconextaccess.oidcng.token_uri }} user-info-uri: {{ openconextaccess.oidcng.user_info_uri }} jwk-set-uri: {{ openconextaccess.oidcng.jwk_set_uri }} - user-name-attribute: sub - user-info-authentication-method: client_secret_basic + user-name-attribute: "sub" + user-info-authentication-method: "client_secret_basic" jpa: properties: hibernate: - naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy + naming-strategy: "org.hibernate.cfg.ImprovedNamingStrategy" format_sql: false show_sql: false open-in-view: false show-sql: false datasource: - driver-class-name: org.mariadb.jdbc.Driver url: jdbc:mariadb://{{ openconextaccess.db.host }}/openconextaccess?autoReconnect=true username: {{ openconextaccess.db.user }} password: {{ openconextaccess.db.secret }} + driver-class-name: "org.mariadb.jdbc.Driver" flyway: - locations: classpath:db/mysql/migration + locations: "classpath:db/mysql/migration" fail-on-missing-locations: true mail: - host: {{ smtp_server }} + host: "{{ smtp_server }}" oidcng: - discovery-url: {{ openconextaccess.oidcng.discovery_url }} - introspect-url: {{ openconextaccess.oidcng.introspect_url }} - resource-server-id: myconext.rs - resource-server-secret: secret - base-url: {{ openconextaccess_base_domain }} + discovery-url: "{{ access_dashboard.oidcng.discovery_url }}" + introspect-url: "{{ access_dashboard.oidcng.introspect_url }}" + #TODO + resource-server-id: "myconext.rs" + resource-server-secret: "secret" + base-url: "{{ access_dashboard_base_domain }}" cron: user-cleaner-cron: "PT60M" @@ -87,8 +88,8 @@ cron: user-inactivity-delete-days: 1095 lifecycle: - user: lifecycle password: {{ openconextaccess_lifecycle_secret }} + user: "lifecycle" jira: enabled: true @@ -120,22 +121,30 @@ config: identity_providers: - name: "SXS IdP" entityid: "http://mock-idp" - descriptionEN: "A test IdP that allows you to simulate attribute sets yourself. You can find the metadata here" - descriptionNL: "Een test-IdP waarmee je zelf attributen-sets kunt simuleren. De metadata vind je hier" + descriptionEN: > + A test IdP that allows you to simulate attribute sets yourself. + You can find the metadata here + descriptionNL: > + Een test-IdP waarmee je zelf attributen-sets kunt simuleren. + De metadata vind je hier - name: "SXS Dummy" entityid: "https://idp.diy.surfconext.nl" - descriptionEN: "A test IdP with fictitious user accounts. You can find the metadata here" - descriptionNL: "Een test-IdP met fictieve gebruikersaccounts. De metadata vind je hier" - idp_proxy_meta_data: {{ openconextaccess.idp_proxy_meta_data }} + descriptionEN: > + A test IdP with fictitious user accounts. + You can find the metadata here" + descriptionNL: > + Een test-IdP met fictieve gebruikersaccounts. + De metadata vind je hier" + idp_proxy_meta_data: "{{ access_dashboard.idp_proxy_meta_data }}" minimal_stepup_acr_level: "http://{{ base_domain }}/assurance/loa2" features: - - name: idp + - name: "idp" enabled: true - - name: invite + - name: "invite" enabled: true - - name: sram + - name: "sram" enabled: true - - name: mfa + - name: "mfa" enabled: true acr_values: {% for loa in [stepup_intrinsic_loa] + stepup_loa_values_supported %} @@ -154,9 +163,9 @@ gui: content: {{ environment_shortname }} feature: - enable-performance-seed: False - statistics-enabled: False - stepup-required: False + enable-performance-seed: false + statistics-enabled: false + stepup-required: false email: from: "{{ noreply_email }}" @@ -171,14 +180,14 @@ manage: url: {{ openconextaccess.manage.url }} user: {{ openconextaccess.manage.user }} password: {{ openconextaccess.manage.password }} - defaultState: testaccepted + defaultState: "testaccepted" # If manage is disabled (e.g. enabled: False) the staticManageDirectory is the directory where the {metadata_type}.json files # are located. This can also be an absolute file path, e.g. file:///opt/openconext/invite/manage - staticManageDirectory: classpath:/manage + staticManageDirectory: "classpath:/manage" # staticManageDirectory: file:///usr/local/etc/manage invite: - enabled: True + enabled: true url: "https://invite.{{ base_domain }}" user: {{ invite.access_user }} password: "{{ invite.access_secret }}" @@ -208,10 +217,10 @@ springdoc: swagger-ui: path: "/ui/api-ui.html" enabled: false - operationsSorter: method + operationsSorter: "method" oauth: - client-id: ${spring.security.oauth2.client.registration.oidcng.client-id} - client-secret: ${spring.security.oauth2.client.registration.oidcng.client-secret} + client-id: "${spring.security.oauth2.client.registration.oidcng.client-id}" + client-secret: "${spring.security.oauth2.client.registration.oidcng.client-secret}" use-basic-authentication-with-access-code-grant: true management: @@ -225,17 +234,17 @@ management: base-path: "/internal" endpoint: info: - access: unrestricted + access: "unrestricted" health: - access: unrestricted - show-details: always + access: "unrestricted" + show-details: "always" mappings: - access: none + access: "none" metrics: - access: none + access: "none" info: git: - mode: full + mode: "full" # used by the git plugin info: From de95b094a4af710770e2d64ae6aed1124d39a0b6 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 15:01:42 +0200 Subject: [PATCH 17/46] rename openconextaccess_* to access_dashboard_* --- .../template/secrets/secret_example.yml | 2 +- roles/access_dashboard/defaults/main.yml | 5 +- roles/access_dashboard/handlers/main.yml | 2 +- roles/access_dashboard/tasks/main.yml | 29 +++---- .../templates/serverapplication.yml.j2 | 75 ++++++++++--------- .../invite/templates/serverapplication.yml.j2 | 4 +- 6 files changed, 56 insertions(+), 61 deletions(-) diff --git a/environments/template/secrets/secret_example.yml b/environments/template/secrets/secret_example.yml index 8b8e69309..a6c052658 100644 --- a/environments/template/secrets/secret_example.yml +++ b/environments/template/secrets/secret_example.yml @@ -141,7 +141,7 @@ invite_lifecycle_secret: "secret" invite_internal_secret: "secret" invite_profile_secret: "secret" invite_sp_dashboard_secret: "secret" -invite_access_secret: "secret" +invite_access_dashboard_secret: "secret" invite_private_key_pkcs8: | -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCfpYYMgKYDICkp diff --git a/roles/access_dashboard/defaults/main.yml b/roles/access_dashboard/defaults/main.yml index 23e66a727..a92af8fe9 100644 --- a/roles/access_dashboard/defaults/main.yml +++ b/roles/access_dashboard/defaults/main.yml @@ -1,5 +1,4 @@ --- -openaccess_server_restart_policy: always -openaccess_server_restart_retries: 0 -openaccess_docker_networks: +access_dashboard_docker_networks: - name: "loadbalancer" +access_dashboard_cronjobmaster: true diff --git a/roles/access_dashboard/handlers/main.yml b/roles/access_dashboard/handlers/main.yml index 0f5bd5880..f100ec4a6 100644 --- a/roles/access_dashboard/handlers/main.yml +++ b/roles/access_dashboard/handlers/main.yml @@ -7,4 +7,4 @@ # avoid restarting it creates unexpected data loss according to docker_container_module notes comparisons: '*': "ignore" - when: "accessservercontainer is success and accessservercontainer is not change" + when: "access_dashboard_server_container is success and access_dashboard_server_container is not change" diff --git a/roles/access_dashboard/tasks/main.yml b/roles/access_dashboard/tasks/main.yml index 252eddb02..c863f064e 100644 --- a/roles/access_dashboard/tasks/main.yml +++ b/roles/access_dashboard/tasks/main.yml @@ -21,7 +21,7 @@ - name: "Add the MariaDB docker network to the list of networks when MariaDB runs in Docker" ansible.builtin.set_fact: - openaccess_docker_networks: + access_dashboard_docker_networks: - name: "loadbalancer" - name: "openconext_mariadb" when: "mariadb_in_docker | default(false) | bool" @@ -31,10 +31,11 @@ name: "access_dashboard_server" env: TZ: "{{ timezone }}" - image: "ghcr.io/openconext/openconext-access/accessserver:{{ openconextaccess_version }}" + image: "ghcr.io/openconext/openconext-access/accessserver:{{ access_dashboard_version }}" pull: true + restart_policy: "always" state: "started" - networks: "{{ openaccess_docker_networks }}" + networks: "{{ access_dashboard_docker_networks }}" mounts: - source: "/opt/openconext/openaccess/serverapplication.yml" target: "/application.yml" @@ -47,27 +48,21 @@ command: "-Xmx512m --spring.config.location=./" etc_hosts: host.docker.internal: "host-gateway" - register: "accessservercontainer" + register: "access_dashboard_server_container" - name: "Create the access client container" community.docker.docker_container: - name: "accessgui" - image: "ghcr.io/openconext/openconext-access/accessclient:{{ openconextaccess_version }}" + name: "access_dashboard_gui" + image: "ghcr.io/openconext/openconext-access/accessclient:{{ access_dashboard_version }}" pull: true restart_policy: "always" state: "started" networks: - name: "loadbalancer" labels: - traefik.http.routers.accessclient.rule: "Host(`{{ openconextaccess_base_domain }}`)" + traefik.http.routers.accessclient.rule: "Host(`{{ access_dashboard_base_domain }}`)" traefik.http.routers.accessclient.tls: "true" traefik.enable: "true" - healthcheck: - test: ["CMD", "curl", "--fail", "http://localhost/internal/health"] - interval: "10s" - timeout: "10s" - retries: 3 - start_period: "10s" hostname: "access" mounts: - source: "/etc/localtime" @@ -79,7 +74,7 @@ type: "bind" read_only: true env: - S3_STORAGE_URL: "{{ openconextaccess.s3_storage.url }}" - S3_STORAGE_KEY: "{{ openconextaccess.s3_storage.key }}" - S3_STORAGE_SECRET: "{{ openconextaccess.s3_storage.secret }}" - S3_STORAGE_BUCKET: "{{ openconextaccess.s3_storage.bucket }}" + S3_STORAGE_URL: "{{ access_dashboard.s3_storage.url }}" + S3_STORAGE_KEY: "{{ access_dashboard.s3_storage.key }}" + S3_STORAGE_SECRET: "{{ access_dashboard.s3_storage.secret }}" + S3_STORAGE_BUCKET: "{{ access_dashboard.s3_storage.bucket }}" diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 8bb47955b..6dee531ed 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -21,7 +21,7 @@ spring: session: jdbc: initialize-schema: never -{% if openaccess_cronjobmaster is defined and openaccess_cronjobmaster == false %} +{% if access_dashboard_cronjobmaster is defined and access_dashboard_cronjobmaster == false %} cleanup-cron: "-" {% else %} cleanup-cron: "0 */5 * * * *" @@ -37,17 +37,17 @@ spring: client: registration: oidcng: - client-id: {{ openconextaccess.oidcng.client_id }} - client-secret: {{ openconextaccess.oidcng.secret }} + client-id: "{{ access_dashboard.oidcng.client_id }}" + client-secret: "{{ access_dashboard.oidcng.secret }}" redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}" authorization-grant-type: "authorization_code" scope: "openid" provider: oidcng: - authorization-uri: {{ openconextaccess.oidcng.authorization_uri }} - token-uri: {{ openconextaccess.oidcng.token_uri }} - user-info-uri: {{ openconextaccess.oidcng.user_info_uri }} - jwk-set-uri: {{ openconextaccess.oidcng.jwk_set_uri }} + authorization-uri: "{{ access_dashboard.oidcng.authorization_uri }}" + token-uri: "{{ access_dashboard.oidcng.token_uri }}" + user-info-uri: "{{ access_dashboard.oidcng.user_info_uri }}" + jwk-set-uri: "{{ access_dashboard.oidcng.jwk_set_uri }}" user-name-attribute: "sub" user-info-authentication-method: "client_secret_basic" jpa: @@ -59,10 +59,10 @@ spring: open-in-view: false show-sql: false datasource: - url: jdbc:mariadb://{{ openconextaccess.db.host }}/openconextaccess?autoReconnect=true - username: {{ openconextaccess.db.user }} - password: {{ openconextaccess.db.secret }} driver-class-name: "org.mariadb.jdbc.Driver" + url: "jdbc:mariadb://{{ access_dashboard.db.host }}/access_dashboard?autoReconnect=true" + username: "{{ access_dashboard.db.user }}" + password: "{{ access_dashboard.db.secret }}" flyway: locations: "classpath:db/mysql/migration" fail-on-missing-locations: true @@ -88,16 +88,16 @@ cron: user-inactivity-delete-days: 1095 lifecycle: - password: {{ openconextaccess_lifecycle_secret }} user: "lifecycle" + password: "{{ access_dashboard_lifecycle_secret }}" jira: enabled: true - base-url: {{ openconextaccess.jira.base_url }} - user-name: {{ openconextaccess.jira.username }} - project-key: {{ openconextaccess.jira.project_key }} - environment: {{ openconextaccess.jira.environment }} - api-key: {{ openconextaccess.jira.api_key }} + base-url: "{{ access_dashboard.jira.base_url }}" + user-name: "{{ access_dashboard.jira.username }}" + project-key: "{{ access_dashboard.jira.project_key }}" + environment: "{{ access_dashboard.jira.environment }}" + api-key: "{{ access_dashboard.jira.api_key }}" # Timeout in milliseconds connection-timeout: 10000 @@ -106,7 +106,7 @@ institution-admin: organization-guid-prefix: "urn:mace:surfnet.nl:surfnet.nl:sab:organizationGUID:" config: - client-url: "https://{{ openconextaccess_base_domain }}" + client-url: "https://{{ access_dashboard_base_domain }}" base-url: "{{ base_domain }}" edu_id_schac_home_organization: "eduid.nl" surf_schac_home_organization: "example.com" @@ -115,8 +115,8 @@ config: sram: "https://{{ env }}.sram.surf.nl/" service_desk: "https://servicedesk.surf.nl/jira/plugins/servlet/desk/user/requests?reporter=all" feedback_widget_enabled: true - demo_seed_enabled: {{ openconextaccess.demo_seed_enabled }} - test_environment: {{ openconextaccess.test_environment }} + demo_seed_enabled: "{{ access_dashboard.demo_seed_enabled }}" + test_environment: "{{ access_dashboard.test_environment }}" # For other environments, move to group_vars identity_providers: - name: "SXS IdP" @@ -151,16 +151,17 @@ config: - "{{ loa }}" {% endfor %} -eduid-idp-entity-id: {{ openconextaccess.eduid_idp_entity_id }} +eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}" +# TODO super-admin: users: - "urn:collab:person:example.com:admin" gui: disclaimer: - background-color: {{ environment_ribbon_colour }} - content: {{ environment_shortname }} + background-color: "{{ environment_ribbon_colour }}" + content: "{{ environment_shortname }}" feature: enable-performance-seed: false @@ -176,10 +177,10 @@ email: environment: "{{ environment_shortname }}" manage: - enabled: True - url: {{ openconextaccess.manage.url }} - user: {{ openconextaccess.manage.user }} - password: {{ openconextaccess.manage.password }} + enabled: true + url: "{{ access_dashboard.manage.url }}" + user: "{{ access_dashboard.manage.user }}" + password: "{{ access_dashboard.manage.password }}" defaultState: "testaccepted" # If manage is disabled (e.g. enabled: False) the staticManageDirectory is the directory where the {metadata_type}.json files # are located. This can also be an absolute file path, e.g. file:///opt/openconext/invite/manage @@ -189,23 +190,23 @@ manage: invite: enabled: true url: "https://invite.{{ base_domain }}" - user: {{ invite.access_user }} - password: "{{ invite.access_secret }}" + user: "{{ invite.access_dashboard_user }}" + password: "{{ invite.access_dashboard_secret }}" statistics: - enabled: {{ openconextaccess.statistics.enabled }} - url: {{ openconextaccess.statistics.url }} - user: {{ openconextaccess.statistics.user }} - password: {{ openconextaccess.statistics.password }} + enabled: "{{ access_dashboard.statistics.enabled }}" + url: "{{ access_dashboard.statistics.url }}" + user: "{{ access_dashboard.statistics.user }}" + password: "{{ access_dashboard.statistics.password }}" s3storage: - url: {{ openconextaccess.s3_storage.url }} - key: {{ openconextaccess.s3_storage.key }} - secret: {{ openconextaccess.s3_storage.secret }} - bucket: {{ openconextaccess.s3_storage.bucket }} + url: "{{ access_dashboard.s3_storage.url }}" + key: "{{ access_dashboard.s3_storage.key }}" + secret: "{{ access_dashboard.s3_storage.secret }}" + bucket: "{{ access_dashboard.s3_storage.bucket }}" ohdear: - apiKey: {{ openconextaccess_ohdear_apikey }} + apiKey: "{{ access_dashboard_ohdear_apikey }}" baseUrl: "https://ohdear.app/api" enabled: true diff --git a/roles/invite/templates/serverapplication.yml.j2 b/roles/invite/templates/serverapplication.yml.j2 index ceffe41f0..99ca6c521 100644 --- a/roles/invite/templates/serverapplication.yml.j2 +++ b/roles/invite/templates/serverapplication.yml.j2 @@ -190,8 +190,8 @@ external-api-configuration: applications: - manageId: {{ invite.sp_dashboard_manage_id }} manageType: SAML20_SP - - username: {{ invite.access_user }} - password: "{{ invite.access_secret }}" + - username: "{{ invite.access_dashboard_user }}" + password: "{{ invite.access_dashboard_secret }}" organizationGUIDFallback: {{ invite.surf_idp_organization_guid }} scopes: - access From bcaa1166ccf840a21318c1885c92a447863c9788 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 16:08:17 +0200 Subject: [PATCH 18/46] Fix access_dashboard directory --- roles/access_dashboard/tasks/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/access_dashboard/tasks/main.yml b/roles/access_dashboard/tasks/main.yml index c863f064e..febb5dcfa 100644 --- a/roles/access_dashboard/tasks/main.yml +++ b/roles/access_dashboard/tasks/main.yml @@ -1,7 +1,7 @@ --- - name: "Create directory to keep configfile" ansible.builtin.file: - dest: "/opt/openconext/openaccess" + dest: "/opt/openconext/access_dashboard" state: "directory" owner: "root" group: "root" @@ -10,7 +10,7 @@ - name: "Place the serverapplication configfiles" ansible.builtin.template: src: "{{ item }}.j2" - dest: "/opt/openconext/openaccess/{{ item }}" + dest: "/opt/openconext/access_dashboard/{{ item }}" owner: "root" group: "root" mode: "0644" @@ -37,11 +37,11 @@ state: "started" networks: "{{ access_dashboard_docker_networks }}" mounts: - - source: "/opt/openconext/openaccess/serverapplication.yml" + - source: "/opt/openconext/access_dashboard/serverapplication.yml" target: "/application.yml" type: "bind" read_only: true - - source: "/opt/openconext/openaccess/logback.xml" + - source: "/opt/openconext/access_dashboard/logback.xml" target: "/logback.xml" type: "bind" read_only: true From 5ce14a03827e31fb15641d7afa3e3df1930aab75 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 16:23:34 +0200 Subject: [PATCH 19/46] actually use local apache config --- roles/access_dashboard/tasks/main.yml | 20 +++++++++++++++++-- ...{openaccess.conf.j2 => apache_gui.conf.j2} | 0 2 files changed, 18 insertions(+), 2 deletions(-) rename roles/access_dashboard/templates/{openaccess.conf.j2 => apache_gui.conf.j2} (100%) diff --git a/roles/access_dashboard/tasks/main.yml b/roles/access_dashboard/tasks/main.yml index febb5dcfa..39f88a043 100644 --- a/roles/access_dashboard/tasks/main.yml +++ b/roles/access_dashboard/tasks/main.yml @@ -7,16 +7,28 @@ group: "root" mode: "0770" -- name: "Place the serverapplication configfiles" +- name: "Place the server configfiles" ansible.builtin.template: src: "{{ item }}.j2" dest: "/opt/openconext/access_dashboard/{{ item }}" owner: "root" group: "root" - mode: "0644" + mode: "0600" with_items: - "logback.xml" - "serverapplication.yml" + - "apache_gui.conf" + notify: "Restart accessserver" + +- name: "Place the gui configfiles" + ansible.builtin.template: + src: "{{ item }}.j2" + dest: "/opt/openconext/access_dashboard/{{ item }}" + owner: "root" + group: "root" + mode: "0600" + with_items: + - "apache_gui.conf" notify: "Restart accessserver" - name: "Add the MariaDB docker network to the list of networks when MariaDB runs in Docker" @@ -69,6 +81,10 @@ target: "/etc/localtime" type: "bind" read_only: true + - source: "/opt/openconext/access_dashboard/apache_gui.conf" + target: "/etc/apache2/sites-enabled/appconf.conf" + type: "bind" + read_only: true - source: "/opt/openconext/common/favicon.ico" target: "/var/www/favicon.ico" type: "bind" diff --git a/roles/access_dashboard/templates/openaccess.conf.j2 b/roles/access_dashboard/templates/apache_gui.conf.j2 similarity index 100% rename from roles/access_dashboard/templates/openaccess.conf.j2 rename to roles/access_dashboard/templates/apache_gui.conf.j2 From 331093deebe5a99c030fabaa7370371d3ff53c5b Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 16:29:58 +0200 Subject: [PATCH 20/46] fix server name --- roles/access_dashboard/handlers/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/access_dashboard/handlers/main.yml b/roles/access_dashboard/handlers/main.yml index f100ec4a6..6eb71c4e2 100644 --- a/roles/access_dashboard/handlers/main.yml +++ b/roles/access_dashboard/handlers/main.yml @@ -1,7 +1,7 @@ --- - name: "Restart accessserver" community.docker.docker_container: - name: "accessserver" + name: "access_dashboard_server" state: "started" restart: true # avoid restarting it creates unexpected data loss according to docker_container_module notes From 28c9baa35313ef873761f03c3b7de6556692ea45 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 16:34:11 +0200 Subject: [PATCH 21/46] Fix access dashboard gui apache config --- .../templates/apache_gui.conf.j2 | 85 ++++++++----------- 1 file changed, 37 insertions(+), 48 deletions(-) diff --git a/roles/access_dashboard/templates/apache_gui.conf.j2 b/roles/access_dashboard/templates/apache_gui.conf.j2 index 886bd22a0..fe1cbcc8e 100644 --- a/roles/access_dashboard/templates/apache_gui.conf.j2 +++ b/roles/access_dashboard/templates/apache_gui.conf.j2 @@ -1,12 +1,6 @@ -# General setup for the virtual host, inherited from global configuration -ServerName https://{{ access_dashboard_base_domain }} +ServerName access_dashboard_client -ErrorLog "|/usr/bin/logger -S 32k -p local3.err -t 'Apache-access'" -CustomLog "|/usr/bin/logger -S 32k -p local3.info -t 'Apache-access'" combined - -RewriteEngine on - -RewriteCond %{REQUEST_URI} !\.html$ +RewriteEngine On RewriteCond %{REQUEST_URI} !\.(js|css)(\.map)?$ RewriteCond %{REQUEST_URI} !\.svg$ RewriteCond %{REQUEST_URI} !\.png$ @@ -14,56 +8,51 @@ RewriteCond %{REQUEST_URI} !\.ico$ RewriteCond %{REQUEST_URI} !\.woff$ RewriteCond %{REQUEST_URI} !\.woff2$ RewriteCond %{REQUEST_URI} !\.ttf$ +RewriteCond %{REQUEST_URI} !\.wav$ RewriteCond %{REQUEST_URI} !\.eot$ RewriteCond %{REQUEST_URI} !^/(asset-)?manifest.json$ -RewriteCond %{REQUEST_URI} !^/access -RewriteCond %{REQUEST_URI} !^/spDashboard -RewriteCond %{REQUEST_URI} !^/health -RewriteCond %{REQUEST_URI} !^/info -RewriteCond %{REQUEST_URI} !^/internal -RewriteCond %{REQUEST_URI} !^/login -RewriteCond %{REQUEST_URI} !^/startSSO -RewriteCond %{REQUEST_URI} !^/fonts +RewriteCond %{REQUEST_URI} !^/api/ +RewriteCond %{REQUEST_URI} !^/login/ +RewriteCond %{REQUEST_URI} !^/oauth2/ +RewriteCond %{REQUEST_URI} !^/ui/ +RewriteCond %{REQUEST_URI} !^/internal/ +RewriteCond %{REQUEST_URI} !^/fonts/ RewriteRule (.*) /index.html [L] -ProxyPreserveHost On -ProxyPass /Shibboleth.sso ! -ProxyPass /access/api http://access_dashboard_server:8080/access/api retry=0 -ProxyPassReverse /access/api http://access_dashboard_server:8080/access/api - -ProxyPass /health http://access_dashboard_server:8080/internal/health retry=0 -ProxyPass /info http://access_dashboard_server:8080/internal/info retry=0 -ProxyPass /login http://access_dashboard_server:8080/login retry=0 -ProxyPass /startSSO http://access_dashboard_server:8080/startSSO retry=0 - -ProxyPass /internal http://access_dashboard_server:8080/internal retry=0 +ProxyPass /api http://access_dashboard_server:8080/api retry=0 +ProxyPassReverse /api http://access_dashboard_server:8080/api +ProxyPassMatch ^/oauth2(.*)$ http://access_dashboard_server:8080 +ProxyPassReverse /oauth2 http://access_dashboard_server:8080/oauth2 +ProxyPassMatch ^/internal(.*)$ http://access_dashboard_server:8080 ProxyPassReverse /internal http://access_dashboard_server:8080/internal +ProxyPassMatch ^/login(.*)$ http://access_dashboard_server:8080 +ProxyPassReverse /login http://access_dashboard_server:8080/login +ProxyPassMatch ^/ui(.*)$ http://access_dashboard_server:8080 +ProxyPassReverse /ui http://access_dashboard_server:8080/ui - - AuthType shibboleth - ShibUseHeaders On - ShibRequireSession On - ShibRequestSetting REMOTE_ADDR X-Forwarded-For - Require valid-user - - -DocumentRoot "/var/www/" - - - Require all granted - +DocumentRoot /var/www/ - - Require all granted + + ProxyPreserveHost On - - - Require all granted + + ProxyPreserveHost On - - - Require all granted + + ProxyPreserveHost On + + ProxyPreserveHost On + + + Require all granted + Options -Indexes + + + +Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" +Header set Expires "Sun, 8 Jun 1986 08:06:00 GMT" + Header always set X-Frame-Options "DENY" Header always set Referrer-Policy "strict-origin-when-cross-origin" From 936865b91c8f0da3333f991bd9f307658b2811fd Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 16:35:56 +0200 Subject: [PATCH 22/46] correctly restart gui container --- roles/access_dashboard/handlers/main.yml | 12 +++++++++++- roles/access_dashboard/tasks/main.yml | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/roles/access_dashboard/handlers/main.yml b/roles/access_dashboard/handlers/main.yml index 6eb71c4e2..6f9ea714a 100644 --- a/roles/access_dashboard/handlers/main.yml +++ b/roles/access_dashboard/handlers/main.yml @@ -1,5 +1,5 @@ --- -- name: "Restart accessserver" +- name: "Restart access dashboard server" community.docker.docker_container: name: "access_dashboard_server" state: "started" @@ -8,3 +8,13 @@ comparisons: '*': "ignore" when: "access_dashboard_server_container is success and access_dashboard_server_container is not change" + +- name: "Restart access dashboard gui" + community.docker.docker_container: + name: "access_dashboard_gui" + state: "started" + restart: true + # avoid restarting it creates unexpected data loss according to docker_container_module notes + comparisons: + '*': "ignore" + when: "access_dashboard_gui_container is success and access_dashboard_gui_container is not change" diff --git a/roles/access_dashboard/tasks/main.yml b/roles/access_dashboard/tasks/main.yml index 39f88a043..09fffab69 100644 --- a/roles/access_dashboard/tasks/main.yml +++ b/roles/access_dashboard/tasks/main.yml @@ -18,7 +18,7 @@ - "logback.xml" - "serverapplication.yml" - "apache_gui.conf" - notify: "Restart accessserver" + notify: "Restart access dashboard server" - name: "Place the gui configfiles" ansible.builtin.template: @@ -29,7 +29,7 @@ mode: "0600" with_items: - "apache_gui.conf" - notify: "Restart accessserver" + notify: "Restart access dashboard gui" - name: "Add the MariaDB docker network to the list of networks when MariaDB runs in Docker" ansible.builtin.set_fact: @@ -94,3 +94,4 @@ S3_STORAGE_KEY: "{{ access_dashboard.s3_storage.key }}" S3_STORAGE_SECRET: "{{ access_dashboard.s3_storage.secret }}" S3_STORAGE_BUCKET: "{{ access_dashboard.s3_storage.bucket }}" + register: "access_dashboard_gui_container" From ba0bd97c0c620c802deeb3d6a6ee1b97cd408190 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 16:37:53 +0200 Subject: [PATCH 23/46] test --- roles/access_dashboard/templates/apache_gui.conf.j2 | 1 + 1 file changed, 1 insertion(+) diff --git a/roles/access_dashboard/templates/apache_gui.conf.j2 b/roles/access_dashboard/templates/apache_gui.conf.j2 index fe1cbcc8e..7f62d9734 100644 --- a/roles/access_dashboard/templates/apache_gui.conf.j2 +++ b/roles/access_dashboard/templates/apache_gui.conf.j2 @@ -54,6 +54,7 @@ Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" Header set Expires "Sun, 8 Jun 1986 08:06:00 GMT" + Header always set X-Frame-Options "DENY" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set X-Content-Type-Options "nosniff" From dbfc90027a25bb9ee26d6846a720804189db3baa Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 4 Jun 2026 16:39:06 +0200 Subject: [PATCH 24/46] Fix file install --- roles/access_dashboard/tasks/main.yml | 1 - roles/access_dashboard/templates/apache_gui.conf.j2 | 1 - 2 files changed, 2 deletions(-) diff --git a/roles/access_dashboard/tasks/main.yml b/roles/access_dashboard/tasks/main.yml index 09fffab69..0291f8581 100644 --- a/roles/access_dashboard/tasks/main.yml +++ b/roles/access_dashboard/tasks/main.yml @@ -17,7 +17,6 @@ with_items: - "logback.xml" - "serverapplication.yml" - - "apache_gui.conf" notify: "Restart access dashboard server" - name: "Place the gui configfiles" diff --git a/roles/access_dashboard/templates/apache_gui.conf.j2 b/roles/access_dashboard/templates/apache_gui.conf.j2 index 7f62d9734..fe1cbcc8e 100644 --- a/roles/access_dashboard/templates/apache_gui.conf.j2 +++ b/roles/access_dashboard/templates/apache_gui.conf.j2 @@ -54,7 +54,6 @@ Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate" Header set Expires "Sun, 8 Jun 1986 08:06:00 GMT" - Header always set X-Frame-Options "DENY" Header always set Referrer-Policy "strict-origin-when-cross-origin" Header always set X-Content-Type-Options "nosniff" From 7df220dcab91b4481a56b787c5664576f639dc9e Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 5 Jun 2026 10:44:51 +0200 Subject: [PATCH 25/46] Make sure mariadbdocker only runs on test --- roles/mariadbdocker/tasks/main.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/roles/mariadbdocker/tasks/main.yml b/roles/mariadbdocker/tasks/main.yml index 8945d7e6f..204c8fa52 100644 --- a/roles/mariadbdocker/tasks/main.yml +++ b/roles/mariadbdocker/tasks/main.yml @@ -1,4 +1,8 @@ --- +- name: "Check that we're running on test" + ansible.builtin.meta: "noop" + failed_when: "env != 'test'" + - name: Create MariaDB volume community.docker.docker_volume: name: openconext_mariadb From 7efcb9ed8ebaa611532d129a15b3126a1ab4223b Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 5 Jun 2026 10:46:25 +0200 Subject: [PATCH 26/46] show which users are created --- roles/mariadbdocker/tasks/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/mariadbdocker/tasks/main.yml b/roles/mariadbdocker/tasks/main.yml index 204c8fa52..fb94397ad 100644 --- a/roles/mariadbdocker/tasks/main.yml +++ b/roles/mariadbdocker/tasks/main.yml @@ -72,7 +72,7 @@ login_user: root login_host: localhost login_password: "{{ mariadb_root_password }}" - no_log: true +# no_log: true with_nested: - "{{ databases.users }}" - "{{ database_clients }}" From 6a3451a2a0cbf69fd95bd37ca612abcc6f350517 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 5 Jun 2026 10:50:58 +0200 Subject: [PATCH 27/46] log only name --- roles/mariadbdocker/tasks/main.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/roles/mariadbdocker/tasks/main.yml b/roles/mariadbdocker/tasks/main.yml index fb94397ad..1c99dcc8e 100644 --- a/roles/mariadbdocker/tasks/main.yml +++ b/roles/mariadbdocker/tasks/main.yml @@ -61,7 +61,7 @@ with_items: - "{{ databases.names }}" -- name: Create database user +- name: Create database users community.mysql.mysql_user: name: "{{ item[0].name }}" host: "{{ item[1] }}" @@ -72,10 +72,9 @@ login_user: root login_host: localhost login_password: "{{ mariadb_root_password }}" -# no_log: true - with_nested: - - "{{ databases.users }}" - - "{{ database_clients }}" + loop: "{{ databases.users | product(database_clients) | list }}" + loop_control: + label: "{{ item[0].name }}@{{ item[1] }}" - name: Add mariadb backup user community.mysql.mysql_user: From 4fb3bf5d8ed9a50523288ac5f8b2b712c8f0887e Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 5 Jun 2026 11:05:08 +0200 Subject: [PATCH 28/46] ansible-lint --- roles/mariadbdocker/tasks/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/mariadbdocker/tasks/main.yml b/roles/mariadbdocker/tasks/main.yml index 1c99dcc8e..c6830f589 100644 --- a/roles/mariadbdocker/tasks/main.yml +++ b/roles/mariadbdocker/tasks/main.yml @@ -61,16 +61,16 @@ with_items: - "{{ databases.names }}" -- name: Create database users +- name: "Create database users" community.mysql.mysql_user: name: "{{ item[0].name }}" host: "{{ item[1] }}" password: "{{ item[0].password }}" priv: "{{ item[0].db_name }}.*:{{ item[0].privilege }}" - state: present + state: "present" append_privs: true - login_user: root - login_host: localhost + login_user: "root" + login_host: "localhost" login_password: "{{ mariadb_root_password }}" loop: "{{ databases.users | product(database_clients) | list }}" loop_control: From b85e83c7556f4f9695237b4abea967cc6d704ef9 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 5 Jun 2026 11:08:20 +0200 Subject: [PATCH 29/46] Fix galera_create_users: show created users (and fix ansible-linting) --- roles/galera_create_users/tasks/main.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/roles/galera_create_users/tasks/main.yml b/roles/galera_create_users/tasks/main.yml index b0b086469..fd44b31b4 100644 --- a/roles/galera_create_users/tasks/main.yml +++ b/roles/galera_create_users/tasks/main.yml @@ -1,14 +1,14 @@ -- name: Create database user - mysql_user: +--- +- name: "Create database users" + community.mysql.mysql_user: name: "{{ item[0].name }}" host: "{{ item[1] }}" password: "{{ item[0].password }}" - priv: "{{ item[0].db_name }}.*:{{item[0].privilege}}" - state: present - login_unix_socket: /var/lib/mysql/mysql.sock + priv: "{{ item[0].db_name }}.*:{{ item[0].privilege }}" + state: "present" append_privs: true - with_nested: - - "{{ databases.users }}" - - "{{ database_clients }}" + login_unix_socket: "/var/lib/mysql/mysql.sock" run_once: true - no_log: true + loop: "{{ databases.users | product(database_clients) | list }}" + loop_control: + label: "{{ item[0].name }}@{{ item[1] }}" From e1760da79fa78972a17997fc89ef35317e9dcb41 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Mon, 8 Jun 2026 16:56:54 +0200 Subject: [PATCH 30/46] fix indentation --- .../templates/serverapplication.yml.j2 | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 6dee531ed..ccc7acadc 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -119,22 +119,22 @@ config: test_environment: "{{ access_dashboard.test_environment }}" # For other environments, move to group_vars identity_providers: - - name: "SXS IdP" - entityid: "http://mock-idp" - descriptionEN: > - A test IdP that allows you to simulate attribute sets yourself. - You can find the metadata here - descriptionNL: > - Een test-IdP waarmee je zelf attributen-sets kunt simuleren. - De metadata vind je hier - - name: "SXS Dummy" - entityid: "https://idp.diy.surfconext.nl" - descriptionEN: > - A test IdP with fictitious user accounts. - You can find the metadata here" - descriptionNL: > - Een test-IdP met fictieve gebruikersaccounts. - De metadata vind je hier" + - name: "SXS IdP" + entityid: "http://mock-idp" + descriptionEN: > + A test IdP that allows you to simulate attribute sets yourself. + You can find the metadata here + descriptionNL: > + Een test-IdP waarmee je zelf attributen-sets kunt simuleren. + De metadata vind je hier + - name: "SXS Dummy" + entityid: "https://idp.diy.surfconext.nl" + descriptionEN: > + A test IdP with fictitious user accounts. + You can find the metadata here + descriptionNL: > + Een test-IdP met fictieve gebruikersaccounts. + De metadata vind je hier idp_proxy_meta_data: "{{ access_dashboard.idp_proxy_meta_data }}" minimal_stepup_acr_level: "http://{{ base_domain }}/assurance/loa2" features: @@ -148,7 +148,7 @@ config: enabled: true acr_values: {% for loa in [stepup_intrinsic_loa] + stepup_loa_values_supported %} - - "{{ loa }}" + - "{{ loa }}" {% endfor %} eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}" From 88e7f584bcffcfbf02e230fcb24d18ccd6ac4473 Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Tue, 9 Jun 2026 11:08:11 +0200 Subject: [PATCH 31/46] Allow multiple external schachomeorganizations https://github.com/OpenConext/OpenConext-access/issues/752 --- roles/access_dashboard/templates/serverapplication.yml.j2 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index ccc7acadc..a8a9a5b61 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -108,8 +108,12 @@ institution-admin: config: client-url: "https://{{ access_dashboard_base_domain }}" base-url: "{{ base_domain }}" - edu_id_schac_home_organization: "eduid.nl" - surf_schac_home_organization: "example.com" + external_schac_home_organizations: + - "eduid.nl" + - "surfguest.nl" + owner_schac_home_orgs: + - "surfnet.nl" + - "example.com" discovery: "https://connect.surfconext.nl/oidc/.well-known/openid-configuration" invite: "https://invite.{{ base_domain }}" sram: "https://{{ env }}.sram.surf.nl/" From 6358e9b70909d430d835c4fe2a9e960921a16185 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Tue, 9 Jun 2026 14:22:36 +0200 Subject: [PATCH 32/46] minio permission --- roles/minio/tasks/configure_container.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/minio/tasks/configure_container.yml b/roles/minio/tasks/configure_container.yml index 0755bdd07..27047ed15 100644 --- a/roles/minio/tasks/configure_container.yml +++ b/roles/minio/tasks/configure_container.yml @@ -13,7 +13,7 @@ dest: "{{ minio_dir }}/{{ item }}" owner: root group: root - mode: "0644" + mode: "0600" with_items: - config.env notify: Restart minio From 1500bb9febd234a968d621c54d51931a0eac5826 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Tue, 9 Jun 2026 14:33:50 +0200 Subject: [PATCH 33/46] use dir in disk instead of volume for minio --- roles/minio/tasks/configure_container.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/roles/minio/tasks/configure_container.yml b/roles/minio/tasks/configure_container.yml index 27047ed15..2a8681341 100644 --- a/roles/minio/tasks/configure_container.yml +++ b/roles/minio/tasks/configure_container.yml @@ -38,11 +38,12 @@ - name: "loadbalancer" mounts: - source: "{{ minio_dir }}/config.env" - target: /etc/config.env - type: bind - - source: minio_data + target: "/etc/config.env" + type: "bind" + read_only: true + - source: "{{ minio_dir }}/data" target: "{{ minio_data_dir_oncontainer }}" - type: volume + type: "bind" command: server --console-address ":9090" {{ minio_data_dir_oncontainer }} labels: From a535611b8716ee8d0fc08f2e3e9c769ff4ae9dff Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Tue, 9 Jun 2026 14:34:42 +0200 Subject: [PATCH 34/46] JIRA feature toggle for test environment --- roles/access_dashboard/templates/serverapplication.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index a8a9a5b61..43114c732 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -92,7 +92,7 @@ lifecycle: password: "{{ access_dashboard_lifecycle_secret }}" jira: - enabled: true + enabled: "{{ access_dashboard.jira.enabled }}" base-url: "{{ access_dashboard.jira.base_url }}" user-name: "{{ access_dashboard.jira.username }}" project-key: "{{ access_dashboard.jira.project_key }}" From f83a85b604da86fba700ac9c940cd6ec0aa90372 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Tue, 9 Jun 2026 16:16:56 +0200 Subject: [PATCH 35/46] minio (wip) --- roles/minio/defaults/main.yml | 11 ++- roles/minio/tasks/attach_policies.yml | 6 ++ roles/minio/tasks/configure_container.yml | 12 ++- roles/minio/tasks/create_buckets.yml | 101 ++++++++++++++++++++++ roles/minio/tasks/create_users.yml | 49 ++++++----- roles/minio/tasks/main.yml | 15 +++- 6 files changed, 162 insertions(+), 32 deletions(-) create mode 100644 roles/minio/tasks/attach_policies.yml create mode 100644 roles/minio/tasks/create_buckets.yml diff --git a/roles/minio/defaults/main.yml b/roles/minio/defaults/main.yml index cd6baacbe..45bccc775 100644 --- a/roles/minio/defaults/main.yml +++ b/roles/minio/defaults/main.yml @@ -8,7 +8,14 @@ minio_url_local: "http://127.0.0.1:9000" minio_alias: "openconext" minio_client_path: $HOME/minio-binaries minio_mc: "{{ minio_client_path }}/mc" -minio_users: - - { name: 'openconext', password: "{{ minio_passwords.openconext }}" } # set passwords in vault minio_client_checksum: "sha256:01f866e9c5f9b87c2b09116fa5d7c06695b106242d829a8bb32990c00312e891" minio_client_version: "RELEASE.2025-08-13T08-35-41Z" + +minio_users: + - { name: "openconext", password: "minio_user_openconext_password", full_access: true } + +minio_buckets: + - name: "test-bucket" + public: true + write_users: + - "openconext" diff --git a/roles/minio/tasks/attach_policies.yml b/roles/minio/tasks/attach_policies.yml new file mode 100644 index 000000000..6b28ab138 --- /dev/null +++ b/roles/minio/tasks/attach_policies.yml @@ -0,0 +1,6 @@ +--- +- name: "Check and attach policies" + become: false # No mc client actions as root + block: + - debug: + var: username diff --git a/roles/minio/tasks/configure_container.yml b/roles/minio/tasks/configure_container.yml index 2a8681341..a967b2824 100644 --- a/roles/minio/tasks/configure_container.yml +++ b/roles/minio/tasks/configure_container.yml @@ -18,14 +18,18 @@ - config.env notify: Restart minio -- name: Create a docker volume - community.docker.docker_volume: - name: minio_data +- name: Create data directory + ansible.builtin.file: + path: "{{ minio_dir }}/data" + state: "directory" + owner: "root" + group: "root" + mode: "0700" - name: Create and start the server container community.docker.docker_container: name: minio - image: quay.io/minio/minio:{{ minio_version }} + image: "quay.io/minio/minio:{{ minio_version }}" pull: true restart_policy: "always" state: started diff --git a/roles/minio/tasks/create_buckets.yml b/roles/minio/tasks/create_buckets.yml new file mode 100644 index 000000000..462379f05 --- /dev/null +++ b/roles/minio/tasks/create_buckets.yml @@ -0,0 +1,101 @@ +--- +- name: "Check and create buckets" + become: false # No mc client actions as root + block: + - name: "Check whether bucket already exists" + ansible.builtin.command: + cmd: '{{ minio_mc }} anonymous get "{{ minio_alias }}/{{ bucket.name }}"' + register: "minio_bucket_present" + changed_when: false + failed_when: "minio_bucket_present.rc > 1" # rc 1 means bucket does not exist + check_mode: false + + - name: "Create bucket" + when: '"The specified bucket does not exist" in minio_bucket_present.stderr' + ansible.builtin.command: + cmd: '{{ minio_mc }} mb "{{ minio_alias }}/{{ bucket.name }}"' + register: "minio_add_bucket" + failed_when: "minio_add_bucket.rc > 1" # rc==1 means bucket already exists + changed_when: "minio_add_bucket.rc == 0" + + - name: "Set anonymous permission for bucket" + when: '"is `download`" not in minio_bucket_present.stdout' + ansible.builtin.command: + cmd: '{{ minio_mc }} anonymous set download "{{ minio_alias }}/{{ bucket.name }}"' + changed_when: true + + - name: "Policy name" + ansible.builtin.set_fact: + minio_policy_name: "rw-{{ bucket.name }}" + + - name: "Policy file" + ansible.builtin.set_fact: + minio_policy_file: "{{ minio_dir }}/policy-{{ minio_policy_name }}.json" + + - name: "Write policy" + become: true + ansible.builtin.copy: + dest: "{{ minio_policy_file }}" + owner: "root" + group: "root" + mode: "0755" + content: | + { "Version": "2012-10-17", + "Statement": [ { + "Effect": "Allow", + "Action": ["s3:*"], + "Resource": [ + "arn:aws:s3:::{{ bucket.name }}", + "arn:aws:s3:::{{ bucket.name }}/*" + ] } + ] } + + - name: "Check if policy exists" + ansible.builtin.shell: + executable: "/bin/bash" # default dash does not support process substitution + cmd: | + {{ minio_mc }} admin policy info {{ minio_alias }} {{ minio_policy_name }} > "/tmp/{{ minio_policy_name }}-upstream" + register: minio_policy_exists + failed_when: false + changed_when: false + check_mode: false + + - name: "Check if policy is changed" + when: "minio_policy_exists.rc == 0" + ansible.builtin.shell: + executable: "/bin/bash" # default dash does not support process substitution + cmd: > + diff \ + <(jq '.Policy' "/tmp/{{ minio_policy_name }}-upstream") \ + <(jq '.' '{{ minio_policy_file }}' ) + register: "minio_policy_changed" + failed_when: false + changed_when: false + check_mode: false + + - name: "Upload policy" + when: 'minio_policy_exists.rc == 1 or minio_policy_changed.rc == 1' + ansible.builtin.command: + cmd: '{{ minio_mc }} admin policy create {{ minio_alias }} "{{ minio_policy_name }}" "{{ minio_policy_file }}"' + register: "minio_policy_upload" + changed_when: "'Created policy `' + minio_policy_name + '` successfully' in minio_policy_upload.stdout" + + - name: "Check policy mappings" + #language=Shell + ansible.builtin.shell: + cmd: > + {{ minio_mc }} admin policy entities '{{ minio_alias }}' --policy '{{ minio_policy_name }}' --json | + jq '[.result.policyMappings[]?.users // []] | flatten(1)' + register: "minio_policy_attached" + changed_when: false + check_mode: false + + - name: "Attach policy to user" + when: 'username not in minio_policy_attached.stdout | from_json' + ansible.builtin.command: + cmd: '{{ minio_mc }} admin policy attach {{ minio_alias }} "{{ minio_policy_name }}" --user={{ username }}' + register: "minio_attach_policy" + changed_when: "'Added user `' + username + '` successfully" in minio_attach_policy.stdout'" + loop: "{{ bucket.write_users }}" + loop_control: + loop_var: "username" diff --git a/roles/minio/tasks/create_users.yml b/roles/minio/tasks/create_users.yml index 6cf56958d..3947581b0 100644 --- a/roles/minio/tasks/create_users.yml +++ b/roles/minio/tasks/create_users.yml @@ -1,25 +1,30 @@ -- name: Check and create users +--- +- name: "Check and create users" + become: false # No mc client actions as root block: - - name: Check whether user is already configured - ansible.builtin.command: "{{ minio_mc }} admin user info {{ minio_alias }} {{ user.name }}" - register: minio_user_present - changed_when: false - ignore_errors: true - failed_when: minio_user_present.rc > 1 # rc 1 means alias not present thjats what we wanted to know + - name: "Check whether user is already configured" + ansible.builtin.command: > + {{ minio_mc }} admin user info {{ minio_alias }} {{ user.username }} + register: "minio_user_present" + changed_when: false + failed_when: "minio_user_present.rc > 1" # rc 1 means alias not present that's what we wanted to know + check_mode: false - - name: create and configure users - when: - - minio_user_present.rc==1 - - '"Unable to get user info" in minio_user_present.stderr' - block: - - name: Create users - ansible.builtin.command: "{{ minio_mc }} admin user add {{ minio_alias }} {{ user.name }} {{ user.password }}" - register: minio_add_user - changed_when: '"Added user `" + user.name + "` successfully" in minio_add_user.stdout' - no_log: true + - name: "Create and configure user" + when: 'minio_user_present.rc == 1 and "Unable to get user info" in minio_user_present.stderr' + block: + - name: "Create user" + ansible.builtin.command: > + {{ minio_mc }} admin user add {{ minio_alias }} {{ user.username }} {{ user.password }} + register: "minio_add_user" + changed_when: > + "Added user `{{ user.username }}` successfully" in minio_add_user.stdout +# no_log: true - - name: Attach read write policy - ansible.builtin.command: "{{ minio_mc }} admin policy attach {{ minio_alias }} readwrite --user={{ user.name }}" - register: minio_attach_user - changed_when: '"Added user `" + user.name + "` successfully" in minio_add_user.stdout' - become: false # No mc client actions as root + - name: "Attach read write policy" + when: "'full_access' in user and user.full_access" + ansible.builtin.command: > + {{ minio_mc }} admin policy attach {{ minio_alias }} readwrite --user={{ user.username }} + register: "minio_attach_user" + changed_when: > + "Added user `" + user.username + "` successfully" in minio_add_user.stdout diff --git a/roles/minio/tasks/main.yml b/roles/minio/tasks/main.yml index aa823b249..001af8b78 100644 --- a/roles/minio/tasks/main.yml +++ b/roles/minio/tasks/main.yml @@ -1,14 +1,21 @@ -- name: Configure and start container +--- +- name: "Configure and start container" ansible.builtin.include_tasks: "configure_container.yml" -- name: Configure minio client +- name: "Configure minio client" ansible.builtin.include_tasks: "configure_minio_client.yml" -- name: Configure minio server +- name: "Configure minio server" ansible.builtin.include_tasks: "configure_minio_server.yml" -- name: Add minio users +- name: "Add minio users" ansible.builtin.include_tasks: "create_users.yml" loop: "{{ minio_users }}" loop_control: loop_var: "user" + +- name: "Add minio buckets" + ansible.builtin.include_tasks: "create_buckets.yml" + loop: "{{ minio_buckets }}" + loop_control: + loop_var: "bucket" From 000f1790a29825e5f341bd05500d0ef201cb897a Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 10 Jun 2026 11:33:57 +0200 Subject: [PATCH 36/46] run container as user --- roles/minio/tasks/configure_container.yml | 75 +++++++++++++++-------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/roles/minio/tasks/configure_container.yml b/roles/minio/tasks/configure_container.yml index a967b2824..97eb47850 100644 --- a/roles/minio/tasks/configure_container.yml +++ b/roles/minio/tasks/configure_container.yml @@ -1,41 +1,65 @@ --- -- name: Create minio files directory +- name: "Create minio user" + ansible.builtin.group: + name: "container_minio" + # not supported in our ansible version + #gid_min: "{{ container_gid_min }}" + #gid_max: "{{ container_gid_max }}" + gid: "{{ container_ids.minio }}" + system: true + +- name: "Create minio user" + ansible.builtin.user: + name: "container_minio" + group: "container_minio" + home: "{{ minio_dir }}" + create_home: false + password: "!" + shell: "/bin/false" + # not supported in our ansible version + #uid_min: "{{ container_uid_min }}" + #uid_max: "{{ container_uid_max }}" + uid: "{{ container_ids.minio }}" + system: true + +- name: "Create minio files directory" ansible.builtin.file: - state: directory + state: "directory" path: "{{ minio_dir }}" - owner: root - group: root + owner: "root" + group: "root" mode: "0755" -- name: Place the serverapplication configfiles - ansible.builtin.template: - src: "{{ item }}.j2" - dest: "{{ minio_dir }}/{{ item }}" - owner: root - group: root - mode: "0600" - with_items: - - config.env - notify: Restart minio - -- name: Create data directory +- name: "Create data directory" ansible.builtin.file: path: "{{ minio_dir }}/data" state: "directory" + owner: "container_minio" + group: "container_minio" + mode: "0750" + +- name: "Place the serverapplication configfiles" + ansible.builtin.template: + src: "{{ item }}.j2" + dest: "{{ minio_dir }}/{{ item }}" owner: "root" - group: "root" - mode: "0700" + group: "container_minio" + mode: "0640" + with_items: + - "config.env" + notify: "Restart minio" -- name: Create and start the server container +- name: "Create and start the server container" community.docker.docker_container: - name: minio + name: "minio" image: "quay.io/minio/minio:{{ minio_version }}" + user: "{{ container_ids.minio }}:{{ container_ids.minio }}" pull: true restart_policy: "always" - state: started + state: "started" env: MINIO_CONFIG_ENV_FILE: "/etc/config.env" - ports: + published_ports: # Publish container port 9000 for mc client commands - "9000:9000" networks: @@ -48,8 +72,7 @@ - source: "{{ minio_dir }}/data" target: "{{ minio_data_dir_oncontainer }}" type: "bind" - - command: server --console-address ":9090" {{ minio_data_dir_oncontainer }} + command: 'server --console-address ":9090" {{ minio_data_dir_oncontainer }}' labels: traefik.http.routers.minio.rule: "Host(`minio.{{ base_domain }}`)" traefik.http.routers.minio.tls: "true" @@ -72,9 +95,9 @@ timeout: 10s retries: 3 start_period: 10s - register: minio_container + register: "minio_container" -- name: Show container debug info +- name: "Show container debug info" ansible.builtin.debug: msg: "{{ minio_container }}" verbosity: 2 From a85859a9ecfcf362f9eebd42aa595118052270f6 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 10 Jun 2026 12:13:38 +0200 Subject: [PATCH 37/46] fix quotes --- roles/minio/tasks/create_buckets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/minio/tasks/create_buckets.yml b/roles/minio/tasks/create_buckets.yml index 462379f05..7f6c19c68 100644 --- a/roles/minio/tasks/create_buckets.yml +++ b/roles/minio/tasks/create_buckets.yml @@ -95,7 +95,7 @@ ansible.builtin.command: cmd: '{{ minio_mc }} admin policy attach {{ minio_alias }} "{{ minio_policy_name }}" --user={{ username }}' register: "minio_attach_policy" - changed_when: "'Added user `' + username + '` successfully" in minio_attach_policy.stdout'" + changed_when: "'Added user `' + username + '` successfully' in minio_attach_policy.stdout" loop: "{{ bucket.write_users }}" loop_control: loop_var: "username" From 0a04180db62a5e038bbb679f1dff7831604a4219 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 10 Jun 2026 12:23:37 +0200 Subject: [PATCH 38/46] correctly sort keys in policy --- roles/minio/tasks/create_buckets.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/minio/tasks/create_buckets.yml b/roles/minio/tasks/create_buckets.yml index 7f6c19c68..4680cc4e6 100644 --- a/roles/minio/tasks/create_buckets.yml +++ b/roles/minio/tasks/create_buckets.yml @@ -66,8 +66,8 @@ executable: "/bin/bash" # default dash does not support process substitution cmd: > diff \ - <(jq '.Policy' "/tmp/{{ minio_policy_name }}-upstream") \ - <(jq '.' '{{ minio_policy_file }}' ) + <(jq --sort-keys '.Policy' "/tmp/{{ minio_policy_name }}-upstream") \ + <(jq --sort-keys '.' '{{ minio_policy_file }}' ) register: "minio_policy_changed" failed_when: false changed_when: false From 3c19ade15894639e6125ff283264cf5c9cbd9f43 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 10 Jun 2026 12:36:42 +0200 Subject: [PATCH 39/46] make superadmins, external sho and owner sho configurable --- roles/access_dashboard/defaults/main.yml | 3 +++ .../templates/serverapplication.yml.j2 | 11 +++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/roles/access_dashboard/defaults/main.yml b/roles/access_dashboard/defaults/main.yml index a92af8fe9..6cfaa36a3 100644 --- a/roles/access_dashboard/defaults/main.yml +++ b/roles/access_dashboard/defaults/main.yml @@ -2,3 +2,6 @@ access_dashboard_docker_networks: - name: "loadbalancer" access_dashboard_cronjobmaster: true +access_dashboard_external_sho: ["eduid.nl"] +access_dashboard_owner_sho: ["example.com"] +access_dashboard_super_admins: ["urn:collab:person:example.com:admin"] diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 43114c732..893a45c92 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -108,12 +108,8 @@ institution-admin: config: client-url: "https://{{ access_dashboard_base_domain }}" base-url: "{{ base_domain }}" - external_schac_home_organizations: - - "eduid.nl" - - "surfguest.nl" - owner_schac_home_orgs: - - "surfnet.nl" - - "example.com" + external_schac_home_organizations: "{{ access_dashboard_external_sho }}" + owner_schac_home_orgs: "{{ access_dashboard_owner_sho }}" discovery: "https://connect.surfconext.nl/oidc/.well-known/openid-configuration" invite: "https://invite.{{ base_domain }}" sram: "https://{{ env }}.sram.surf.nl/" @@ -159,8 +155,7 @@ eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}" # TODO super-admin: - users: - - "urn:collab:person:example.com:admin" + users: "{{ access_dashboard_super_admins }}" gui: disclaimer: From 3141dcc11c5745dce8d2fb223ef1052490c42312 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 10 Jun 2026 12:40:55 +0200 Subject: [PATCH 40/46] access-dashboard: remove S3 secrets from gui container --- roles/access_dashboard/tasks/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/roles/access_dashboard/tasks/main.yml b/roles/access_dashboard/tasks/main.yml index 0291f8581..a8ed5c4d7 100644 --- a/roles/access_dashboard/tasks/main.yml +++ b/roles/access_dashboard/tasks/main.yml @@ -90,7 +90,5 @@ read_only: true env: S3_STORAGE_URL: "{{ access_dashboard.s3_storage.url }}" - S3_STORAGE_KEY: "{{ access_dashboard.s3_storage.key }}" - S3_STORAGE_SECRET: "{{ access_dashboard.s3_storage.secret }}" S3_STORAGE_BUCKET: "{{ access_dashboard.s3_storage.bucket }}" register: "access_dashboard_gui_container" From 92f122897da85447149affc9a5e1b6692f5d0226 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Wed, 10 Jun 2026 16:45:39 +0200 Subject: [PATCH 41/46] Fix superadmin expansion --- roles/access_dashboard/templates/serverapplication.yml.j2 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 893a45c92..15a88d748 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -153,9 +153,8 @@ config: eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}" -# TODO super-admin: - users: "{{ access_dashboard_super_admins }}" + users: {{ access_dashboard_super_admins | to_yaml}} gui: disclaimer: From 8a3a02151adf5fca6642d66f5fa086469fb4ef0b Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 11 Jun 2026 09:08:57 +0200 Subject: [PATCH 42/46] try to fix superadmins --- roles/access_dashboard/templates/serverapplication.yml.j2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 15a88d748..ad0e69af0 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -154,7 +154,7 @@ config: eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}" super-admin: - users: {{ access_dashboard_super_admins | to_yaml}} + users: {{ access_dashboard_super_admins | to_json}} gui: disclaimer: From 98e50fc22cb2f49830d93687eabca804de382665 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 11 Jun 2026 09:27:54 +0200 Subject: [PATCH 43/46] fix yaml error --- roles/access_dashboard/templates/serverapplication.yml.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index ad0e69af0..7cef6fbe3 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -108,8 +108,8 @@ institution-admin: config: client-url: "https://{{ access_dashboard_base_domain }}" base-url: "{{ base_domain }}" - external_schac_home_organizations: "{{ access_dashboard_external_sho }}" - owner_schac_home_orgs: "{{ access_dashboard_owner_sho }}" + external_schac_home_organizations: {{ access_dashboard_external_sho | to_json }} + owner_schac_home_orgs: {{ access_dashboard_owner_sho | to_json }} discovery: "https://connect.surfconext.nl/oidc/.well-known/openid-configuration" invite: "https://invite.{{ base_domain }}" sram: "https://{{ env }}.sram.surf.nl/" From 833edb0b7b44697a55f203c9fc27c4c313fcd11f Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 11 Jun 2026 09:38:53 +0200 Subject: [PATCH 44/46] fix application.yml syntax --- .../templates/serverapplication.yml.j2 | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 7cef6fbe3..08891fce7 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -108,8 +108,14 @@ institution-admin: config: client-url: "https://{{ access_dashboard_base_domain }}" base-url: "{{ base_domain }}" - external_schac_home_organizations: {{ access_dashboard_external_sho | to_json }} - owner_schac_home_orgs: {{ access_dashboard_owner_sho | to_json }} + external_schac_home_organizations: +{% for sho in access_dashboard_external_sho %}{# Note: spring yaml parser is wonky #} + - {{ sho }} +{% endfor %} + owner_schac_home_orgs: +{% for sho in access_dashboard_owner_sho %}{# Note: spring yaml parser is wonky #} + - {{ sho }} +{% endfor %} discovery: "https://connect.surfconext.nl/oidc/.well-known/openid-configuration" invite: "https://invite.{{ base_domain }}" sram: "https://{{ env }}.sram.surf.nl/" @@ -147,14 +153,17 @@ config: - name: "mfa" enabled: true acr_values: - {% for loa in [stepup_intrinsic_loa] + stepup_loa_values_supported %} + {% for loa in [stepup_intrinsic_loa] + stepup_loa_values_supported %}{# Note: spring yaml parser is wonky #} - "{{ loa }}" {% endfor %} eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}" super-admin: - users: {{ access_dashboard_super_admins | to_json}} + users: +{% for sub in access_dashboard_super_admins %}{# Note: spring yaml parser is wonky #} + - {{ sub }} +{% endfor %} gui: disclaimer: From 03949d1cb2310c43a86a372655984dbb4d7c7ee1 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 11 Jun 2026 10:28:04 +0200 Subject: [PATCH 45/46] fix quotes --- roles/access_dashboard/templates/serverapplication.yml.j2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 08891fce7..126b5d960 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -110,11 +110,11 @@ config: base-url: "{{ base_domain }}" external_schac_home_organizations: {% for sho in access_dashboard_external_sho %}{# Note: spring yaml parser is wonky #} - - {{ sho }} + - "{{ sho }}" {% endfor %} owner_schac_home_orgs: {% for sho in access_dashboard_owner_sho %}{# Note: spring yaml parser is wonky #} - - {{ sho }} + - "{{ sho }}" {% endfor %} discovery: "https://connect.surfconext.nl/oidc/.well-known/openid-configuration" invite: "https://invite.{{ base_domain }}" @@ -162,7 +162,7 @@ eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}" super-admin: users: {% for sub in access_dashboard_super_admins %}{# Note: spring yaml parser is wonky #} - - {{ sub }} + - "{{ sub }}" {% endfor %} gui: From 48217da6e29401b73f5f6fc8c80cc7c610ac880d Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Thu, 11 Jun 2026 10:31:29 +0200 Subject: [PATCH 46/46] fix indentation --- roles/access_dashboard/templates/serverapplication.yml.j2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/access_dashboard/templates/serverapplication.yml.j2 b/roles/access_dashboard/templates/serverapplication.yml.j2 index 126b5d960..1de4f8221 100644 --- a/roles/access_dashboard/templates/serverapplication.yml.j2 +++ b/roles/access_dashboard/templates/serverapplication.yml.j2 @@ -153,9 +153,9 @@ config: - name: "mfa" enabled: true acr_values: - {% for loa in [stepup_intrinsic_loa] + stepup_loa_values_supported %}{# Note: spring yaml parser is wonky #} +{% for loa in [stepup_intrinsic_loa] + stepup_loa_values_supported %}{# Note: spring yaml parser is wonky #} - "{{ loa }}" - {% endfor %} +{% endfor %} eduid-idp-entity-id: "{{ access_dashboard.eduid_idp_entity_id }}"