IAM Authentication Provider for X-Road Admin GUI access
The purpose of this modification is to allow for a single Identity and Access Management interface in the form of an external IAM provider. For convenience this solution uses Keycloak but any OIDC capable technology would work and the examples given for Keycloak can be interpolated.
This change will directly affect the code of NIIS X-Road 7.x and implemented in that, preferably included in the upstream as a pull request but for now provided by forking the released version. All changes are backwards compatible.
Solution
X-Road administration GUI access is currently only allowed for local machine users through pluggable authentication module (PAM). Users that require access, need to registered and have predetermined groups set in the local machine serving the administration GUI application.
GovStack environments require the use of an external Identity and Access Management system. Integration with IAM should be done accorfing to OAuth2 framework.
We will be implementing OpenID Connect (OIDC) protocol (that is built on top of OAuth 2.0) support in X-Road administration GUI-s (Security Server and Central Server). The IAM will be responsible for declaring the correct user-role mappings. User roles will be delivered to X-Road backend service via user identity tokens.
X-Road administration GUI-s are Vue.js based single page applications. The authentication state is held on server side and client side only holds the session ID. In order to implement IAM support without breaking backward compatability, we will be implementig authentication according to the OIDC Authorization Code Flow. Clients are authorized once the authorization code has been validated on the X-Road proxy-ui-api service and a session ID is returned to the front-end application.
Token structure
The authentication scheme requires that the user identity tokens, issued by the IAM, contain the authority information granted to the user. X-Road requires that user tokens contain one or more of the following role names:
xroad-security-officer
xroad-registration-officer
xroad-service-administrator
xroad-system-administrator
xroad-securityserver-observer
IAM must provide a roles claim in each issued user identity token.
Example ID token structure:
{
"exp": 1685022693,
"iat": 1685022393,
"auth_time": 1685021720,
"jti": "df8c31d5-cb32-4e17-9f2e-5340702ce7ab",
"iss": "http://host.docker.internal:8089/realms/pubsub-realm",
"aud": "pubsub",
"sub": "d49fab86-3549-4659-b123-2f74918070d3",
"typ": "ID",
"azp": "pubsub",
"nonce": "f6YNBEB0wUNbzuTa_ydR2KbkSJdSuXRzXPa_5AE2JiY",
"session_state": "da1c67e1-1bf0-4c39-810d-2b675fb5dae1",
"at_hash": "NYOsXhGlZrEQ5JHXevId2Q",
"acr": "0",
"sid": "da1c67e1-1bf0-4c39-810d-2b675fb5dae1",
"email_verified": true,
"roles": [
"default-roles-pubsub-realm",
"offline_access",
"uma_authorization",
"xroad-system-administrator"
],
"name": "System Administrator",
"preferred_username": "sa",
"given_name": "System",
"family_name": "Administrator",
"email": "sa@sa.sa"
} |
X-Road will read all the roles and based on them will determine the fine-graned authority access for authenticated users.
Configuration
IAM access over OIDC will substiture PAM login when enabled. It is envisioned that both authentication means are not supported simultaneously.
X-Road server administrator can enable OIDC login by setting command line arguments to the X-Road application process. X-Road System Parameters User Guide describes how to set command line arguments to the process (https://www.x-tee.ee/docs/test/xroad/ug-syspar_x-road_v7_system_parameters.html#6-adding-command-line-arguments ).
In breaf:
Edit the /etc/xroad/services/local.properties
file in the machine/container that is executing X-Road Security Server and/or Central Server application process.
Add the following parameters to the server process that is executing X-Road proxy-ui-api (security server admin) application, or the centralserver-admin-service (central server admin) application.
XROAD_PROXY_UI_API_PARAMS=-Dxroad.ui.authentication-method=OAUTH2 -Dspring.security.oauth2.client.registration.iam-provider.client-id=pubsub -Dspring.security.oauth2.client.registration.iam-provider.client-secret=wAIz8MUUXHCeUH0f26oY3jpZk0IJpVBK -Dspring.security.oauth2.client.registration.iam-provider.authorization-grant-type=authorization_code -Dspring.security.oauth2.client.registration.iam-provider.redirect-uri={baseUrl}/login/oauth2/code/{registrationId} -Dspring.security.oauth2.client.registration.iam-provider.scope=openid -Dspring.security.oauth2.client.registration.iam-provider.provider=iam-provider -Dspring.security.oauth2.client.provider.iam-provider.issuer-uri=http://host.docker.internal:8089/realms/pubsub-realm -Dspring.security.oauth2.client.provider.iam-provider.authorization-uri=http://host.docker.internal:8089/realms/pubsub-realm/protocol/openid-connect/auth -Dspring.security.oauth2.client.provider.iam-provider.token-uri=http://host.docker.internal:8089/realms/pubsub-realm/protocol/openid-connect/token -Dspring.security.oauth2.client.provider.iam-provider.user-info-uri=http://host.docker.internal:8089/realms/pubsub-realm/protocol/openid-connect/userinfo -Dspring.security.oauth2.client.provider.iam-provider.user-name-attribute=preferred_username
XROAD_CS_ADMIN_SERVICE_PARAMS=-Dxroad.ui.authentication-method=OAUTH2 -Dspring.security.oauth2.client.registration.iam-provider.client-id=pubsub -Dspring.security.oauth2.client.registration.iam-provider.client-secret=Cb6THaqLuqCieP7dt5M8i1HBG0sLJoQk -Dspring.security.oauth2.client.registration.iam-provider.authorization-grant-type=authorization_code -Dspring.security.oauth2.client.registration.iam-provider.redirect-uri={baseUrl}/login/oauth2/code/{registrationId} -Dspring.security.oauth2.client.registration.iam-provider.scope=openid -Dspring.security.oauth2.client.registration.iam-provider.provider=iam-provider -Dspring.security.oauth2.client.provider.iam-provider.issuer-uri=https://keycloak.local:8089/realms/pubsub-realm -Dspring.security.oauth2.client.provider.iam-provider.authorization-uri=https://keycloak.local:8089/realms/pubsub-realm/protocol/openid-connect/auth -Dspring.security.oauth2.client.provider.iam-provider.token-uri=https://keycloak.local:8089/realms/pubsub-realm/protocol/openid-connect/token -Dspring.security.oauth2.client.provider.iam-provider.user-info-uri=https://keycloak.local:8089/realms/pubsub-realm/protocol/openid-connect/userinfo -Dspring.security.oauth2.client.provider.iam-provider.user-name-attribute=preferred_username |
Configuring KeyCloak as an IAM for local testing purposes:
Configure a new OIDC client application
Left menu bar > Select correct realm > Clients menu item > Create Client
Insert new client configuration for your environment (example will be based on client with ID "pubsub")
Press Save
Edit the client credentials, generate password
Open the client Credentials Tab and edit client secret.
Edit client scopes to add roles to identity tokens
Client scopes tab > Click on "pubsub-dedicated" client scope link (link name will include your client id).
In order to add client roles to issed identity tokens, a scope mapper must be created/added
Click "Add predefined mapper" button
Search for "realm roles"
Tick the select box and press "Add" button
Configure the mapper so that it is included into the identity tokens that are issued for users
Save