Staging instance, all changes can be removed at any time

Skip to content

cli: Add auth command group

Add a CLI tool to easily retrieve bearer tokens for Web API authentication.

$ swh auth
Usage: swh auth [OPTIONS] COMMAND [ARGS]...

  Authenticate Software Heritage users with OpenID Connect.

  This CLI tool eases the retrieval of bearer tokens to authenticate a user
  querying the Software Heritage Web API.

Options:
  --oidc-server-url TEXT  URL of OpenID Connect server (default to
                          "https://auth.softwareheritage.org/auth/")
  --realm-name TEXT       Name of the OpenID Connect authentication realm
                          (default to "SoftwareHeritage")
  --client-id TEXT        OpenID Connect client identifier in the realm
                          (default to "swh-web")
  -h, --help              Show this message and exit.

Commands:
  login    Login and create new offline OpenID Connect session.
  logout   Logout from an offline OpenID Connect session.
  refresh  Refresh an offline OpenID Connect session.

The proposed workflow to authenticate API calls is the following.

When a user has an account on the swh Identity Provider server (Keycloak), he can login using this tool and get its authentication tokens to send in HTTP headers when querying the Web API.

$ swh auth login johndoe | jq
Password: 
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPSnhVQ0p0TmJQT0NOUGFNNmc3ZU1zY2pqTXhoem9vNGxZaFhsa1c2TWhBIn0.eyJqdGkiOiI3NjMzNTAzZi04NGFjLTRmZTMtOGRmNS01ZTQ4MTAxZjAwMmIiLCJleHAiOjE1ODQ3MjE3NTAsIm5iZiI6MCwiaWF0IjoxNTg0NzIxMTUwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvU29mdHdhcmVIZXJpdGFnZSIsImF1ZCI6WyJzd2gtd2ViIiwiYWNjb3VudCJdLCJzdWIiOiJmZWFjZDM0NC1iNDY4LTRhNjUtYTIzNi0xNGY2MWU2YjcyMDAiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJzd2gtd2ViIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiYzE0ZTFiN2ItODI2My00ODUyLWJkMWMtYWRjN2JjMTJhMTM2IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIqIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsic3doLXdlYiI6eyJyb2xlcyI6WyJ0aHJvdHRsaW5nLWV4ZW1wdGVkIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiSm9obiBEb2UiLCJncm91cHMiOlsiL3BhcnRuZXJzIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImpvaG5kb2UiLCJnaXZlbl9uYW1lIjoiSm9obiIsImZhbWlseV9uYW1lIjoiRG9lIiwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSJ9.hFeLjlxkj3OzotJDwbuIZrSePmJdxRnxMTAla_nhgTnKdmY4TcMxyA2gaAG3ig7sSKbO3s86XCsn4B943TygLgS_YXYkpulQdk3bwUTu4zISE2zBtB2NFUyFie05Zxq3Z6zrlAw9TAApq4Ig0VnS5axpYdiQaXiTif4bLPZzxVRJ5NTHZJjjXjv7XUXhbH62Su0xd7FdUaxWMvCFrEY3ONiFxZ9v8n_jZNYt_1A1qPuR-LvPhytu86xOq7IImKfyrRcfAfYHUDmA4S5XduE2viIDNA_0p2bUuYwQwhjfHbv7IASAGquW6DqA6hAJp4dafnPyiRUDdlwtWVypo-ttMw",
  "expires_in": 600,
  "refresh_expires_in": 0,
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJmNjMzMDE5MS01YTU4LTQxMDAtOGIzYS00ZDdlM2U1NjA3MTgifQ.eyJqdGkiOiI2ZjU5ZWFkNS05OWIzLTRiMWUtYWM3My0xNTRmYzc2NmNjYWIiLCJleHAiOjAsIm5iZiI6MCwiaWF0IjoxNTg0NzIxMTUwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvU29mdHdhcmVIZXJpdGFnZSIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hdXRoL3JlYWxtcy9Tb2Z0d2FyZUhlcml0YWdlIiwic3ViIjoiZmVhY2QzNDQtYjQ2OC00YTY1LWEyMzYtMTRmNjFlNmI3MjAwIiwidHlwIjoiT2ZmbGluZSIsImF6cCI6InN3aC13ZWIiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJjMTRlMWI3Yi04MjYzLTQ4NTItYmQxYy1hZGM3YmMxMmExMzYiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InN3aC13ZWIiOnsicm9sZXMiOlsidGhyb3R0bGluZy1leGVtcHRlZCJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBvZmZsaW5lX2FjY2VzcyJ9.h8AxJU1_ouNrwnz6NKKx8AKBu2UbtOu1riP4Jil7XWU",
  "token_type": "bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPSnhVQ0p0TmJQT0NOUGFNNmc3ZU1zY2pqTXhoem9vNGxZaFhsa1c2TWhBIn0.eyJqdGkiOiIwZGIwMmM5Zi0yZGJlLTRiMjgtOTYzNS1lMGVhNjliMWM3NjEiLCJleHAiOjE1ODQ3MjE3NTAsIm5iZiI6MCwiaWF0IjoxNTg0NzIxMTUwLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvU29mdHdhcmVIZXJpdGFnZSIsImF1ZCI6InN3aC13ZWIiLCJzdWIiOiJmZWFjZDM0NC1iNDY4LTRhNjUtYTIzNi0xNGY2MWU2YjcyMDAiLCJ0eXAiOiJJRCIsImF6cCI6InN3aC13ZWIiLCJhdXRoX3RpbWUiOjAsInNlc3Npb25fc3RhdGUiOiJjMTRlMWI3Yi04MjYzLTQ4NTItYmQxYy1hZGM3YmMxMmExMzYiLCJhY3IiOiIxIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiSm9obiBEb2UiLCJncm91cHMiOlsiL3BhcnRuZXJzIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImpvaG5kb2UiLCJnaXZlbl9uYW1lIjoiSm9obiIsImZhbWlseV9uYW1lIjoiRG9lIiwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSJ9.i5QcmvmAYv4m26mrMQZi_FUuKNqg3I9yN8IdJ2nGKS-1q7jjJkjfVtOut6cdQ_V4UY7X9U7p4bXN3TRReOKn8dHsSlPwQpfzP9r6BimPAOFMS5yw-QAgOiLWFPtD8jlFwNCKNC5mT5iftTv-e9nEAGGgrFbgmsieIhVJzYb4sn8UvjX2YikHn2emYnzobrv_7hTHYOr6JXouzNKiziNOdEB1K_H4zAngfidXexZoQa872x_z0XpEYwZmWYc1PScGsAwc1qSQLz014StytnNiKcOjbUX8fQ64xT7xkf3QPiaye0usVzCNmh3kURfF3aW1Kmhax-AUKDItzO6fvHWtPQ",
  "not-before-policy": 1584551170,
  "session_state": "c14e1b7b-8263-4852-bd1c-adc7bc12a136",
  "scope": "openid email profile offline_access"
}

