NOTE Authentication is currently implemented and active in all versions >= 0.6.x. The OIDC IDP must expose an End-Session-Endpoint, otherwise the logout will not work. Tapir integrates well with Keycloak.
Tapir management needs the IDP client to put the role admin
into the token.
Tapir supports authentication via OIDC and Deploy-Keys. While OIDC secures the app and Tapir management, Deploy-Keys are used for the REST-API in a CI/CD context.
NOTE: To use Tapir UI you need to be authenticated. However, you can read the registry without authentication. In particular the Terraform CLI will work without authentication, since Tapir does not yet support the Login API.
The OIDC mechanism is used for the UI and Tapir management, while Deploy-Keys are used for the REST-API to publish modules and providers only.
Tapir requires setting up and utilizing a backend to enable functionalities like search, metadata, data persistence, and more. It’s important to distinguish between the backend and storage configurations as they serve different roles. Supported backends include:
elasticsearch
dynamodb
cosmosdb
Available storage backends are:
s3
azureBlob
local
/tapir
to persist your data. This is highly recommended. Otherwise, you loose the data if the container gets removed.Configuring secrets for Tapir is largely at the users discretion. It is recommended to use a secret manager like AWS Secrets Manager or Azure Key Vault to store sensitive data like keys, passwords, connection strings, etc. Tapir needs the secret values set as environment variables, and depending on the actual runtime there are different approaches.
For example, if you’re using Kubernetes, you can use Opaque Kubernetes Secrets to store and manage sensitive information manually. Each secret store solution like AWS Secrets Manager, Azure Key Vault, Hashicorp Vault, etc. has its own way of injecting said secrets into Kubernetes as well. Or furthermore, you could use a Kubernetes external secrets operator. It’s important to follow the best practices and guidelines provided by the respective service.
You can configure Tapir passing the following environment variables:
Variable | Description | Required | Default | |
---|---|---|---|---|
BACKEND_CONFIG | The database to make use of. Allowed values: elasticsearch, dynamodb, cosmosdb | X | dynamodb | |
BACKEND_ELASTICSEARCH_HOST | Host of the Elasticsearch instance | Yes, if BACKEND_CONFIG is elasticsearch | ||
BACKEND_ELASTICSEARCH_USER | Username to authenticate on Elasticsearch | |||
BACKEND_ELASTICSEARCH_PASSWORD | Password to authenticate on Elasticsearch | |||
BACKEND_AZURE_MASTER_KEY | Master key of your CosmosDb | Yes, if BACKEND_CONFIG is cosmosdb | ||
BACKEND_AZURE_ENDPOINT | Endpoint of your CosmosDb | Yes, if BACKEND_CONFIG is cosmosdb | ||
STORAGE_CONFIG | The blob storage to make use of. Allowed values: s3, azureBlob, local | X | s3 | |
STORAGE_ACCESS_SESSION_DURATION | Amount of minutes the signed download url is valid | X | 5 | |
AZURE_BLOB_CONNECTION_STRING | Connection string to use for authentication | Yes, if STORAGE_CONFIG is azureBlob | ||
AZURE_BLOB_CONTAINER_NAME | Blob container name to be used to store module archives | Yes, if STORAGE_CONFIG is azureBlob | tf-registry | |
S3_STORAGE_BUCKET_NAME | S3 bucket name to be used to store module archives | Yes, if STORAGE_CONFIG is s3 | tf-registry | |
S3_STORAGE_BUCKET_REGION | AWS region of the target S3 bucket | Yes, if STORAGE_CONFIG is s3 | eu-central-1 | |
REGISTRY_HOSTNAME | The hostname of the registry, must be set to the DNS record of Tapir | Yes, if STORAGE_CONFIG is local | localhost | |
REGISTRY_PORT | The port of the registry | Yes, if STORAGE_CONFIG is local | 443 | |
API_MAX_BODY_SIZE | The maximum payload size for module/providers to be uploaded | X | 100M | |
REGISTRY_GPG_KEYS_0__ID | GPG key ID of the key to be used (eg. D17C807B4156558133A1FB843C7461473EB779BD) | X | ||
REGISTRY_GPG_KEYS_0__ASCII_ARMOR | Ascii armored and bas64 encoded GPG public key (only RSA/DSA supported) | X | ||
AUTH_ENDPOINT | The base URL of the OpenID Connect (OIDC) server, for example, https://host:port/auth. OIDC discovery endpoint will be called by default by appending a ‘.well-known/openid-configuration’ path to this URL. Note if you work with Keycloak OIDC server, make sure the base URL is in the following format: https://host:port/realms/{realm} where {realm} has to be replaced by the name of the Keycloak realm. | |||
AUTH_CLIENT_ID | The client id | |||
AUTH_CLIENT_SECRET | Client secret if the client requires one | |||
AUTH_TOKEN_PATH | Relative path or absolute URL of the OIDC token endpoint which issues access and refresh tokens. This property must be set for the application if OIDC discovery is not available. | X | ||
AUTH_PATH | Relative path or absolute URL of the OIDC authorization endpoint which authenticates the users. This property must be set for the application if OIDC discovery is not available. | Yes, if the Identity provider does not expose a discovery path | ||
AUTH_ROLE_SOURCE | The source of the role claim in the access token. The default value is ‘accesstoken’ which means the role claim is expected to be in the access token. If the role claim is in the ID token, set this property to ‘idtoken’. If the role claim is in the userinfo endpoint, set this property to ‘userinfo’. | X | accesstoken | |
AUTH_TOKEN_ATTRIBUTE_EMAIL | The attribute name in the token where the email is placed in | X | ||
AUTH_TOKEN_ATTRIBUTE_GIVEN_NAME | The attribute name in the token where the given name is placed in | X | given_name | |
AUTH_TOKEN_ATTRIBUTE_FAMILY_NAME | The attribute name in the token where the family name is placed in | X | family_name | |
AUTH_TOKEN_ATTRIBUTE_PREFERRED_USERNAME | The attribute name in the token where the preferred username is placed in | X | preferred_username | |
END_SESSION_PATH | IDP end session path, will be used to logout | X | /protocol/openid-connect/logout | |
CORS_ORIGINS | Configure CORS origins | X | * |
:information_source: A note on the GPG configuration. Quarkus (and therefore Tapir) is based on Smallrye microprofile and supports indexed properties. Hence, you can add one or more key specifying indexed properties. See example below for passing two GPG keys (Mind the two subsequent underscores after the index):
REGISTRY_GPG_KEYS_0__ID=D17C807B4156558133A1FB843C7461473EB779BD
REGISTRY_GPG_KEYS_0__ASCII_ARMOR=LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgp.....tUUlO
REGISTRY_GPG_KEYS_1__ID=LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSDLPFKF
REGISTRY_GPG_KEYS_1__ASCII_ARMOR=LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgp.....JDIFH