Class: Clerk::SDK

Inherits:
ClerkHttpClient::SDK
  • Object
show all
Defined in:
lib/clerk/sdk.rb

Constant Summary collapse

DEFAULT_HEADERS =
{
  "User-Agent": "Clerk/#{Clerk::VERSION}; Faraday/#{Faraday::VERSION}; Ruby/#{RUBY_VERSION}",
  "X-Clerk-SDK": "ruby/#{Clerk::VERSION}",
  "Clerk-API-Version": "2025-04-10",
}
JWKS_CACHE_LIFETIME =

How often (in seconds) should JWKs be refreshed

3600
@@jwks_cache =

1 hour

JWKSCache.new(JWKS_CACHE_LIFETIME)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.jwks_cacheObject



19
20
21
# File 'lib/clerk/sdk.rb', line 19

def self.jwks_cache
  @@jwks_cache
end

Instance Method Details

#decode_token(token) ⇒ Object

Returns the decoded JWT payload without verifying if the signature is valid.

WARNING: This will not verify whether the signature is valid. You should not use this for untrusted messages! You most likely want to use ‘verify_token`.



27
28
29
# File 'lib/clerk/sdk.rb', line 27

def decode_token(token)
  JWT.decode(token, nil, false).first
end

#verify_token(token, force_refresh_jwks: false, algorithms: ["RS256"], timeout: 5) ⇒ Object

Decode the JWT and verify it’s valid (verify claims, signature etc.) using the provided algorithms.

JWKS are cached for JWKS_CACHE_LIFETIME seconds, in order to avoid unecessary roundtrips. In order to invalidate the cache, pass ‘force_refresh_jwks: true`.

A timeout for the request to the JWKs endpoint can be set with the ‘timeout` argument.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/clerk/sdk.rb', line 37

def verify_token(token, force_refresh_jwks: false, algorithms: ["RS256"], timeout: 5)
  jwk_loader = ->(options) do
    # JWT.decode requires that the 'keys' key in the Hash is a symbol (as
    # opposed to a string which our SDK returns by default)
    {keys: SDK.jwks_cache.fetch(self, kid_not_found: options[:invalidate] || options[:kid_not_found], force_refresh: force_refresh_jwks)}
  end

  claims = JWT.decode(token, nil, true, algorithms: algorithms, exp_leeway: timeout, jwks: jwk_loader).first

  # orgs
  if claims["v"].nil? || claims["v"] == 1
    claims["v"] = 1
  elsif claims["v"] == 2 && claims["o"]
    claims["org_id"]          = claims["o"].fetch("id", nil)
    claims["org_slug"]        = claims["o"].fetch("slg", nil)
    claims["org_role"]        = "org:#{claims["o"].fetch("rol", nil)}"

    org_permissions = compute_org_permissions_from_v2_token(claims)
    claims["org_permissions"] = org_permissions if org_permissions.any?
    claims.delete("o")
    claims.delete("fea")
  end

  claims
end