The access token must be sent in HTTP headers to authenticate requests to Web API. It has a short living period (usually 10 minutes) and must be renewed regularly.

To renew an access token, the refresh token has to be used by sending it to the Keycloak server in a refresh request. This token has a longer living period and can be used at anytime to get a new access token without the need to login again.

The refresh operation will be automatically handled if you use the swh.web.client.WebAPIClient class (diff incoming for that feature).

For users not working with Python, they can get a new access token through this command:

$ swh auth refresh $TOKEN | jq
"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJPSnhVQ0p0TmJQT0NOUGFNNmc3ZU1zY2pqTXhoem9vNGxZaFhsa1c2TWhBIn0.eyJqdGkiOiI1ZTJiZWJmMS1hNDhhLTRlYjAtODBjNi01MWM3MTlhOWNjZjUiLCJleHAiOjE1ODQ3MjIyMDksIm5iZiI6MCwiaWF0IjoxNTg0NzIxNjA5LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvU29mdHdhcmVIZXJpdGFnZSIsImF1ZCI6WyJzd2gtd2ViIiwiYWNjb3VudCJdLCJzdWIiOiJmZWFjZDM0NC1iNDY4LTRhNjUtYTIzNi0xNGY2MWU2YjcyMDAiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJzd2gtd2ViIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiYzE0ZTFiN2ItODI2My00ODUyLWJkMWMtYWRjN2JjMTJhMTM2IiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyIqIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsic3doLXdlYiI6eyJyb2xlcyI6WyJ0aHJvdHRsaW5nLWV4ZW1wdGVkIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIG9mZmxpbmVfYWNjZXNzIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJuYW1lIjoiSm9obiBEb2UiLCJncm91cHMiOlsiL3BhcnRuZXJzIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImpvaG5kb2UiLCJnaXZlbl9uYW1lIjoiSm9obiIsImZhbWlseV9uYW1lIjoiRG9lIiwiZW1haWwiOiJqb2huLmRvZUBleGFtcGxlLmNvbSJ9.J8BTceH3VrfDLw677CLys7cNZgiyaRC0_ewtegn_thdFzv1CwDULKnTIZHb-o_nBXhpA-hEaMUnu-tsE3yleCqMuKLjBq6c9kt2bVGvyR3-aIcbBb5gX6KzJPxPSBfvz-mQzjpuQMfswPMrYkDm--fQa3KgwuHc5CDs15rPSINKH7YZLkVbi4rIQ--7DhbqM3F4NPIUrTIAb7pSAIe2N9XzSZHc0ZbWbq7-NkxjOL-fOeI8oqPbQkFDIq7vzTcGYiiI9VJoIIxTHtkTYJHv6RdU3Yj2u0-im7P-_8em0waaHy1zAq2SBzXSKpadlQ22k6yiBrcQ6gNov0w896nVcPA"

It is also possible to logout from the authenticated session which invalidates all previously emitted tokens.

$ swh auth logout $TOKEN
Successfully logged out from OpenID Connect session

Migrated from D2861 (view on Phabricator)

Merge request reports

Loading