jose.jwks wraps Nimbus key sources. A source can be remote and cached. It can
also be local and in-memory.
(require '[jose.jwk :as jwk]
'[jose.jwks :as jwks]
'[jose.jws :as jws]
'[jose.jwt :as jwt])
(def source
(jwks/remote-source "https://www.googleapis.com/oauth2/v3/certs"
{:cache-ttl-ms 300000
:cache-refresh-ms 15000
:connect-timeout-ms 5000
:read-timeout-ms 5000
:rate-limit-ms 30000}))
Options:
| Option | Meaning |
|---|---|
:cache-ttl-ms | Cache time to live in milliseconds. |
:cache-refresh-ms | Cache refresh timeout in milliseconds. |
:connect-timeout-ms | HTTP connect timeout in milliseconds. |
:read-timeout-ms | HTTP read timeout in milliseconds. |
:rate-limit-ms | Minimum interval for Nimbus rate limiting. |
All options are optional. Without options, Nimbus uses its defaults. The remote source from Nimbus already caches keys.
Invalid URLs throw ex-info with {:jose/error :invalid-url}. jwks/get-keys
throws {:jose/error :key-source-failure} for a remote retrieval failure.
(def rsa-key
(jwk/generate :rsa {:kid "rsa-1" :use :sig :alg :rs256}))
(def local
(jwks/local-source [(jwk/public-jwk rsa-key)]))
jwks/local-source accepts a vector of JWKs. It also accepts a JWK set value
accepted by jwk/parse-set.
(jwks/get-keys local {:kid "rsa-1"})
(jwks/get-keys local {:kty :rsa :use :sig :alg :rs256})
(jwks/find-key local "rsa-1")
Matcher options for jwks/get-keys:
| Option | Values |
|---|---|
:kid | Key ID string. |
:kty | :rsa, :ec, :okp, or :oct. |
:use | :sig or :enc. |
:alg | Algorithm keyword, string, or Nimbus Algorithm. |
jwks/get-keys returns a vector. jwks/find-key returns the first matching key
for a key ID, or nil.
(def compact-jws
(jws/sign rsa-key "payload" {:alg :rs256 :kid "rsa-1"}))
(jws/verify-with-jwks local compact-jws)
;; => {:payload "payload", :payload-bytes ..., :header ...}
(def compact-jwt
(jwt/sign rsa-key
{:sub "alice" :iss "https://issuer.example"}
{:alg :rs256 :kid "rsa-1" :expires-in 3600}))
(jwt/verify-with-jwks local compact-jwt {:iss "https://issuer.example"})
;; => verified claims map
jws/verify-with-jwks and jwt/verify-with-jwks select a key from the compact
object header kid and alg. They then call the normal verifier.
Key selection errors:
:jose/error | Cause |
|---|---|
:key-not-found | No key matches the header kid and alg. |
:ambiguous-key | The compact object has no kid and more than one key matches alg. |
jose-clj chooses the verifier from the selected JWK key type. It does not trust the algorithm in the compact object. An HS256 forgery over an RSA public key is rejected because the selected RSA JWK is verified with an RSA verifier, not a MAC verifier.
The repository includes a ^:integration test that reads the Google certificate
JWKS:
(jwks/remote-source "https://www.googleapis.com/oauth2/v3/certs")
Kaocha skips it by default through tests.edn:
:skip-meta [:integration]
Use remote-source examples only when the test environment has network access.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |