Class: Kilden::IdentitySigner

Inherits:
Object
  • Object
show all
Defined in:
lib/kilden/identity_signer.rb

Overview

Signs the short-lived identity tokens that make browser events verifiable (Kilden's trust model). Deliberately separate from Client: a controller rendering a page wants a token, not an event queue.

signer = Kilden::IdentitySigner.new(ENV["KILDEN_IDENTITY_SECRET"], kid: "k1")
token  = signer.sign(current_user.id.to_s, traits: { plan: "pro" })

Only sign a sub your backend authenticated. Signing user input (params) lets anyone impersonate anyone — with a "verified" stamp on top.

HS256 is implemented by hand because the spec freezes the byte form of the token (kilden-sdk-spec §6.1); a JWT library's serialization choices would silently diverge.

Constant Summary collapse

MAX_TTL =

7 days; identity tokens are short-lived by design

604_800

Instance Method Summary collapse

Constructor Details

#initialize(identity_secret, kid:) ⇒ IdentitySigner

Returns a new instance of IdentitySigner.



23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/kilden/identity_signer.rb', line 23

def initialize(identity_secret, kid:)
  if !identity_secret.is_a?(String) || identity_secret.empty?
    raise ConfigurationError,
          "identity secret is required"
  end
  if !kid.is_a?(String) || kid.empty?
    raise ConfigurationError,
          "kid is required (the platform looks the secret up by kid)"
  end

  @secret = identity_secret
  @kid = kid
end

Instance Method Details

#sign(sub, ttl: 3600, traits: nil) ⇒ Object

Returns the signed JWT for sub (the distinct_id the token vouches for). ttl defaults to one hour and is capped at 7 days.

Raises:

  • (ArgumentError)


39
40
41
42
43
44
45
# File 'lib/kilden/identity_signer.rb', line 39

def sign(sub, ttl: 3600, traits: nil)
  raise ArgumentError, "sub must be a non-empty string" if !sub.is_a?(String) || sub.empty?
  raise ArgumentError, "ttl must be in (0, #{MAX_TTL}] seconds" if !ttl.is_a?(Integer) || ttl <= 0 || ttl > MAX_TTL

  iat = Time.now.to_i
  build(sub, iat: iat, exp: iat + ttl, traits: traits)
end