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:

  1. Configure a new OIDC client application

    1. Left menu bar > Select correct realm > Clients menu item > Create Client

    2. Insert new client configuration for your environment (example will be based on client with ID "pubsub")

      1.  

      2.  

      3.  

      4. Press Save

  2. Edit the client credentials, generate password

    1. Open the client Credentials Tab and edit client secret.

  3. Edit client scopes to add roles to identity tokens

    1. Client scopes tab > Click on "pubsub-dedicated" client scope link (link name will include your client id).

  4. In order to add client roles to issed identity tokens, a scope mapper must be created/added

    1. Click "Add predefined mapper" button

    2. Search for "realm roles"

    3. Tick the select box and press "Add" button

  5. Configure the mapper so that it is included into the identity tokens that are issued for users

    1.  

    2. Save