Class: Zitadel::Client::Auth::WebTokenAuthenticator

Inherits:
OAuthAuthenticator show all
Defined in:
lib/zitadel/client/auth/web_token_authenticator.rb,
sig/lib.rbs

Overview

OAuth authenticator implementing the JWT bearer flow.

This implementation builds a JWT assertion dynamically in get_grant().

Defined Under Namespace

Classes: WebTokenAuthenticatorBuilder

Instance Attribute Summary

Attributes inherited from Authenticator

#host

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from OAuthAuthenticator

#auth_headers, #auth_token, #refresh_token

Methods inherited from Authenticator

#auth_headers

Constructor Details

#initialize(open_id, auth_scopes, jwt_issuer, jwt_subject, jwt_audience, private_key, jwt_lifetime: 3600, jwt_algorithm: 'RS256', key_id: nil, transport_options: nil) ⇒ WebTokenAuthenticator

Constructs a WebTokenAuthenticator.

rubocop:disable Metrics/ParameterLists, Metrics/MethodLength

Parameters:

  • open_id (OpenId)

    The OpenId instance with OAuth endpoint information.

  • auth_scopes (Set<String>)

    The scope(s) for the token request.

  • jwt_issuer (String)

    The JWT issuer.

  • jwt_subject (String)

    The JWT subject.

  • jwt_audience (String)

    The JWT audience.

  • private_key (String)

    The private key used to sign the JWT.

  • jwt_lifetime (Integer) (defaults to: 3600)

    Lifetime of the JWT in seconds (default 3600 seconds).

  • jwt_algorithm (String) (defaults to: 'RS256')

    The JWT signing algorithm (default "RS256").

  • key_id (String, nil) (defaults to: nil)

    Optional key identifier for the JWT header (default: nil).

  • transport_options (TransportOptions, nil) (defaults to: nil)

    Optional transport options for TLS, proxy, and headers.

  • (OpenId)
  • (Set[String])
  • (String)
  • (String)
  • (String)
  • (String, OpenSSL::PKey::PKey)
  • jwt_lifetime: (Integer) (defaults to: 3600)
  • jwt_algorithm: (String) (defaults to: 'RS256')
  • key_id: (String, nil) (defaults to: nil)
  • transport_options: (TransportOptions, nil) (defaults to: nil)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/zitadel/client/auth/web_token_authenticator.rb', line 30

def initialize(open_id, auth_scopes, jwt_issuer, jwt_subject, jwt_audience, private_key,
               jwt_lifetime: 3600, jwt_algorithm: 'RS256', key_id: nil, transport_options: nil)
  transport_options ||= TransportOptions.defaults

  conn_opts = transport_options.to_connection_opts

  # noinspection RubyArgCount,RubyMismatchedArgumentType
  super(open_id, auth_scopes, OAuth2::Client.new('zitadel', 'zitadel', {
                                                   site: open_id.host_endpoint,
                                                   token_url: open_id.token_endpoint,
                                                   connection_opts: conn_opts
                                                 }), transport_options: transport_options)
  @jwt_issuer = jwt_issuer
  @jwt_subject = jwt_subject
  @jwt_audience = jwt_audience
  @jwt_lifetime = jwt_lifetime
  @jwt_algorithm = jwt_algorithm
  @key_id = key_id
  # noinspection RubyMismatchedVariableType
  @private_key = if private_key.is_a?(String)
                   OpenSSL::PKey::RSA.new(private_key)
                 else
                   private_key
                 end
end

Class Method Details

.builder(host, user_id, private_key, transport_options: nil) ⇒ WebTokenAuthenticatorBuilder

Returns a builder for constructing a WebTokenAuthenticator.

Parameters:

  • host (String)

    The base URL for the OAuth provider.

  • user_id (String)

    The user identifier (used as both the issuer and subject).

  • private_key (String)

    The private key used to sign the JWT.

  • transport_options (TransportOptions, nil) (defaults to: nil)

    Optional transport options for TLS, proxy, and headers.

  • (String)
  • (String)
  • (String)
  • transport_options: (TransportOptions, nil) (defaults to: nil)

Returns:



99
100
101
102
# File 'lib/zitadel/client/auth/web_token_authenticator.rb', line 99

def self.builder(host, user_id, private_key, transport_options: nil)
  WebTokenAuthenticatorBuilder.new(host, user_id, user_id, host, private_key,
                                   transport_options: transport_options)
end

.from_json(host, json_path, transport_options: nil) ⇒ WebTokenAuthenticator

Creates a WebTokenAuthenticator instance from a JSON configuration file.

The JSON file must be formatted as follows:

{
"type": "serviceaccount",
"keyId": "<key-id>",
"key": "<private-key>",
"userId": "<user-id>"
}

rubocop:disable Metrics/MethodLength

Parameters:

  • host (String)

    Base URL for the API endpoints.

  • json_path (String)

    File path to the JSON configuration file.

  • transport_options (TransportOptions, nil) (defaults to: nil)

    Optional transport options for TLS, proxy, and headers.

  • (String)
  • (String)
  • transport_options: (TransportOptions, nil) (defaults to: nil)

Returns:

Raises:

  • (RuntimeError)

    If the file cannot be read, the JSON is invalid, or required keys are missing.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/zitadel/client/auth/web_token_authenticator.rb', line 75

def self.from_json(host, json_path, transport_options: nil)
  config = JSON.parse(File.read(json_path))
rescue Errno::ENOENT => e
  raise "Unable to read JSON file at #{json_path}: #{e.message}"
rescue JSON::ParserError => e
  raise "Invalid JSON in file at #{json_path}: #{e.message}"
else
  raise "Expected a JSON object, got #{config.class}" unless config.is_a?(Hash)

  user_id, private_key, key_id = config.values_at('userId', 'key', 'keyId')
  raise "Missing required keys 'userId', 'keyId' or 'key'" unless user_id && key_id && private_key

  WebTokenAuthenticator.builder(host, user_id, private_key, transport_options: transport_options)
                       .key_identifier(key_id).build
end

Instance Method Details

#get_grant(client, auth_scopes) ⇒ OAuth2::AccessToken

Overrides the base get_grant to return client credentials grant parameters.

rubocop:disable Metrics/MethodLength

Parameters:

Returns:



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/zitadel/client/auth/web_token_authenticator.rb', line 110

def get_grant(client, auth_scopes)
  client.assertion.get_token(
    { iss: @jwt_issuer,
      sub: @jwt_subject,
      aud: @jwt_audience,
      iat: Time.now.utc.to_i,
      exp: (Time.now.utc + @jwt_lifetime).to_i },
    {
      algorithm: @jwt_algorithm,
      key: @private_key,
      kid: @key_id
    },
    {
      scope: auth_scopes
    }
  )
end