Who wants an OIDC CLI?

What even is an OIDC CLI?

oidc --issuer=https://issuer.example.com \
--port=5432 \
--client_id=some-client-id \
--client_secret=some-client-secret \
--profile \
--email \
# Browser launches https://issuer.example.com, using the authorization_endpoint returned by https://issuer.example.com/.well-known/openid-configuration# User logs in, approves scopes `openid`, `profile`, and `email`, and a code is returned to the CLI listening at http://localhost:5432# CLI exchanges code for `id_token` and `access_token`# Information from `id_token`, `access_token` (if a JWT), and `/userinfo` is displayedID Token:
"sub": "user",
"aud": "some-client-id",
"azp": "some-client-id",
"roles": [
"user's role"
"email": "some@email"
"email_verified": "true|false"
"iss": "https://issuer.example.com",
"jti": "fc7ed671-43e4-4294-aecc-8cf221650135"

It should just be that simple to get an id_token! No need to try for curl commands or Postman requests. It should be:

  • Self-configuring (via /.well-known/openid-configuration)
  • Stateless
  • Able to display all the information available (id_token, access_token, and /userinfo response)

Parameters such as --profile and --email could be aliases for a --scopes parameter that could be repeated to ask for multiple scopes, includes scopes beyond the built-in scopes to request OIDC claims as described in the OIDC specification §5.4. In this example, I include an additional scope --roles to indicate that a roles claim should be returned in the id_token.

Client Registration

Note that retrieving a token will require that a client is registered at the authorization server, with information as shown below. This would also require basic client authentication, using either basic or post semantics. The redirect_uri must reference localhost or some other hostname that can be locally aliased to localhost. The port is configurable as shown in the above example, and it’s possible that even a path could be configurable as well, since the OIDC CLI would be able to register any endpoints it likes.

client_id: some-client-id
client_secret: some-client-secret
redirect_uri: http://localhost:5432/
- openid
- profile
- email

Other client authentication mechanisms could be supported, with the additional options required to support them. This includes mTLS, which requires quite a bit more effort to configure with a CLI.

OAuth2 flows

In the above example, I assumed an OAuth2 authorization_code flow with one scope ( openid) to indicate that we would like an id_token, and additional scopes (email and phone) to indicate that we would like to populate that token with additional claims. It’s also possible that the CLI could support a hybrid or id_token only request, perhaps with a parameter such as --request=id_token .

Sound Interesting?

Let me know if you think this would be useful or add value. Feels like it could be done pretty easily in several languages — just need to pick the right language, security framework, and CLI framework combination. Implementation issues such as support for non-HTTPS authorization servers for local debugging could be secure-by-default but allow some leeway for localhost (note that RFC 6749 §3.1 does require the use of TLS).



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store