Class: Nonnative::Token

Inherits:
Object
  • Object
show all
Defined in:
lib/nonnative/token.rb

Overview

Builds signed tokens (JWT, PASETO, or SSH) for authenticating against services under test.

The consumer passes in the signing parameters they parsed from their own configuration; this class is not coupled to any particular service's configuration format. The generated token string is ready to pass to Header.auth_bearer.

Examples:

JWT

token = Nonnative::Token.new(kind: 'jwt', issuer: 'iss', key: 'key-1',
                             private_key: 'config/ed25519.pem', expiration: 3600)
header = Nonnative::Header.auth_bearer(token.generate(aud: 'GET /v1/things', sub: 'user-1'))

PASETO

token = Nonnative::Token.new(kind: 'paseto', issuer: 'iss', key: 'key-1',
                             private_key: 'config/ed25519.pem', expiration: 3600)
token.generate(aud: Nonnative::Token.grpc_audience('/health.v1.Health/Check'), sub: 'user-1')

See Also:

Constant Summary collapse

KINDS =

Supported token kinds mapped to their implementation.

{ 'jwt' => Nonnative::JwtToken, 'paseto' => Nonnative::PasetoToken, 'ssh' => Nonnative::SshToken }.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(kind:, issuer:, key:, private_key:, expiration:) ⇒ Token

Returns a new instance of Token.

Parameters:

  • kind (String)

    token kind, one of "jwt", "paseto", or "ssh"

  • issuer (String)

    the iss claim (unused by the ssh kind)

  • key (String)

    the key id (JWT kid header, PASETO kid footer, or SSH kid claim)

  • private_key (String)

    path to the Ed25519 private key file (PKCS#8 PEM for jwt/paseto, OpenSSH format for ssh)

  • expiration (Integer)

    token lifetime in seconds (drives exp)

Raises:

  • (ArgumentError)

    if the kind is not supported



50
51
52
53
# File 'lib/nonnative/token.rb', line 50

def initialize(kind:, issuer:, key:, private_key:, expiration:)
  klass = KINDS.fetch(kind) { raise ArgumentError, "Unsupported token kind '#{kind}'" }
  @token = klass.new(issuer: issuer, key: key, private_key: private_key, expiration: expiration)
end

Class Method Details

.grpc_audience(full_method) ⇒ String

Builds the audience string for a gRPC endpoint.

Parameters:

  • full_method (String)

    the gRPC full method (for example "/health.v1.Health/Check")

Returns:

  • (String)

    the audience string



39
40
41
# File 'lib/nonnative/token.rb', line 39

def grpc_audience(full_method)
  full_method
end

.http_audience(method, path) ⇒ String

Builds the audience string for an HTTP endpoint.

Parameters:

  • method (String)

    HTTP method (for example "GET")

  • path (String)

    request path (for example "/v1/things")

Returns:

  • (String)

    the audience string (for example "GET /v1/things")



31
32
33
# File 'lib/nonnative/token.rb', line 31

def http_audience(method, path)
  "#{method} #{path}"
end

Instance Method Details

#generate(aud:, sub:) ⇒ String

Generates a signed token.

Parameters:

  • aud (String)

    the aud claim

  • sub (String)

    the sub claim

Returns:

  • (String)

    the signed token



60
61
62
# File 'lib/nonnative/token.rb', line 60

def generate(aud:, sub:)
  @token.generate(aud: aud, sub: sub)
end