SoarAuthenticationToken

Gem Version

This gem provides authentication token generation and validation capability for the SOAR architecture.

Installation

Add this line to your application's Gemfile:

gem 'soar_authentication_token'

And then execute:

bundle

Or install it yourself as:

gem install soar_authentication_token

Configuration of generators and validators

There are three provider groups for operation: JwtToken, RemoteToken or StaticToken

JwtTokenGenerator/JwtTokenValidator

With the JwtTokenValidator provider the tokens are decoded, verified and meta extracted locally using configured key material. In practice the the token generation and validation services run in this mode since their roles are to generate and validate tokens.

RemoteTokenGenerator/RemoteTokenValidator

With the RemoteTokenValidator provider the tokens are passed to a token validation service for validation. This allows for a centralized management of tokens. The key material are therefore managed on the validation service and . In this mode you only have to provide the url of the validation service.

StaticTokenValidator

In this mode the StaticTokenValidator is configured with a list of preconfigured static tokens. Incoming tokens are simply checked against this list. No extraction of meta is performed on the tokens but retrieved from the configuration. Rotation of tokens is simple since many tokens can be configured. This mode is to be used in only two scenarios:

  • Between the various authentication token services that requires authentication between themselves. These services themselves do not the benefit of another centralized authentication service to rely on.
  • In test scenarios where you do not want to pull in the authentication services to perform testing of your services.

Testing

Run the rspec test tests using docker compose:

export UID
docker-compose build --force-rm --no-cache
docker-compose down
docker-compose run --rm soar-authentication-token
docker-compose down

Updating

For test purposes this repo relies on various other repos with services. This is to test the interaction between the generator and validation clients and these services. In order to pull the latest from the referenced projects and build fresh docker images, simply the following commands:

export UID
git pull && git submodule foreach 'git fetch origin --tags; git checkout master; git pull'
docker-compose down
docker-compose build --force-rm --no-cache

Usage

KeypairGenerator

In support of generating JWT tokens this class is responsible for generating an EC keypairs in PEM format. Use this when rotating keypairs in production or for testing the generators/validators.

generator = SoarAuthenticationToken::KeypairGenerator.new
private_key, public_key = generator.generate

RackMiddleware

The rack middleware allows you to perform validation of all requests before it even hits your resource. The middleware also populates the 'user' key in the rack session with the authenticated identifier and the 'auth_token_meta' key with meta regarding the authentication that might be useful to more sensitive services.

First step is to configure the middleware. Actually you are not configuring the middleware but the TokenValidator instance that will be used in the validation. Most of the time you will be reaching out to a remote validation service and configure it as such:

@iut_configuration = {
  'provider' => 'SoarAuthenticationToken::RemoteTokenValidator',
  'validator-url' => 'http://authentication-token-validator-service:9393/validate'
}
@iut = SoarAuthenticationToken::RackMiddleware.new(@test_app, @iut_configuration)

The middleware will look for the authentication token in the HTTP header 'AUTHORIZATION'.

Please refer to the rack middleware spec for detailed examples on how to use the middleware.

TokenGenerator

The class generates tokens or requests a token from a generator service as configured.

For remote token generation, configure as such:

@configuration_remote = {
  'provider' => 'SoarAuthenticationToken::RemoteTokenGenerator',
  'generator-url' => 'http://authentication-token-generator-service:9393/generate',
  'generator-client-auth-token' => 'xxxx'
}

For local token generation, configure as such:

generator = SoarAuthenticationToken::KeypairGenerator.new
private_key, public_key = generator.generate
@configuration_local = {
  'provider' => 'SoarAuthenticationToken::JwtTokenGenerator',
  'private_key' => private_key
}

Create storage client. The example here uses a local stub client that uses a in-memory store.

gem 'auth_token_store_provider', "~> 1.0.1"
require 'auth_token_store_provider'
store = AuthTokenStoreProvider::StubClient.new

After configuration you simply generate a token like this:

generator = SoarAuthenticationToken::TokenGenerator.new(configuration)
generator.inject_store_provider(store)
token, token_generator_meta = generator.generate(authenticated_identifier: '[email protected]', flow_identifier: 'test-flow-id')

TokenValidator

The class validates tokens or requests validation of a token from a validation service as configured.

For remote token validation, configure as such:

@configuration_remote = {
  'provider' => 'SoarAuthenticationToken::RemoteTokenGenerator',
  'validator-url' => 'http://authentication-token-validator-service:9393/validate',
}

For local token validation, configure as such:

generator = SoarAuthenticationToken::KeypairGenerator.new
private_key, public_key = generator.generate
@configuration_local = {
  'provider' => 'SoarAuthenticationToken::JwtTokenValidator',
  'public_key' => public_key
}

Create storage client. The example here uses a local stub client that uses a in-memory store.

gem 'auth_token_store_provider', "~> 1.0.1"
require 'auth_token_store_provider'
store = AuthTokenStoreProvider::StubClient.new

After configuration you simply valiate a token like this:

validator = SoarAuthenticationToken::TokenValidator.new(configuration)
validator.inject_store_provider(store)
token_validity, token_validator_meta, messages = validator.validate(authentication_token: token, flow_identifier: 'test-flow-id')

Contributing

Bug reports and feature requests are welcome by email to barney dot de dot villiers at hetzner dot co dot za. This gem is sponsored by Hetzner (Pty) Ltd (http://hetzner.co.za)

Notes

License

The gem is available as open source under the terms of the MIT License.