Class: KairosMcp::Auth::Authenticator

Inherits:
Object
  • Object
show all
Defined in:
lib/kairos_mcp/auth/authenticator.rb

Overview

Authenticator: Verifies HTTP requests using Bearer tokens

Extracts the Bearer token from the Authorization header, verifies it against the TokenStore, and returns user context.

Usage:

auth = Authenticator.new(token_store)
user_context = auth.authenticate(env)
# => { user: "masa", role: "owner", ... } or nil

Instance Method Summary collapse

Constructor Details

#initialize(token_store) ⇒ Authenticator

Returns a new instance of Authenticator.

Parameters:

  • token_store (TokenStore)

    Token store instance



19
20
21
# File 'lib/kairos_mcp/auth/authenticator.rb', line 19

def initialize(token_store)
  @token_store = token_store
end

Instance Method Details

#authenticate(env) ⇒ Hash?

Authenticate a Rack request

Parameters:

  • env (Hash)

    Rack environment hash

Returns:

  • (Hash, nil)

    User context if authenticated, nil otherwise



27
28
29
30
31
32
# File 'lib/kairos_mcp/auth/authenticator.rb', line 27

def authenticate(env)
  raw_token = extract_bearer_token(env)
  return nil unless raw_token

  @token_store.verify(raw_token)
end

#authenticate!(env) ⇒ AuthResult

Authenticate and return a result object with error details

Parameters:

  • env (Hash)

    Rack environment hash

Returns:

  • (AuthResult)

    Result with success/failure details



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/kairos_mcp/auth/authenticator.rb', line 38

def authenticate!(env)
  # Local dev mode: when no tokens are configured, allow unauthenticated
  # access with a default owner context. This makes local testing seamless.
  if @token_store.empty?
    return AuthResult.new(
      success: true,
      user_context: { user: 'local', role: 'owner', local_dev: true }
    )
  end

  raw_token = extract_bearer_token(env)

  unless raw_token
    return AuthResult.new(
      success: false,
      error: 'missing_token',
      message: 'Authorization header with Bearer token is required'
    )
  end

  user_context = @token_store.verify(raw_token)

  if user_context
    AuthResult.new(success: true, user_context: user_context)
  else
    AuthResult.new(
      success: false,
      error: 'invalid_token',
      message: 'Invalid, expired, or revoked token'
    )
  end
end