From 2d82fcbea8dc5df12798ea4ded3a90697cd0a2d1 Mon Sep 17 00:00:00 2001 From: Anil Panta Date: Fri, 14 Feb 2025 14:53:02 -0500 Subject: [PATCH 1/3] oidc: rework oidc flow address doc #475 --- docs/operator/installing_server.md | 399 +++++------------------------ docs/user/using_the_client.md | 29 +-- 2 files changed, 72 insertions(+), 356 deletions(-) diff --git a/docs/operator/installing_server.md b/docs/operator/installing_server.md index 3465bad6385..f5742bf2986 100644 --- a/docs/operator/installing_server.md +++ b/docs/operator/installing_server.md @@ -200,369 +200,108 @@ becomes `RUCIO_CFG_DATABASE_DEFAULT`. All available environment variables are: - RUCIO_CFG_PERMISSION_SUPPORT_RUCIO - RUCIO_CFG_WEBUI_USERCERT -## Server Configuration for Open ID Connect AuthN/Z - -In order to be able to use [OIDC](https://openid.net/connect/) -JSON Web Tokens ([JWTs](https://en.wikipedia.org/wiki/JSON_Web_Token)) and -related [OAuth2.0](https://oauth.net/2/) authentication and authorization with Rucio, -one first needs to have an account with an Identity Provider (IdP) -which will act as Rucio admin account representing the Rucio Application. -Currently, the only fully supported IdP is [INDIGO IAM](https://indigo-iam.github.io/v/current/). -Once you have got your Rucio Service IAM Account [A] -(and its subject claim identifier), you will need to [register two IAM Rucio -clients](https://indigo-iam.github.io/docs/v/current/user-guide/client-registration.html) -linked to this account. Please save the relevant __client_id__, -__client_secret__, and __registration access token (RAT)__ in -a safe place, as you will be needing them. - -In both clients, one needs to setup the __redirect_uris__ to -include the following paths: -```bash -https:///auth/oidc_token -https:///auth/oidc_code -``` +## Server Configuration for OpenID Connect Authentication & Authorization and Transfers -We will use one client as -__Rucio Auth IAM Client__ [C1] (i.e. client for the authentication and -authorization on the Rucio server). This client needs to have __token_exchange__, -__token_refresh__, and __authorization_code__ grants enabled. For __token_exchange__ -and __token_refresh__ you might need to contact the IAM admin as such settings are -usually not accessible to IAM users. In addition, you will need to request your -IAM admin to allow your client returning refresh tokens with lifetime being visible -in their unverified header. In addition Rucio assumes refresh tokens to expire -immediately after their first use, which has to be also confirmed by your IAM admin. - -The second -client, let's call it __Rucio Admin IAM Client__ [C2], can be used by a Rucio probe -script (e.g. [check_scim](https://github.com/rucio/probes/blob/master/attic/check_scim), -[sync_iam_rucio](https://github.com/ESCAPE-WP2/Utilities-and-Operations-Scripts/blob/master/iam-rucio-sync/sync_iam_rucio.py)) -in order to synchronize existing Rucio accounts with Rucio -identities. Rucio will also use this client's credentials in order to request -tokens for itself. The IAM administrator must include the __scim:read__ scope and -allow the __client_credentials__ grant type for [C2] in order -to grant you rights to pre-provision IAM users for Rucio. Examples of the -configuration of these two clients follow below: - -Example of the __Rucio Auth IAM Client__ [C1] configuration: - -```json -{ - "client_id": "AbcCDe123...", - "registration_access_token": "AbcCDe123...", - "redirect_uris": [ - "https://rucio-auth.cern.ch/auth/oidc_token", - "https://rucio-auth.cern.ch/auth/oidc_code", - ], - "client_name": "rucio-admin-client", - "client_uri": null, - "logo_uri": null, - "contacts": [ - "jaroslav.guenther@gmail.com" - ], - "tos_uri": null, - "token_endpoint_auth_method": "client_secret_basic", - "scope": "address fts phone openid profile offline_access \ - rucio email wlcg wlcg.groups fts:submit-transfer", - "grant_types": [ - "refresh_token", - "urn:ietf:params:oauth:grant-type:token-exchange", - "authorization_code" - ], - "response_types": [ - "code" - ], - "policy_uri": null, - "jwks_uri": null, - "jwks": null, - "jwksType": "URI", - "application_type": null, - "sector_identifier_uri": null, - "subject_type": null, - "request_object_signing_alg": null, - "userinfo_signed_response_alg": null, - "userinfo_encrypted_response_alg": null, - "userinfo_encrypted_response_enc": null, - "id_token_signed_response_alg": null, - "id_token_encrypted_response_alg": null, - "id_token_encrypted_response_enc": null, - "default_max_age": 60000, - "require_auth_time": true, - "default_acr_values": null, - "initiate_login_uri": null, - "post_logout_redirect_uris": null, - "claims_redirect_uris": [], - "request_uris": [], - "software_statement": null, - "software_id": null, - "software_version": null, - "code_challenge_method": null, - "registration_client_uri": "https://wlcg.cloud.cnaf.infn.it/register/fdc297fc-0907-4a68-9022-3ccc7dd2501a", - "client_secret_expires_at": 0, - "client_id_issued_at": 1574700620 -} -``` +To enable OIDC authentication and authorization with Rucio using JSON Web Tokens (JWTs) and OAuth2.0, you need an Identity Provider (IdP) that supports OIDC. First, you need to register a client (let's call it `user_auth_client`) with the IdP using the following criteria: -Example of the __Rucio Admin IAM Client__ [C2] configuration: +### User Authentication Client +- **Grant Type**: `authorization_code` +- **Scopes**: Minimum `openid` and `profile` +- **Audience**: Recommended: `rucio` +- **Redirect URIs**: `https:///auth/oidc_code` -```bash -{ - "client_id": "AbcDe123...", - "registration_access_token": "AbcDe123...", - "client_secret": "AbcDe123...", - "redirect_uris": [], - "client_name": null, - "client_uri": null, - "logo_uri": null, - "contacts": [ - "jaroslav.guenther@gmail.com" - ], - "tos_uri": null, - "token_endpoint_auth_method": "client_secret_basic", - "scope": "address scim:read phone email wlcg profile \ - fts:submit-transfer rucio fts fts:submit-transfer", - "grant_types": [ - "client_credentials" - ], - "response_types": [], - "policy_uri": null, - "jwks_uri": null, - "jwks": null, - "jwksType": "URI", - "application_type": null, - "sector_identifier_uri": null, - "subject_type": null, - "request_object_signing_alg": null, - "userinfo_signed_response_alg": null, - "userinfo_encrypted_response_alg": null, - "userinfo_encrypted_response_enc": null, - "id_token_signed_response_alg": null, - "id_token_encrypted_response_alg": null, - "id_token_encrypted_response_enc": null, - "default_max_age": 60000, - "require_auth_time": true, - "default_acr_values": null, - "initiate_login_uri": null, - "post_logout_redirect_uris": null, - "claims_redirect_uris": [], - "request_uris": [], - "software_statement": null, - "software_id": null, - "software_version": null, - "code_challenge_method": null, - "registration_client_uri": "https://wlcg.cloud.cnaf.infn.it/register/5b5e5d37-926b-4b42-8a98-a0b4b28baf18", - "client_secret_expires_at": 0, - "client_id_issued_at": 1574700703 -} -``` +#### Creating `idpsecrets.json` -To make the Rucio server aware of the two clients above, one has to exchange the -empty dictionary in `etc/idpsecrets.json` file with one containing the -relevant information. Example of such dictionary (for multiple IdPs) follows: +For a single VO instance, create a file `idpsecrets.json` with the following content: ```json { - "": { - - "issuer": "https://", - - "redirect_uris": [ - "https:///auth/oidc_token", - "https:///auth/oidc_code" - ], - - "client_id": "", - "client_secret": "", - - # this is not really needed for the OIDC functionality - # but it is suggested to store it anyway as it is required - # to edit the client in INDIGO IAM - "registration_access_token": "", - - "SCIM": { - "client_id": "", - "client_secret": "", - "registration_access_token": "" - } - }, - - "wlcg": { - - "issuer": "https://wlcg.cloud.cnaf.infn.it/", - - "redirect_uris": [ - "https://rucio-auth.cern.ch/auth/oidc_token", - "https://rucio-auth.cern.ch/auth/oidc_code" - ], - - "client_id": "fdc297fc-09 ...", - "client_secret": "APFVcga_X ...", - "registration_access_token": "eyJraWQiOi ...", - - "SCIM": { - "client_id": "5b5e5d3 ...", - "client_secret": "IQqAcMOa ...", - "registration_access_token": "eyJraW ..." - } - }, - - "xdc": { ... }, + "def": { + "user_auth_client": [ + { + "issuer": "https://mock-oidc-provider", + "client_id": "mock-client-id", + "client_secret": "secret", + "redirect_uris": "https://rucio/auth/oidc_code" + } + ] + } } ``` -After this is done, please make sure your `rucio.cfg` file contains the -following section: +#### Requiring extra Scopes +If you want to add extra scope of ID token for authentication you can add it as required in server by seeting + +Scopes can be extended if needed using the following configuration: ```cfg [oidc] -idpsecrets = /path/to/your/idpsecrets.json -admin_issuer = -expected_audience = '' -expected_scope = 'openid profile' +id_token_extra_scopes= email, ``` -Parameters __idpsecrets__ and __admin_issuer__ have to be present. -__IdP nickname__ stands for your preferred IdP (e.g. 'wlcg'). The IdP -specified under __admin_issuer__ will be contacted to get information about Rucio -Users (SCIM) and to request tokens for the Rucio __root__ account. The -__expected_scope__ and __expected_audence__ parameters are optional and if not filled, -the Rucio server will set them to `openid profile` and `rucio` -respectively. The expected scopes and audiences have to be configured -correspondingly on the side of your registered clients at your IdP (usually you -can control accepted scopes and audiences for your clients via an IdP web -interface). - -To finalize the process, one should assign the OIDC identities to the relevant -Rucio __admin_account__ (e.g. 'root', 'ddmadmin'). This identity ID is -composed of the Rucio Service IAM Account [A] subject claim and -issuer url such as demonstrated below: - -```bash -# Add the Rucio Service IAM Account ID as an OIDC identity -rucio-admin identity add --account rucio_admin_account \ - --type OIDC \ - --id "SUB=b3127dc7-2be3-417b-9647-6bf61238ad01, \ - ISS=https://wlcg.cloud.cnaf.infn.it/" \ - --email "wlcg-doma-rucio@cern.ch" +Add corresponding claims existence for the above scopes +```cfg +[oidc] +id_token_extra_scopes= email +id_token_extra_claims= email ``` -A second identity has to be added to the same __admin_account__ representing -the __client_credentials__ flow of the Rucio application, i.e. of the -__Rucio Admin IAM Client__ [C2] from above. This identity consists of -the __client_id__ of [C2] and the issuer (the token obtained via the -client credentials flow using [C2] will contain in the __sub__ claim the -__client_id__ of [C2] instead of Rucio Service IAM Account [A] __sub__ claim): +Rucio will exchange the authorization code using user_auth_client for an ID token and an access token. If additional scopes are required for the access token, configure them as follows: -```bash -# Add the Rucio Admin IAM Client client_id as an OIDC identity -rucio-admin identity add --account rucio_admin_account \ - --type OIDC \ - --id "SUB=5b5e5d37-926b-4b42-8a98-a0b4b28baf18, \ - ISS=https://wlcg.cloud.cnaf.infn.it/" \ - --email "wlcg-doma-rucio@cern.ch" -``` +[oidc] +extra_access_token_scope= extra_scopes -Note: In case you can not/will not run any IAM -> Rucio user mapping tool in -order to sync Rucio accounts with their IAM identities, you should assign the -appropriate OIDC identity manually (as in the example above) to each Rucio -account which is meant to use the OIDC authN/Z: +Ensure all required scopes are included as needed. -```bash -# Add an IAM User Account ID as an OIDC identity -# (needs to be done for each user!) -rucio-admin identity add --account rucio_user_account \ - --type OIDC \ - --id "SUB=5b5e5d37-926b-4b42-8a98-a0b4b28baf18, \ - ISS=https://wlcg.cloud.cnaf.infn.it/" \ - --email "wlcg-doma-rucio@cern.ch" +#### Allowing Refresh +```cfg +[oidc] +id_token_extra_scopes= offline_access ``` -Finally, in order to ensure the correct lifetime management of the tokens and auth -sessions, one has to run the __oauth-manager__ daemon. +### Transfer +To use tokens for transfers you need to register another client lets call it `client_credential_client` which needs following. -### Configuration for Daemons +- **Grant Type**: `client_credentials` +- **Scopes**: `fts`, `storage.read:/` and `storage.modify:/` +- **Audience**: `` and `` -OIDC authN/Z is also supported by the Rucio conveyor daemons and more -specifically by the __conveyor-submitter__ and __conveyor-poller__ ones. -__Conveyor-submitter__ is responsible for submission of the transfers created in -connection with an existing Rucio rule. __Conveyor-poller__ is responsible for -polling the state of the transfers that have been submitted and updating the -relevant state in the database. +If you want to allow FTS to refresh storage token, allow refresh token to be returned too. -In order to enable this functionality, RSEs must have an attribute set as follows: +### **Configuration File Format (Single VO Syntax)** -```cfg -oidc_support: True +```json +{ + "def": { + "user_auth_client": [ + { + "issuer": "https://mock-oidc-provider", + "client_id": "mock-client-id", + "client_secret": "secret", + "redirect_uris": "https://rucio/auth/oidc_code" + } + ], + "client_credential_client": { + "client_id": "", + "client_secret": "", + "issuer": "https://indigoiam/" + } + } +} ``` -In general, the Rucio account which created such a rule will be used to request a -JWT token for OAuth2 authentication with FTS3. More specifically, there -are three Rucio authentication flows that are possible: - -1. __User Token Exchange__: In this case, a valid OIDC token that the user authenticated - with in Rucio is getting [exchanged](https://indigo-iam.github.io/docs/v/current/user-guide/api/oauth-token-exchange.html) - with an appropriate token that is intended to be served to the FTS3 server. - This FTS3 intended token must have a specific audience [*] as well as - specific scopes [**] that the FTS3 server expects, this applies for the next - authentication flows as well. It is also worth noting that the acquired FTS3 - intended token includes all original claims that were present in the initial token. - -1. __Admin Flow__: In this Rucio authN/Z flow, the [client_credentials](https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) - flow is used with the __Rucio Admin IAM Client__ [C2]. The __sub__ claim of the - acquired token becomes the __client_id__ of [C2]. In this case any group membership - that was present in the original token is not included in the new FTS3 intended - token. Additionally, for this flow to be successful a valid user OIDC token - must already be present in the database. - -1. __Admin Root Flow__: This scenario has the same logic as flow 2, with the - difference that it is used when the relevant rule is created by the - Rucio __admin_account__ (e.g. 'root'). - No other user token is involved in this case. - -In all three formerly mentioned cases, if a valid FTS3 intended token -already exists in the Rucio database then a new token is not requested -and the existing one is used. - -The OIDC authentication mechanism shall be configured by the -following parameters in the `rucio.cfg` file: +### Configuration for RSE +For RSEs which uses token, RSEs must have an attribute set as follows: -```cfg -[conveyor] -# if set to True, then only flow 1 will be tried -# if set to False, then flow 1 will never be tried -allow_user_oidc_tokens = False (default) - -# FTS3 intended audience [*] -request_oidc_audience = 'fts:example' (default) - -# FTS3 intended scopes [**] -request_oidc_scope = 'fts:submit-transfer' (default) ``` - -For the __conveyor-poller__ to work an additional configuration is needed: - -```cfg -[conveyor] -poller_oidc_account = rucio_admin_account +oidc_support: True ``` - -On an another level, the __reaper__ daemon can be also configured to -perform deletions of files on the storage by using an OIDC token, -the following configuration is needed: - -```cfg -[reaper] -oidc_account = rucio_admin_account -oidc_audience = same logic as [*] but for the storage -oidc_scope = same logic as [**] but for the storage +Lets say your RSE has protocol with prefix `/path/myexp/mypath` , if you want to use this as scope you needs to have `client_credential_client` +scope `storage:read:/path/myexp/mypath` and `storage:modify:/path/myexp/mypath`. If you want to register scopes as `storage:read:/myexp/mypath` and `storage:modify:/myexp/mypath` you need to set RSE's attribute as: +``` +oidc_base_path: /path ``` - -Note aside: For some IdPs it may happen that the scope and audience claims are -not a part of the token payload. For this reason Rucio has a fall-back mechanism -to get this information using the IdPs introspection endpoint. To allow Rucio to -introspect tokens that were not issued by its clients, please talk to the IdP -admin who should enable this functionality for your clients. - ### Rucio WebUI Login with CERN SSO By using the Rucio OIDC capabilities it is possible to integrate the diff --git a/docs/user/using_the_client.md b/docs/user/using_the_client.md index 8f158252769..9739a5153f9 100644 --- a/docs/user/using_the_client.md +++ b/docs/user/using_the_client.md @@ -104,17 +104,7 @@ email : root@abc.com ## Open ID Connect authentication examples -There are 3 CLI login methods. Two were introduced in order to avoid typing the -password in the Rucio CLI. The default Identity Provider `(IdP)/issuer` is -configured on the side of Rucio server. In case multiple IdPs are supported, -user can specify which one he desires to use by `--oidc-issuer=\` -option (where IdP nickname is the key under which issuers are configured on -Rucio server side in the *idpsecrets.json* file). In the following examples we -assume that user does not want to use the rucio account name specified in the -*rucio.cfg* file on the client side (if so `-a` parameter can be omitted). If -*auth_type* is specified to be "oidc" in the *rucio.cfg* file, `-S` can be -omitted as well. Furthermore, we use the same default issuer as configured on -Rucio server side. +There are 2 CLI login methods. 1. Login via user's browser + fetch code: @@ -128,22 +118,9 @@ Rucio server side. rucio -a=\ -S=OIDC --oidc-polling -v whoami ``` -1. Automatic login: - ```bash - rucio -a=\ \ - -S=OIDC --oidc-user=\ \ - --oidc-password=\ \ - --oidc-auto \ - -v \ - whoami - ``` - -We strongly discourage this approach, typing your password in CLI does not -comply with OAuth2/OIDC standard ! -Options for automatic token refresh: Assuming the rucio-oauth-manager daemon is -running on the Rucio server side, one can also grant Rucio a refresh token and +Options for automatic token refresh: Assuming the one can also grant Rucio a refresh token and specify the time for which Rucio should act on behalf of the user (in hours) using the `--refresh-lifetime` option: @@ -158,7 +135,7 @@ rucio -a=\ \ If Rucio Server is granted a user both valid access and refresh tokens, it is also possible to configure Rucio Client to ask Rucio Server for token -refresh. Assuming user used one of the 3 CLI authentication methods above + +refresh. Assuming user used one of the 2 CLI authentication methods above + requested offline_access in the scope, rucio.cfg file can be configured with the following parameters in the `[client]` section: From 2f969d9bfa38007ec65be283fc085fe208adc0f6 Mon Sep 17 00:00:00 2001 From: Anil Panta Date: Tue, 18 Feb 2025 23:28:34 -0500 Subject: [PATCH 2/3] update-oidc-doc --- docs/operator/installing_server.md | 144 ++++++++++++----------------- docs/operator/multi_vo_rucio.md | 39 ++++++++ docs/user/using_the_client.md | 64 ++++++++++--- 3 files changed, 149 insertions(+), 98 deletions(-) diff --git a/docs/operator/installing_server.md b/docs/operator/installing_server.md index f5742bf2986..213b53f6f1d 100644 --- a/docs/operator/installing_server.md +++ b/docs/operator/installing_server.md @@ -220,7 +220,7 @@ For a single VO instance, create a file `idpsecrets.json` with the following con "def": { "user_auth_client": [ { - "issuer": "https://mock-oidc-provider", + "issuer": "", "client_id": "mock-client-id", "client_secret": "secret", "redirect_uris": "https://rucio/auth/oidc_code" @@ -229,37 +229,71 @@ For a single VO instance, create a file `idpsecrets.json` with the following con } } ``` - -#### Requiring extra Scopes -If you want to add extra scope of ID token for authentication you can add it as required in server by seeting - -Scopes can be extended if needed using the following configuration: - +And please make sure you specify the path to this file either via env var `IDP_SECRETS_FILE` or in rucio.cfg as ```cfg [oidc] -id_token_extra_scopes= email, +idpsecrets = /path/to/your/idpsecrets.json ``` -Add corresponding claims existence for the above scopes +#### Requiring extra Scopes +If you want to add extra scope of ID token for authentication you can add it as required in server. + +Scopes can be extended if needed using the following configuration and corresponding claims existence for the scopes ```cfg [oidc] -id_token_extra_scopes= email -id_token_extra_claims= email +id_token_extra_scopes= email, extra_scope +id_token_extra_claims= email, claim_of_extra_scope ``` +Only claim existence is check for now. If you need functionality for exact claim's value match please contact us we can add that feature too. + Rucio will exchange the authorization code using user_auth_client for an ID token and an access token. If additional scopes are required for the access token, configure them as follows: [oidc] -extra_access_token_scope= extra_scopes +extra_access_token_scope= extra_access_scopes Ensure all required scopes are included as needed. -#### Allowing Refresh -```cfg -[oidc] -id_token_extra_scopes= offline_access +#### Adding user identity +To add user oidc identity you ned to get `SUB`, Subject Identifier, of the user in the IDP. Then run the command: +```shell +rucio account identity add --account jdoe --type OIDC --id 'SUB= ISS=' +``` +or legacy command +```shell +rucio-admin identity add --account jdoe --type OIDC --id 'SUB= ISS=' +``` +Example for IAM instance +```shell +rucio account identity add --account jdoe --type OIDC --id 'SUB=3ed4fg-6ff2-4097-ad3b-953e11bb52b8 ISS=https://panda-iam-doma.cern.ch/' ``` +#### Multiple IDP +To configure multiple IDPs your `idpsecrets.json` looks like: +```json +{ + "def": { + "user_auth_client": [ + { + "issuer": "", + "client_id": "mock-client-id", + "client_secret": "secret", + "redirect_uris": "https://rucio/auth/oidc_code", + "issuer_nickname": "issuer1" + }, + { + "issuer": "", + "client_id": "mock-client-id2", + "client_secret": "secret2", + "redirect_uris": "https://rucio/auth/oidc_code", + "issuer_nickname": "issuer2" + } + ] + } +} +``` +Notice now we *must* add `issuer_nickname` field to each idp. This is used by client to reference which issuer it is authenticating to. + ### Transfer To use tokens for transfers you need to register another client lets call it `client_credential_client` which needs following. @@ -267,16 +301,16 @@ To use tokens for transfers you need to register another client lets call it `cl - **Scopes**: `fts`, `storage.read:/` and `storage.modify:/` - **Audience**: `` and `` -If you want to allow FTS to refresh storage token, allow refresh token to be returned too. +If you want to allow FTS to refresh storage token, allow refresh token to be returned too i.e. add `offline_access` in the scopes. -### **Configuration File Format (Single VO Syntax)** +#### **Configuration File (idpsecrets.json) Format (Single VO Syntax)** ```json { "def": { "user_auth_client": [ { - "issuer": "https://mock-oidc-provider", + "issuer": "", "client_id": "mock-client-id", "client_secret": "secret", "redirect_uris": "https://rucio/auth/oidc_code" @@ -285,83 +319,23 @@ If you want to allow FTS to refresh storage token, allow refresh token to be ret "client_credential_client": { "client_id": "", "client_secret": "", - "issuer": "https://indigoiam/" + "issuer": "" } } } ``` -### Configuration for RSE +#### Configuration for RSE For RSEs which uses token, RSEs must have an attribute set as follows: ``` oidc_support: True ``` Lets say your RSE has protocol with prefix `/path/myexp/mypath` , if you want to use this as scope you needs to have `client_credential_client` -scope `storage:read:/path/myexp/mypath` and `storage:modify:/path/myexp/mypath`. If you want to register scopes as `storage:read:/myexp/mypath` and `storage:modify:/myexp/mypath` you need to set RSE's attribute as: +scope `storage:read:/path/myexp/mypath` and `storage:modify:/path/myexp/mypath`. + +If you want to register scopes as `storage:read:/myexp/mypath` and `storage:modify:/myexp/mypath` you need to set RSE's attribute as: ``` oidc_base_path: /path ``` -### Rucio WebUI Login with CERN SSO - -By using the Rucio OIDC capabilities it is possible to integrate the -[CERN SSO](https://auth.docs.cern.ch/user-documentation/oidc/oidc/) service with -the WebUI so users will be able to login with a CERN account. -Please note that in contrast to INDIGO IAM, the CERN IdP can only be -used for WebUI login at the moment and not for the other operations -that were described previously. The following steps are needed: - -1. The Rucio administrators need to create a new application at the - [Application Portal](https://application-portal.web.cern.ch/). - Please note that the __Application Identifier__ field will be the - audience claim in the tokens acquired by the CERN Authorization Service. - -1. In the newly created Application, a new __SSO Registration__ is needed. - Please select OIDC in the - 'Which protocol does your application use for authentication?' question. - At the same time, the two Rucio redirect URIs are needed as - described in the `etc/idpsecrets.json` configuration that was mentioned previously. - -1. The new CERN IdP needs to be added in the `etc/idpsecrets.json` configuration, - with the newly acquired client secret that was given after step 2. - Please note that in this case the SCIM field needs to be filled even though - it will never be used for this IdP, one can just repeat the original - client_id and client_secret. The configuration will have the following format: - - ```json - { - # ... - "cern": { - - "issuer": "https://auth.cern.ch/auth/realms/cern", - - "redirect_uris": [ - "https:///auth/oidc_token", - "https:///auth/oidc_code" - ], - - "client_id": "", # Same as Application Identifier - "client_secret": "", - - "SCIM": { - "client_id": "", - "client_secret": "", - } - } - # ... - } - ``` - -1. Finally, the CERN user identities need to be mapped to Rucio accounts - as it was previously described. One example mapping follows: - - ```bash - # Add an CERN User Account Username as an OIDC identity - # (needs to be done for each user!) - # Note that the SUB field is the CERN Account username - rucio-admin identity add --account rucio_user_account \ - --type OIDC \ - --id "SUB=ridona, \ - ISS=https://auth.cern.ch/auth/realms/cern" \ - --email "rucio@cern.ch" - ``` + diff --git a/docs/operator/multi_vo_rucio.md b/docs/operator/multi_vo_rucio.md index 758a04cca8d..59213bb1f83 100644 --- a/docs/operator/multi_vo_rucio.md +++ b/docs/operator/multi_vo_rucio.md @@ -74,6 +74,45 @@ submitting and polling transfers to use the correct certificates. [3 char vo name] = [path/to/vo/proxy] ``` +## Changes to Token config +Create a file `idpsecrets.json` with the following content: +```json +{ + "": { + "user_auth_client": [ + { + "issuer": "", + "client_id": "mock-client-id", + "client_secret": "secret", + "redirect_uris": "https://rucio/auth/oidc_code" + } + ], + "client_credential_client": { + "client_id": "", + "client_secret": "", + "issuer": "" + } + }, + "": { + "user_auth_client": [ + { + "issuer": "", + "client_id": "mock-client-id", + "client_secret": "secret", + "redirect_uris": "https://rucio/auth/oidc_code" + } + ], + "client_credential_client": { + "client_id": "", + "client_secret": "", + "issuer": "" + } + }, +} +``` + +Now replace ``/`` with your VOs that you have. + ## Role of the super_root For overall administration of Multi-VO Rucio another layer of admin role has diff --git a/docs/user/using_the_client.md b/docs/user/using_the_client.md index 9739a5153f9..bf04b00023d 100644 --- a/docs/user/using_the_client.md +++ b/docs/user/using_the_client.md @@ -103,26 +103,65 @@ email : root@abc.com ``` ## Open ID Connect authentication examples - There are 2 CLI login methods. 1. Login via user's browser + fetch code: - ```bash - rucio -a=\ -S=OIDC -v whoami + ```bash + rucio -a=\ -S=OIDC -v whoami + ``` + OR with rucio.cfg as: + ```cfg + [client] + + rucio_host = https://\:443 + auth_host = https://\:443 + auth_type = oidc + account = \ + ``` + ```bash + rucio -v whoami + ``` + +2. Login via user's browser + polling Rucio auth server: + + ```bash + rucio -a=\ -S=OIDC --oidc-polling -v whoami + ``` + Or with rucio.cfg as: + ```cfg + [client] + rucio_host = https://\:443 + auth_host = https://\:443 + auth_type = oidc + oidc_polling = True + account = \ + ``` + ```bash + rucio -v whoami + ``` + + +If your rucio has multi idp setup you must specify issuer's nickname in client. You need ask you rucio provider for this value.: + ```bash + rucio -a=\ -S=OIDC --oidc-issuer -v whoami + ``` + or with rucio.cfg as: + ```cfg + [client] + rucio_host = https://\:443 + auth_host = https://\:443 + auth_type = oidc + oidc_polling = True + oidc_issuer=\ + account = \ ``` - -1. Login via user's browser + polling Rucio auth server: - ```bash - rucio -a=\ -S=OIDC --oidc-polling -v whoami + rucio -v whoami ``` - - - Options for automatic token refresh: Assuming the one can also grant Rucio a refresh token and specify the time for which Rucio should act on behalf of the user (in hours) -using the `--refresh-lifetime` option: +using the `--refresh-lifetime` option and adding offline_access to `--oidc-scope`: ```bash rucio -a=\ \ @@ -132,6 +171,7 @@ rucio -a=\ \ -v \ whoami ``` +If you are specifying the scope all the required scope is needed . (at minimum `openid profile` but can be more if configured on server. Please check with rucio rucio provider) If Rucio Server is granted a user both valid access and refresh tokens, it is also possible to configure Rucio Client to ask Rucio Server for token @@ -165,9 +205,7 @@ rucio_host = https://\:443 auth_host = https://\:443 auth_type = oidc account = \ -oidc_audience = rucio oidc_scope = openid profile offline_access -oidc_issuer = wlcg auth_oidc_refresh_active = true auth_oidc_refresh_before_exp = 20 ``` From 01a27b42b3a00497cb955db161a98cd33f623d65 Mon Sep 17 00:00:00 2001 From: Anil Panta Date: Thu, 20 Feb 2025 12:15:15 -0500 Subject: [PATCH 3/3] update-oidc-doc-offline_acccess --- docs/operator/installing_server.md | 20 ++++++++++---------- docs/operator/multi_vo_rucio.md | 2 +- docs/user/using_the_client.md | 14 ++++++-------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/docs/operator/installing_server.md b/docs/operator/installing_server.md index 213b53f6f1d..535d08ca6e7 100644 --- a/docs/operator/installing_server.md +++ b/docs/operator/installing_server.md @@ -245,9 +245,9 @@ id_token_extra_scopes= email, extra_scope id_token_extra_claims= email, claim_of_extra_scope ``` -Only claim existence is check for now. If you need functionality for exact claim's value match please contact us we can add that feature too. +Only claim existence is checked for now. Please open a [feature request](https://github.com/rucio/rucio/issues/new?template=feature.yaml) if you would be interested in having this check expanded to take into account the claim value as well. -Rucio will exchange the authorization code using user_auth_client for an ID token and an access token. If additional scopes are required for the access token, configure them as follows: +Rucio will exchange the authorization code using `user_auth_client` for an ID token and an access token. If additional scopes are required for the access token, configure them as follows: [oidc] extra_access_token_scope= extra_access_scopes @@ -255,7 +255,7 @@ extra_access_token_scope= extra_access_scopes Ensure all required scopes are included as needed. #### Adding user identity -To add user oidc identity you ned to get `SUB`, Subject Identifier, of the user in the IDP. Then run the command: +To add user oidc identity you need to get the `SUB` (Subject Identifier) of the user in the IDP. Then run the command: ```shell rucio account identity add --account jdoe --type OIDC --id 'SUB= ISS=' ``` @@ -269,7 +269,7 @@ rucio account identity add --account jdoe --type OIDC --id 'SUB=3ed4fg-6ff2-4097 ``` #### Multiple IDP -To configure multiple IDPs your `idpsecrets.json` looks like: +To configure multiple IDPs, your `idpsecrets.json` should look like: ```json { "def": { @@ -292,10 +292,10 @@ To configure multiple IDPs your `idpsecrets.json` looks like: } } ``` -Notice now we *must* add `issuer_nickname` field to each idp. This is used by client to reference which issuer it is authenticating to. +Notice now we *must* add an `issuer_nickname` field to each IDP. This is used by the client to reference which issuer it is authenticating to. ### Transfer -To use tokens for transfers you need to register another client lets call it `client_credential_client` which needs following. +To use tokens for transfers, you need to register another client `client_credential_client`, configured as such: - **Grant Type**: `client_credentials` - **Scopes**: `fts`, `storage.read:/` and `storage.modify:/` @@ -303,7 +303,7 @@ To use tokens for transfers you need to register another client lets call it `cl If you want to allow FTS to refresh storage token, allow refresh token to be returned too i.e. add `offline_access` in the scopes. -#### **Configuration File (idpsecrets.json) Format (Single VO Syntax)** +#### Configuration File (`idpsecrets.json`) Format (Single VO Syntax) ```json { @@ -326,13 +326,13 @@ If you want to allow FTS to refresh storage token, allow refresh token to be ret ``` #### Configuration for RSE -For RSEs which uses token, RSEs must have an attribute set as follows: +For RSEs which use tokens, RSEs must have an attribute set as follows: ``` oidc_support: True ``` -Lets say your RSE has protocol with prefix `/path/myexp/mypath` , if you want to use this as scope you needs to have `client_credential_client` -scope `storage:read:/path/myexp/mypath` and `storage:modify:/path/myexp/mypath`. +Let's say your RSE has protocol with prefix `/path/myexp/mypath` , if you want to use this as scope you need to have `client_credential_client` +scopes `storage:read:/path/myexp/mypath` and `storage:modify:/path/myexp/mypath`. If you want to register scopes as `storage:read:/myexp/mypath` and `storage:modify:/myexp/mypath` you need to set RSE's attribute as: ``` diff --git a/docs/operator/multi_vo_rucio.md b/docs/operator/multi_vo_rucio.md index 59213bb1f83..bbb6567b0eb 100644 --- a/docs/operator/multi_vo_rucio.md +++ b/docs/operator/multi_vo_rucio.md @@ -111,7 +111,7 @@ Create a file `idpsecrets.json` with the following content: } ``` -Now replace ``/`` with your VOs that you have. +Now replace ``/`` with the instance VOs. ## Role of the super_root diff --git a/docs/user/using_the_client.md b/docs/user/using_the_client.md index bf04b00023d..5a707a12f8a 100644 --- a/docs/user/using_the_client.md +++ b/docs/user/using_the_client.md @@ -142,7 +142,7 @@ There are 2 CLI login methods. ``` -If your rucio has multi idp setup you must specify issuer's nickname in client. You need ask you rucio provider for this value.: +If the Rucio instance is configured for multi-IDP, you must specify the issuer's nickname in the client. You can request this value from the instance's operators. ```bash rucio -a=\ -S=OIDC --oidc-issuer -v whoami ``` @@ -159,19 +159,19 @@ If your rucio has multi idp setup you must specify issuer's nickname in client. ```bash rucio -v whoami ``` + Options for automatic token refresh: Assuming the one can also grant Rucio a refresh token and specify the time for which Rucio should act on behalf of the user (in hours) -using the `--refresh-lifetime` option and adding offline_access to `--oidc-scope`: +using the `--oidc-refresh-lifetime` option and adding `offline_access` to `--oidc-scope`: -```bash +```shell rucio -a=\ \ -S=OIDC \ - --oidc-scope="openid profile offline_access" \ + --oidc-scope='offline_access' \ --oidc-refresh-lifetime=24 \ -v \ whoami ``` -If you are specifying the scope all the required scope is needed . (at minimum `openid profile` but can be more if configured on server. Please check with rucio rucio provider) If Rucio Server is granted a user both valid access and refresh tokens, it is also possible to configure Rucio Client to ask Rucio Server for token @@ -191,8 +191,6 @@ gets to `auth_oidc_refresh_before_exp` minutes (20 min default) before token expiration, Rucio Client will ask Rucio Server for token refresh with every command. If the token has been refreshed in the recent 5 min already once, the same one will be returned (protection on the Rucio Server side). If the -presented token has been refreshed automatically on the Rucio Server side by a -oauth_manager daemon run, it will return this existing new token. If the presented token is invalid/expired/does not have refresh token in the DB, no refresh will be attempted. @@ -205,7 +203,7 @@ rucio_host = https://\:443 auth_host = https://\:443 auth_type = oidc account = \ -oidc_scope = openid profile offline_access +oidc_scope = offline_access auth_oidc_refresh_active = true auth_oidc_refresh_before_exp = 20 ```