I managed to test locally with docker by hacking on pupperware and using a docker image with systemd support (inspired by docker-systemd) to run the puppet agent.
Everything works as expected regarding authentication and authorization in swh-web.

I think we might want separate realms for production, staging and "localhost testing". At the very least, we will want separate clients, because I don't think application credentials and user sessions should be shared across the different usecases.

If you agree with this I'm happy to pick this diff up to implement the idea.

I think we might want separate realms for production, staging and "localhost testing". At the very least, we will want separate clients, because I don't think application credentials and user sessions should be shared across the different usecases.

One realm per environment seems the right way to go I think. This will enable to have a different set of users for each of them and test new clients safely.

I could not resist to test locally. This is the puppet output of my first run once I plugged the code in my local puppet testing env : P633
We can see that realms are correctly created but swh-web client creation for SoftwareHeritageStaging realm failed and the
protocol mappers creation too.

After a (painful) debugging session, I noticed that an explicit id must be set for each client with the same name in order for Keycloak to
successfully create them using its admin API.
In a same manner, protocol mappers must be created using the client id and not its name.

I added inline comments fixing the observed issues. Resulting puppet run after those changes can be found here: P634

classprofile::keycloak::resources{$realms=lookup({name=>'keycloak::resources::realms',value_type=>Hash,merge=>{strategy=>'deep',knockout_prefix=>'--',},default_value=>{},})$realm_common_settings=lookup({name=>'keycloak::resources::realms::common_settings',value_type=>Hash,merge=>{strategy=>'deep',knockout_prefix=>'--',},default_value=>{},})$client_common_settings=lookup({name=>'keycloak::resources::clients::common_settings',value_type=>Hash,merge=>{strategy=>'deep',knockout_prefix=>'--',},default_value=>{},})$realms.each|$realm_name,$realm_data|{$_local_realm_settings=pick($realm_data['settings'],{})$_full_realm_settings=deep_merge($realm_common_settings,$_local_realm_settings)keycloak_realm{$realm_name:ensure=>present,*=>$_full_realm_settings,}$clients=pick($realm_data['clients'],{})$realm_client_common_settings=deep_merge($client_common_settings,pick($realm_data['client_settings'],{}))$clients.each|$client_name,$client_data|{$_local_client_settings=pick($client_data['settings'],{})$_full_client_settings=deep_merge($realm_client_common_settings,$_local_client_settings)$client_id=fqdn_uuid("${realm_name}.${client_name}")keycloak_client{"${client_name} on ${realm_name}":ensure=>present,id=>$client_id,*=>$_full_client_settings,}$protocol_mappers=pick($client_data['protocol_mappers'],[])$protocol_mappers.each|Hash$protocol_mapper_data|{$_pm_data=Hash($protocol_mapper_data.map|$key,$value|{[$key,$value?{'__client_id__'=>$client_name,default=>$value}]})$protocol_mapper_name=$protocol_mapper_data['name']$protocol_mapper_id=fqdn_uuid("${realm_name}.${client_name}.${protocol_mapper_name}")keycloak_client_protocol_mapper{"${protocol_mapper_data['name']} for ${client_id} on ${realm_name}":ensure=>present,id=>$protocol_mapper_id,*=>$_pm_data,}}}}}