Skip to content

Authenticating

With the OpenTestFactory orchestrator, you must be authenticated (logged in) before your request can be authorized (granted permission to access). For information about authorization, see Authorization Overview.

Users in OpenTestFactory orchestrator

It is assumed that an orchestrator-independent service manages users in the following ways:

  • an administrator distributing JWT tokens
  • an administrator delegating the creation of JWT tokens to a trusted authority
  • a file with a list of usernames and passwords

In this regard, the orchestrator does not have objects which represent user accounts. Users cannot be added to an orchestrator through an API call.

Even though a user cannot be added via an API call, any user that presents a valid signed JWT token is considered authenticated. From there, the access control sub-system would determine whether the user is authorized to perform a specific operation on a resource.

API requests are tied to a user. This means every process inside or outside the orchestrator, from a human user typing opentf-ctl on a workstation, to plugin services, must authenticate when making requests to the orchestrator.

Authentication strategies

The Orchestrator uses bearer tokens to authenticate API requests through authentication modules. As HTTP requests are made to the orchestrator, modules attempt to associate the following attributes with the request:

  • Username: a string that identifies the end user. Common values might be admin or jane@example.com.
  • UID: a string that identifies the end user and attempts to be more consistent and unique than a username.
  • Groups: a set of strings, each of which indicates the user’s membership in a named logical collection of users. Common values might be system:administrators or devops-team.
  • Extra fields: a map of strings to lists of strings that holds additional information authorizers may find useful.

All values are opaque to the authentication system and only hold significance when interpreted by an authorizer.

You can enable multiple authentication methods at once.

When multiple authenticator modules are enabled, the first module to successfully authenticate the request short-circuits the evaluation. The orchestrator does not guarantee the order authenticators run in.

Info

If no authentication method is specified when using one of the provided Docker images, a temporary JWT token is generated and shown in the logs. A new JWT token will be generated whenever the container restarts.

Signed JWT Tokens

Signed JWT token authentication is enabled by specifying paths in the trusted_authorities section of the service’s configuration file or by providing the --trusted-authorities=SOMEPATHS command-line option. The referenced paths must contain one or more public keys to use to validate client requests presented to the orchestrator.

Info

If you are using one of the provided Docker images, use the OPENTF_TRUSTEDKEYS_PATHS environment variable instead. The setting will apply to every service launched by the image.

Example

JWT tokens signed with a key matching the public key(s) found in /etc/opentf will have access to resources in the default namespace only:

apiVersion: opentestfactory.org/v1beta2
kind: ServiceConfig
current-context: default
contexts:
- context:
    trusted_authorities:
    - /etc/opentf/dept_a/*
    - /etc/opentf/admin_key.pub
    # ...
  name: allinone

This is equivalent to starting the service using:

... --trusted-authorities=/etc/opentf/dept_a/*,/etc/opentf/admin_key.pub

Static Tokens File

The orchestrator reads bearer tokens from a file when given the --token-auth-file option on the command line. Currently, the token list cannot be changed without restarting the orchestrator.

Info

If you are using one of the provided Docker images, use the OPENTF_TOKEN_AUTH_FILE environment variable instead. The setting will apply to every service launched by the image.

Important

This file is only used when using the ABAC authorizer.

Some legacy services require signed JWT tokens and cannot work with arbitrary tokens, so it is strongly recommended to only use tokens that are verified by known trusted authorities. This may change in a future release.

In particular, running a workflow using an arbitrary token (that is, a token defined in the ‘static tokens’ file but not verified by a trusted authority) will likely end in a workflow failure.

The ‘static tokens’ file is a CSV file with a minimum of 3 columns: token, user name, and user uid, followed by optional group names.

Note

If you have more than one group the column must be double-quoted e.g.

token,user,uid,"group1,group2,group3"

Empty lines and lines starting with a # character are ignored as comments.

Example

Alice’s uid is alice, and she is part of no groups. An authorizer must grant permissions to her uid for them to apply to Alice.

Bob’s uid is bob, and is part of two groups, team_a and team_b. An authorizer may grant permissions to Bob based on those groups, in addition to the permissions granted on his uid.

The third line is ignored as it starts with a pound sign.

ey...,Alice Doe,alice
ey...,Bob Doe,bob,"team_a,team_b"
#ey...,Carol Doe,carol,"team_b"

Putting a Bearer Token in a Request

When using bearer token authentication from an HTTP client, the orchestrator expects an Authorization header with a value of Bearer <token>. The bearer token must be a character sequence that can be put in an HTTP header value using no more than the encoding and quoting facilities of HTTP. For example: if the bearer token is 13aadf4d-dace-406c-09a8-e965ec7b2596 then it would appear in an HTTP header as shown below.

Authorization: Bearer 13aadf4d-dace-406c-09a8-e965ec7b2596