Obtaining an IAM access token from a CLI
A token can be obtained from a command-line interface (CLI) in different ways:
- using
oidc-agent - using scripts linked to this page, with the resource-owner password credentials flow (deprecated) or the device code flow
- using
curl.
In this section we recommend the installations of a set of tools that can help in managing tokens.
oidc-agent
oidc-agent is a useful tool to easily get and manage access tokens for command-line applications.
Installing oidc-agent
See oidc-agent installation instructions.
Quick Almalinux9 installation instructions
This recipe shows how to quickly install oidc-agent on Almalinux9.
Install the oidc-agent repofile
cd /etc/yum.repos.d
wget https://repo.data.kit.edu//data-kit-edu-almalinux9.repo
refresh the cache and install oidc-agent with
dnf makecache
dnf install oidc-agent
Bootstrapping oidc-agent
The first thing to do is to start oidc-agent.
This can be done issuing the following command:
$ eval $(oidc-agent)
Agent pid 62088
Registering a client
In order to obtain a token out of IAM, a user needs a client registered.
oidc-agent can automate this step and store client credentials securely
on the user machine. This is a one-time operation, you do not need a new
client every time you need a token.
A new client can be registered using the oidc-gen command, as follows:
$ oidc-gen -w device wlcg
The -w device instructs oidc-agent to use the device code flow for the
authentication, which is the recommended way with IAM.
oidc-agent will display a list of different providers that can be used for registration:
[1] https://wlcg.cloud.cnaf.infn.it/
[2] https://iam-test.indigo-datacloud.eu/
...
[20] https://oidc.scc.kit.edu/auth/realms/kit/
Select one of the registered providers, or type a custom issuer (for IAM, the
last character of the issuer string is always a /, e.g.
https://wlcg.cloud.cnaf.infn.it/).
Then oidc-agent asks for the scopes, typing max (without quotes) allows to
get all the allowed scopes.
oidc-agent will register a new client and store the client credentials and a refresh token locally in encrypted form (the agent will ask for a password from the user).
As mentioned, oidc-gen is meant to be used only once, when you need a client registered.
Managing oidc-agent account configurations
To see the list of locally configured accounts use the following command:
> oidc-add -l
The following account configurations are usable:
DEEP-ac
XDC
atlas
...
cms-voms-importer
escape
escape-monitoring
iam-test
infn-cloud
wlcg
You can then load an account in the agent again with the oidc-add command, as follows:
oidc-add wlcg
Once you’ve loaded the account, you can use oidc-token to get tokens for that account.
Getting tokens with oidc-token
Tokens can be obtained using the oidc-token command, as follows:
oidc-token wlcg
This will request a token with all the scopes requested at client registration
time. To limit the scopes included in the token, the -s flag can be used, as
follows:
oidc-token -s storage.read:/ wlcg
The token audience can be limited using the --aud flag,
oidc-token --aud example.audience -s storage.read:/ wlcg
Accessing oidc-agent client configuration
Often is useful to get details about the client configuration generated
by oidc-agent. This can be done with the oidc-gen -p command, that is
used to print a client configuration, as in the following example:
❯ oidc-gen -p wlcg
Enter decryption password for account config 'wlcg':******
{
"name": "wlcg",
"client_name": "oidc-agent:wlcg",
"issuer_url": "https://wlcg.cloud.cnaf.infn.it/",
"device_authorization_endpoint": "https://wlcg.cloud.cnaf.infn.it/devicecode",
"daeSetByUser": 0,
"client_id": "*****",
"client_secret": "*****",
"refresh_token": "****.*****.",
"cert_path": "",
"scope": "storage.create:/ openid offline_access storage.read:/ eduperson_scoped_affiliation storage.modify:/ wlcg wlcg.groups eduperson_entitlement",
"audience": "",
"redirect_uris": ["edu.kit.data.oidc-agent:/redirect", "http://localhost:8080", "http://localhost:47947", "http://localhost:4242"],
"username": "",
"password": "",
"client_id_issued_at": 1600444894,
"registration_access_token": "****",
"registration_client_uri": "https://wlcg.cloud.cnaf.infn.it/register/****",
"token_endpoint_auth_method": "client_secret_basic",
"grant_types": ["urn:ietf:params:oauth:grant-type:device_code", "refresh_token"],
"response_types": ["token"],
"application_type": "web",
"cert_path": "",
"audience": ""
}
Scripts
Obtaining a token with the password flow
Warning
For security reasons, this grant type is deprecated in OAuth2.1 and it may no longer work in INDIGO IAM.The password flow allows a user to get a token from the IAM by using the IAM local credentials (i.e. the username/password credentials setup at IAM registration time).
In order to use the password flow, a non-privileged user has to:
- register a client following the instructions given in [the client registration][client-registration] section
- Note down the
client_idof the generated client and ask an IAM administrator to enable the password flow for such client - Wait until the client as the password flow enabled
- Use a script similar to the one given here (or write your own following the recommendations of the RFC) to obtain a token out of the IAM
Obtaining a token with the device code flow
The device code flow allows a user to get a token from the IAM from a CLI interface while using an external browser for the authentication step. This is convenient since:
- it does not require any authorization from administrators (the device code flow can be requested by the user at client registration time)
- it allows the user to authenticate with any of the authentication mechanisms supported by the IAM
- it does not expose the user credentials to the client application
For nitty and gritty details on how the flow works, see the RFC.
After having registered a client with the device flow enabled (see client registration section), the device code flow can be used to obtain a token using a script like the one here which does the following:
- contacts the device flow endpoint to start a device flow authentication and authorization
- prints code information on the terminal
- waits for user input to proceed and obtain the token(s)
CURL
The aforementioned OAuth flows may also be directly performed with the curl command,
which is exactly the way the scripts obtain a token.
Here we show the client_credentials flow, specified in section 4.4 of the
RFC6749. It is tought for
service accounts, i.e. for scripts able to secure credentials (NOT public clients)
and which can be obtain a token with capabilities. The client credential flow does not
require a user approval step since it is not bounded to any user nor any user attributes,
such as groups. A typical client credential request could be
$ curl -u client-cred:secret http://localhost:8080/token -d grant_type=client_credentials -d scope=read-tasks -s | jq
{
"access_token": "eyJraWQiOiJy...",
"token_type": "Bearer",
"expires_in": 3599,
"scope": "read-tasks"
}
Set custom token expiration
INDIGO IAM supports the expires_in request parameter for custom token expiration,
which is applied when asking for an access token at the /token endpoint.
The token expiration may only be set shorter than the lifetime configured for the
Client (typically 3600 seconds) – visible by Administrators. In case a longer
lifetime is requested, IAM will shorten the token lifetime to the configured one.
A typical token request with custom lifetime (here 10 seconds) in case of client_credentials flow
is
$ curl -u client-cred:secret http://localhost:8080/token -d expires_in=10 -d grant_type=client_credentials -d scope=read-tasks -s | jq
{
"access_token": "eyJraWQiOiJy...",
"token_type": "Bearer",
"expires_in": 9,
"scope": "read-tasks"
}