OpenID Connect client library for the BEAM.


Keywords
client, elixir, erlang, openid, openid-client, openid-connect, security-wg
License
Apache-2.0

Documentation

OpenID Connect Logo

oidcc

OpenID Connect client library for Erlang.

EEF Security WG project Main Branch Module Version Total Download License Last Updated Coverage Status OpenSSF Best Practices OpenSSF Scorecard


OpenID Connect Certified Logo

OpenID Certified by Jonatan Männchen at the Erlang Ecosystem Foundation of multiple Relaying Party conformance profiles of the OpenID Connect protocol: For details, check the Conformance Test Suite.


Erlang Ecosystem Foundation Logo

The refactoring for v3 and the certification is funded as an Erlang Ecosystem Foundation stipend entered by the Security Working Group.


Security Audit For Erlang and Elixir

A security audit was performed by SAFE-Erlang-Elixir more info HERE.


Supported Features

Setup

Please note that the minimum supported Erlang OTP version is OTP26.

Erlang

directly

{ok, Pid} =
    oidcc_provider_configuration_worker:start_link(#{
        issuer => <<"https://accounts.google.com">>,
        name => {local, google_config_provider}
    }).

via supervisor

-behaviour(supervisor).

%% ...

init(_Args) ->
    SupFlags = #{strategy => one_for_one},
    ChildSpecs = [
        #{
            id => oidcc_provider_configuration_worker,
            start =>
                {oidcc_provider_configuration_worker, start_link, [
                    #{
                        issuer => "https://accounts.google.com",
                        name => {local, myapp_oidcc_config_provider}
                    }
                ]},
            shutdown => brutal_kill
        }
    ],
    {ok, {SupFlags, ChildSpecs}}.

Elixir

directly

{:ok, _pid} =
  Oidcc.ProviderConfiguration.Worker.start_link(%{
    issuer: "https://accounts.google.com",
    name: Myapp.OidccConfigProvider
  })

via Supervisor

Supervisor.init(
  [
    {Oidcc.ProviderConfiguration.Worker,
     %{
       issuer: "https://accounts.google.com",
       name: Myapp.OidccConfigProvider
     }}
  ],
  strategy: :one_for_one
)

Usage

Companion libraries

oidcc offers integrations for various libraries:

Erlang

%% Create redirect URI for authorization
{ok, RedirectUri} = oidcc:create_redirect_url(
    myapp_oidcc_config_provider,
    <<"client_id">>,
    <<"client_secret">>,
    #{redirect_uri => <<"https://example.com/callback">>}
),

%% Redirect user to `RedirectUri`

%% Retrieve `code` query / form param from redirect back

%% Exchange code for token
{ok, Token} =
    oidcc:retrieve_token(
        AuthCode,
        myapp_oidcc_config_provider,
        <<"client_id">>,
        <<"client_secret">>,
        #{redirect_uri => <<"https://example.com/callback">>}
    ),

%% Load userinfo for token
{ok, Claims} =
    oidcc:retrieve_userinfo(
        Token,
        myapp_oidcc_config_provider,
        <<"client_id">>,
        <<"client_secret">>,
        #{}
    ),

%% Load introspection for access token
{ok, Introspection} =
    oidcc:introspect_token(
        Token,
        myapp_oidcc_config_provider,
        <<"client_id">>,
        <<"client_secret">>,
        #{}
    ),

%% Refresh token when it expires
{ok, RefreshedToken} =
    oidcc:refresh_token(
        Token,
        myapp_oidcc_config_provider,
        <<"client_id">>,
        <<"client_secret">>,
        #{}
    ).

for more details, see https://hexdocs.pm/oidcc/oidcc.html

Elixir

# Create redirect URI for authorization
{:ok, redirect_uri} =
  Oidcc.create_redirect_url(
    Myapp.OidccConfigProvider,
    "client_id",
    "client_secret",
    %{redirect_uri: "https://example.com/callback"}
  )

# Redirect user to `redirect_uri`

# Retrieve `code` query / form param from redirect back

# Exchange code for token
{:ok, token} =
  Oidcc.retrieve_token(
    auth_code,
    Myapp.OidccConfigProvider,
    "client_id",
    "client_secret",
    %{redirect_uri: "https://example.com/callback"}
  )

# Load userinfo for token
{:ok, claims} =
  Oidcc.retrieve_userinfo(
    token,
    Myapp.OidccConfigProvider,
    "client_id",
    "client_secret",
    %{expected_subject: "sub"}
  )

# Load introspection for access token
{:ok, introspection} =
  Oidcc.introspect_token(
    token,
    Myapp.OidccConfigProvider,
    "client_id",
    "client_secret"
  )

# Refresh token when it expires
{:ok, refreshed_token} =
  Oidcc.refresh_token(
    token,
    Myapp.OidccConfigProvider,
    "client_id",
    "client_secret"
  )

for more details, see https://hexdocs.pm/oidcc/Oidcc.html