JokenJwks.DefaultStrategyTemplate (Joken JWKS v1.6.0) View Source
A JokenJwks.SignerMatchStrategy
template that has a window of time for refreshing its
cache. This is a template and not a concrete implementation. You should use
this module
in order to use the default strategy.
This implementation is a task that should be supervised. It loops on a time window checking whether it should re-fetch keys or not.
Every time a bad kid is received it writes to an ets table a counter to 1. When the task loops, it polls for the counter value. If it is more than zero it starts re-fetching the cache. Upon successful fetching, it zeros the counter once again. This way we avoid overloading the JWKS server.
It will try to fetch signers when supervision starts it. This can be a sync or async operation
depending on the value of first_fetch_sync
. It defaults to false
.
Resiliency
This strategy tries to be smart about keys it can USE to verify signatures. For example, if the provider has encryption keys, it will skip those (any key with field "use" with value "enc").
Also, if the running BEAM instance has no support for a given signature algorithm (future ones possible not implemented on the given OpenSSL + BEAM + JOSE set) it will also skip.
Be sure to check your logs as if there are NO signers available it will log a warning telling you that.
For debugging purpouses, calling the function fetch_signers/2
directly might be helpful.
Usage
This strategy must be under your apps' supervision tree. It must be explicitly used under a module so that you can have more than one JWKS source.
When using this strategy, there is an init_opts/1
callback that can be overridden. This is called
upon supervision start. It should return a keyword list with all the options. This follows the
standard practice of allowing a callback for using runtime configuration. It can override all
other options as this has higher preference.
Configuration
Other than the init_opts/1
callback you can pass options through Mix.Config
and when starting
the supervisor. The order of preference in least significant order is:
- Per environment
Mix.Config
- Supervisor child options
init_opts/1
callback
The only mandatory option is jwks_url
(binary()
) that is, usually, a
runtime parameter like a system environment variable. It is recommended to
use the init_opts/1
callback.
Other options are:
time_interval
(integer()
- default 60_000 (1 minute)): time interval for polling if it is needed to re-fetch the keyslog_level
(:none | :debug | :info | :warn | :error
- default:debug
): the level of log to use for events in the strategy like HTTP errors and so on. It is advised not to turn off logging in productionshould_start
(boolean()
- defaulttrue
): whether to start the supervised polling task. For tests, this should be falsefirst_fetch_sync
(boolean()
- defaultfalse
): whether to fetch the first time synchronously or asyncexplicit_alg
(String.t()
): the JWS algorithm for use with the key. Overrides the one in the JWKhttp_max_retries_per_fetch
(pos_integer()
- default10
): passed toTesla.Middleware.Retry
http_delay_per_retry
(pos_integer()
- default500
): passed toTesla.Middleware.Retry
Examples
defmodule JokenExample.MyStrategy do
use JokenJwks.DefaultStrategyTemplate
def init_opts(opts) do
url = # fetch url ...
Keyword.merge(opts, jwks_url: url)
end
end
defmodule JokenExample.Application do
@doc false
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
{MyStrategy, time_interval: 2_000}
]
opts = [strategy: :one_for_one]
Supervisor.start_link(children, opts)
end
end
Then on your token configuration module:
defmodule MyToken do
use Joken.Config
add_hook(JokenJwks, strategy: MyStrategy)
# rest of your token config
end