Texas is Token Exchange as a Service.
____
! !
! !
! `- _ _ _
| ``` ! _
_____! ! | |
\, \ | |_ _____ ____ _ ___
l _ ; | __/ _ \ \/ / _` / __|
\ _/ \. / | || __/> < (_| \__ \
\ .’ \__\___/_/\_\__,_|___/
. ./’
`. ,
\ ;
``’
Texas implements OAuth 2 token fetch, exchange, and JSON Web Token (JWT) validation, so that you don't have to. It is designed to run as a sidecar container in Kubernetes environments.
Tip
Looking for something that handles OpenID Connect (OIDC) for end-user authentication?
Check out nais/wonderwall.
See the .env.example
file for available configuration options.
To set up a local environment based on this, run:
make setup
Start a mock OAuth 2 server with:
docker-compose up -d
Run Texas:
make local
The hack/
directory contains example snippets with requests that you can run with curl
.
Run all of them with:
make test_roundtrip
Tip
See nais/wonderwalled for an example downstream application that uses Texas.
Texas is currently tailored for use with a subset of authorizations servers and providers, namely:
Support for other providers currently requires changes to the codebase.
Texas abstracts away and handles the boring parts of OAuth 2 and JWTs. It does this by offering a simple API for acquiring, exchanging, and introspecting tokens.
For further details, see the OpenAPI specification (view in Swagger Editor).
Acquires a access token for machine-to-machine use. The grant used depends on the identity provider:
- For Entra ID, the client credentials grant is used.
- For Maskinporten, the JWT authorization grant is used.
Example request:
POST /api/v1/token
Content-Type: application/json
{
"identity_provider": "maskinporten",
"target": "some-scope"
}
Example response:
HTTP 1.1 200 OK
Content-Type: application/json
{
"access_token": "<some-access-token>",
"expires_in": 3599,
"token_type": "Bearer"
}
Exchanges a subject token (typically an access token for an end-user) for a new machine token. The grant used depends on the identity provider:
- For Entra ID, the on-behalf-of flow (which is loosely based on the token exchange grant) is used.
- For TokenX / Tokendings, the token exchange grant is used.
POST /api/v1/token/exchange
Content-Type: application/json
{
"identity_provider": "tokenx",
"user_token": "<some-subject-token>",
"target": "some-other-client"
}
Example response:
HTTP 1.1 200 OK
Content-Type: application/json
{
"access_token": "<some-access-token>",
"expires_in": 3599,
"token_type": "Bearer"
}
Introspects a token in JWT form by performing validation of its standard claims and signature. Loosely based on RFC 7662, section 2.
If valid, the token's claims are returned as JSON.
POST /api/v1/introspect
Content-Type: application/json
{
"identity_provider": "tokenx",
"token": "<some-access-token>"
}
Example response:
HTTP 1.1 200 OK
Content-Type: application/json
{
"active": true,
"aud": "my-target",
"azp": "yolo",
"exp": 1730980893,
"iat": 1730977293,
"iss": "http://localhost:8080/tokenx",
"jti": "e7cbadc3-6bda-49c0-a196-c47328da880e",
"nbf": 1730977293,
"sub": "e015542c-0f81-40f5-bbd9-7c3d9366298f",
"tid": "tokenx"
}
Only the standard claims defined in RFC 7519, section 4.1 are validated. Validation of other claims is the responsibility of the downstream application.
The following claims must always be present and valid:
- The
iss
claim must exist and must match the expected issuer. - The
iat
claim must exist and its value be in the past. - The
exp
claim must exist and its value be in the future.
For most providers, the aud
claim must be present and match the expected audience (often the client ID).
The aud
claim is not validated for tokens from Maskinporten, as they do not contain the aud
claim by default.
The nbf
claim, if set, must be in the past.
Texas handles client authentication with the identity provider for you. Your application doesn't need to know about or handle any credentials.
Texas uses JWTs for client authentication with the respective authorization servers, as defined in RFC 7523, section 2.2.
This is also known as the private_key_jwt
client authentication method.
Using client secrets is not supported.
make check
If you've modified the API specifications, you should regenerate the OpenAPI spec:
make openapi
Commit and push the changes.