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