Leverancen består af et Docker image som er baseret på Keycloak (https://www.keycloak.org/) version 26.4.0. I dette
standard Keycloak Docker image er der installeret extensions som udvider funktionaliteten for at understøtte EHMI
pilotprojektet. Ud over nedenstående dokumentation henvises til dokumentationen af standard Keycloak på 
https://www.keycloak.org/

Logning af certifikatstatus

NSP Keycloak indeholder en extension som kører et job til at logge certifikatstatus med konfigurerbare intervaller. 
Der bør etableres overvågning af loggen for at identificere evt. spærring eller snarligt udløb af disse certifikater.
Formatet på disse logs beskrives nedenfor.

Logger klasse er ```dk.nsp.security.keycloak.jobservice.keycloakcertificateinfo.LogkeycloakCertificateInfoScheduledTask```
Teksten som logges er et json dokument med følgende struktur:

{
  "realmName":"ehmi",
  "realmId":"ehmi",
  "kid":"YIX49ytybvWgXKkZBxHuFGMe6n_rEpRBfaRjrnds-00",
  "subject":"C=DK, OID.2.5.4.97=NTRDK-96024140, O=Testorganisation nr. 96024140, SERIALNUMBER=UI:DK-O:G:541c45fb-46cf-49aa-8cfc-a7cc702678d8, CN=NSP Keycloak Test 1",
  "issuer":"C=DK, O=Den Danske Stat, OU=Test - cti, CN=Den Danske Stat OCES udstedende-CA 1",
  "notBefore":"2025-10-29T17:36:04Z",
  "notAfter":"2028-10-28T17:36:03Z",
  "daysToExpiry":"919",
  "revocationStatus":"VALID"
}


Når dayToExpiry er mindre en f.eks. 30 bør der udløses en alarm/ notifikation.
Nar revocationStatus er forskellig fra VALID bør der udløses en alarm.

Konfiguration af NSP OpenID Connect (OIDC) Keycloak server med NSP plugins

Keycloak konfigureres ved hjælp af Terraform og Keycloaks Terraform provider. Projektet https://git.nspop.dk/scm/con/keycloak-configuration.git indeholder Terraform konfigurationsfiler til at konfigurer Keycloak installationerne i EHMI projektet.

Struktur

├── README.md
└── terraform
    └── configuration
        ├── modules
      ├── localhost
      ├── test1
      └── test2


modules

Denne folder indeholder konfigurationer (i form af Terraform moduler) som bruges generelt for installationer på alle 
miljøer.

localhost

Denne folder indeholder konfiguration af en lokal installation som man f.eks. afvikler på en udvikler maskine. OBS: State
er eksplicit git ignored for denne folder. 

test1

Denne folder indeholder konfiguration af NSP test1 miljøet. Terraform state gemmes på deploy serveren.

test2

Denne folder indeholder konfiguration af NSP test2 miljøet. Terraform state gemmes på deploy serveren.


Keycloak Terraform provider

Der skal benyttes Keycloak provider version >= 5.8.0 for at understøtte keyUse i Java keyproviders i Keycloak.

Hvordan opdateres Keycloak konfiguration via Terraform ?

Dette er en kort vejledning i hvordan Terraform bruges til at konfigurer NSP Keycloak installationer.

Forudsætninger

  • Terraform er installeret
  • Fork'et Terraform Keycloak provider er bygget og konfigureret som beskrevet ovenfor

Localhost

Ved konfiguration af localhost ligger al Terraform state lokalt. I det følgende antages det at der kører en lokal installation af NSP Keycloak via docker compose i ```localhost``` folderen i selve Keycloak projektet.

Først skal der oprettes en client i Keycloak som Terraform bruger til at kalde Keycloak.

I folderen "terraform" køres følgende kommando

./create_tf_client.sh https://keycloak.local/auth admin Test1234 terraform Test1234

Skift til folderen "terraform/configuration/localhost" og kør kommandoerne

terraform init
terraforn apply

Bemærk, at der oprettes en række filer og foldere med bla. Terraform state. Disse er vigtige for at vedligeholde den
lokale Keycloak installation. Det er ligeledes vigtig at slette alt hvis du starter med en ny Keycloak database. Dvs.

rm -rf .terraform
rm -rf .terraform.lock.hcl
rm -rf terraform.tfstate
rm -rf terraform.tfstate.backup

NSP miljøer

Princippet er præcist det samme som ved localhost ovenfor. Dog er der den væsentlige forskel at Terraform state er 
checket ind i dette git repo. State skal altid repræsentere hvad der er konfigureret i Test1. Dvs. processen for at 
lave opdateringer i f.eks. Test1 skal være

  1. Pull nyeste version af state fra git repo
  2. Sikre at INGEN andre laver opdateringer
  3. Lav opdateringer via Terraform (som dermed opdatere state i dette repo)
  4. Push state til git

Alternativet til denne manuelle process for at sikre Terraform state ikke kommer ud af sync, er at benytte en anden 
storage mekanisme til state. F.eks. understøtter Terraform S3 kompatibel storage af state, hvor Terraform skriver
locks for at undgå at state kommer ud af sync.

Klient registrering og opdatering (DCR)

Keycloak understøtter OpenID Connect Dynamic Client Registration (DCR) og flere andre klient registrerings
protokoller. Til NSP brug er Keycloaks DCR udvidet til at håndtere følgende ekstra attributter i klient
metadata:

  • ehmi:eer:device_id
  • ehmi:org_context
  • audience

Værdien af ehmi:eer:device_id gemmes blot som en attribut på den oprettede klient. Det er meningen
at den skal bruges til senere at lave opslag i EER for at whiteliste anmodede SOR/GLN koder

I nuværende release whitelistes anmodede SOR/GLN scopes via den liste som angives i ehmi:org_context
i metadata. Mekanismen og hvorledes disse proprietære attributter benyttes i Keycloak er beskrevet i 
detaljer i "Sikkerhedsarkitektur EHMI Services"

Udover disse proprietære attributter er der også implementeret understøttelse for en audience attribut i 
metadata. Denne gør det muligt at registrere hvilket audience ('aud' claim) tokens skal udstedes til.

Se https://www.keycloak.org/securing-apps/client-registration for generel oplysning om Keycloaks DCR.

Scripts til at kalde DCR

Brugen af DCR beskrevet i https://openid.net/specs/openid-connect-registration-1_0.html

Klient metadata og scripts til at kalde DCR ligger i repo https://git.nspop.dk/scm/con/keycloak-clients.git

For at gøre det lidt nemmere at oprette og vedligeholde klienter manuelt er der lavet 4 shell scripts 
til at kalde registrerings endpoints.

  • import_client.sh
  • get_client.sh
  • update_client.sh
  • delete_client.sh

Bemærk, at efter klient metadata er importeret, kan klienten efterfølgende vedligeholdes ved at bruge
det returnede "registration_client_uri" endpoint og "registration_access_token". Metadata skal efter 
oprettelse udvides med den tildelte "client_id"

URL'en ("registration_endpoint") til brug i "import_client.sh" kan findes i realmet's .well-known dokument, f.eks. her
https://keycloak-test.nspop.dk/auth/realms/ehmi/.well-known/openid-configuration

Navngivningskonvention for client metadata

For hver organisation er der oprettet en folder med dennes klient metadata - f.eks. Trifork og Systematic.

Oprettelse af klient

Når der skal oprettes en ny klient gemmes klientmetadata json dokumentet med suffix '.v000' - f.eks. ```myclient-v000.json```. Klienten oprettes ved at POST'e denne json fil til Keycloaks DCR endpoint. Dette kan gøres nemt med følgende kommando:

$ ./import_client.sh [keycloak baseurl] [keycloak admin username] [keycloak admin password] [realm] [client metadata file]

Baseurl for test1 på NSP er "https://keycloak-test.nspop.dk/auth

Keycloak username og password kender Netic.

Realm på test1 på NSP er "ehmi"

Client metadata file vil f.eks. være "myclient-v000.json"

Response fra denne kommando er et json dokument som beskriver hvad der er oprettet i Keycloak. Dette dokument gemmes i samme folder og navngives med suffix ".response.json". Altså fra eksemplet ovenfor "myclient-v000.json.response.json". I dette respons står der 3 meget vigtige attributter:

 - "client_id" indeholder det id som den nye klient er blevet tildelt af Keycloak. Denne værdi skal indsættes i klientmeta dokumenter hvis der skal laves opdateringer.
 - "registration_client_uri"indeholder URL'en som bruges til at opdatere klienten (den er altså klient specifik)
 - "registration_access_token" indeholder det token som skal sendes med ved opdateringer. Bemærk at der udstedes nye tokens ved opdateringer. Token benyttes altså kun én gang.

Eksempel på oprettelse af klient med scriptet:

$ ./import_client.sh 
Usage:
./import_client.sh [keycloak baseurl] [keycloak admin username] [keycloak admin password] [realm] [client metadata file]
$
$ ./import_client.sh https://keycloak.local/auth admin Test1234 eas client1-metadata.json
Get access token
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1654  100  1582  100    72  12717    578 --:--:-- --:--:-- --:--:-- 13338
Create Initial Access Token
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   614  100   581  100    33  33360   1894 --:--:-- --:--:-- --:--:-- 36117
{"redirect_uris":["https://ehmi-client.local:8443/login/oauth2/code/oauth-par"],"token_endpoint_auth_method":"tls_client_auth",
"token_endpoint_auth_signing_alg":"PS256","grant_types":["client_credentials"],"response_types":[],"client_id":"957e5d96-9ff2-4266-a7c8-cef121104151",
"client_name":"EHMI
Testklient script","scope":"EDS system/AuditEvent.crs","subject_type":"public","id_token_signed_response_alg":"PS256",
"userinfo_signed_response_alg":"PS256","request_object_signing_alg":"PS256","request_uris":[],"tls_client_certificate_bound_access_tokens":true,
"tls_client_auth_subject_dn":"subject=C=DK,2.5.4.97=#0c0e4e5452444b2d3936303234313430,O=Testorganisation nr. 96024140,SERIALNUMBER=UI:DK-O:G:7bd0d84a-c1f3-4650-a351-4235c482ebeb,CN=System 1",
"dpop_bound_access_tokens":false,"post_logout_redirect_uris":["https://ehmi-client.local:8443/login/oauth2/code/oauth-par"],
"client_id_issued_at":1763659448,"registration_client_uri":"https://keycloak.local/auth/realms/eas/clients-registrations/openid-connect/957e5d96-9ff2-4266-a7c8-cef121104151",
"registration_access_token":"eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4ZDk0M2IzZi0yNzQ3LTQwMGMtYjdjNC0zMTFiYWYyY2E1ZGMifQ.eyJleHAiOjAsImlhdCI6MTc2MzY1OTQ0OCwianRpIjoiZjdiNDAzYzAtNjdlNS0zMzkwLTZiZWYtM2RhZDdjYTE3ZjI2IiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5sb2NhbC9hdXRoL3JlYWxtcy9lYXMiLCJhdWQiOiJodHRwczovL2tleWNsb2FrLmxvY2FsL2F1dGgvcmVhbG1zL2VhcyIsInR5cCI6IlJlZ2lzdHJhdGlvbkFjY2Vzc1Rva2VuIiwicmVnaXN0cmF0aW9uX2F1dGgiOiJhdXRoZW50aWNhdGVkIn0.aBIPkgU2FSxGr5gu0rv-8FtlH7GVM6-E97UoSPxIKfEX_OW58uV7evYk4Gqzkx2oY5lyH9KIz5BSlpKbjenF-w",
"backchannel_logout_session_required":false,"require_pushed_authorization_requests":false,"frontchannel_logout_session_required":false
}


Opdatering af klient

Hvis en klient skal opdateres oprettes der et json dokument med navnet "myclient-v001.json". Dette dokument skal indeholde de opdaterede metadata samt "client_id" fra oprettelses responset.

Opdatering kan udføres med kommandoen:

./update_client.sh [registration_client_uri] [registration_access_token] [client metadata file]

Sletning af klient

En klient kan slettes med dette script:

./update_client.sh [registration_client_uri] [registration_access_token]

Hent/vis klient

Det er er muligt at hente registret klient oplysninger med denne kommando:

./update_client.sh [registration_client_uri] [registration_access_token]





  • No labels