Configuration Edit

This page defines the format of OPA configuration files. Fields marked as required must be specified if the parent is defined. For example, when the configuration contains a status key, the status.service field must be defined.

OPA accepts any name for the configuration file. Some tooling may however benefit from knowing what name to associate with OPA’s configuration file (for auto-completion of attributes, linting, etc.). The following names could be considered idiomatic for that purpose:

  • opa-config.yaml (or .json)
  • opa-conf.yaml (or .json)

The configuration file path is specified with the -c or --config-file command line argument:

opa run -s -c opa-config.yaml

The file can be either JSON or YAML format. The following is an example configuration file sets fields in many of the subcomponents inside of OPA.

services:
  acmecorp:
    url: https://example.com/control-plane-api/v1
    response_header_timeout_seconds: 5
    credentials:
      bearer:
        token: "bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm"

labels:
  app: myapp
  region: west
  environment: production

bundles:
  authz:
    service: acmecorp
    resource: bundles/http/example/authz.tar.gz
    persist: true
    polling:
      min_delay_seconds: 60
      max_delay_seconds: 120
    signing:
      keyid: global_key
      scope: write

decision_logs:
  service: acmecorp
  reporting:
    min_delay_seconds: 300
    max_delay_seconds: 600

status:
  service: acmecorp

default_decision: /http/example/authz/allow

persistence_directory: /var/opa

keys:
  global_key:
    algorithm: RS256
    key: <PEM_encoded_public_key>
    scope: read

caching:
  inter_query_builtin_cache:
    max_size_bytes: 10000000
    forced_eviction_threshold_percentage: 70
    stale_entry_eviction_period_seconds: 3600

distributed_tracing:
  type: grpc
  address: localhost:4317
  service_name: opa
  sample_percentage: 50
  encryption: "off"
  resource:
    service_namespace: "my-namespace"
    service_version: "1.1"
    service_instance_id: "1"

server:
  decoding:
    max_length: 134217728
    gzip:
      max_length: 268435456
  encoding:
    gzip:
        min_length: 1024
        compression_level: 9

Services

Services represent endpoints that implement one or more control plane APIs such as the Bundle or Status APIs. OPA configuration files may contain multiple services.

FieldTypeRequiredDescription
services[_].namestringYesUnique name for the service. Referred to by plugins.
services[_].urlstringYesBase URL to contact the service with.
services[_].response_header_timeout_secondsint64No (default: 10)Amount of time to wait for a server’s response headers after fully writing the request. This time does not include the time to read the response body.
services[_].headersobjectNoHTTP headers to include in requests to the service.
services[_].tls.ca_certstringNoThe path to the root CA certificate. If not provided, this defaults to TLS using the host’s root CA set.
services[_].tls.system_ca_requiredboolNo (default: false)Require system certificate appended with root CA certificate.
services[_].allow_insecure_tlsboolNoAllow insecure TLS.
services[_].typestringNo (default: empty)Optional parameter that allows to use an “OCI” service type. This will allow bundle and discovery plugins to download bundles from an OCI registry.

Services can be defined as an array or object. When defined as an object, the object keys override the services[_].name fields. For example:

services:
  s1:
    url: https://s1/example/
  s2:
    url: https://s2/

Is equivalent to

services:
  - name: s1
    url: https://s1/example/
  - name: s2
    url: https://s2/

Each service may optionally specify a credential mechanism by which OPA will authenticate itself to the service.

Bearer Token

OPA will authenticate using the specified bearer token and schema; to enable bearer token authentication, either the token or the path to the token must be specified. If the latter is provided, on each request OPA will re-read the token from the file and use that token for authentication.

The scheme attribute is optional, and will default to Bearer if unspecified.

FieldTypeRequiredDescription
services[_].credentials.bearer.tokenstringYesEnables token-based authentication and supplies the bearer token to authenticate with.
services[_].credentials.bearer.token_pathstringYesEnables token-based authentication and supplies the path to the bearer token to authenticate with.
services[_].credentials.bearer.schemestringNoBearer token scheme to specify.

Client TLS Certificate

OPA will present the specified TLS certificate to authenticate. The paths to the client certificate and the private key are required; the passphrase for the private key is only required if the private key is encrypted.

FieldTypeRequiredDescription
services[_].credentials.client_tls.certstringYesThe path to the client certificate to authenticate with.
services[_].credentials.client_tls.private_keystringYesThe path to the private key of the client certificate.
services[_].credentials.client_tls.private_key_passphrasestringNoThe passphrase to use for the private key.

OAuth2 Client Credentials

OPA will authenticate using a bearer token obtained through the OAuth2 client credentials flow. Following successful authentication at the token endpoint the returned token will be cached for subsequent requests for the duration of its lifetime. Note that as per the OAuth2 standard, only the HTTPS scheme is supported for the token endpoint URL.

FieldTypeRequiredDescription
services[_].credentials.oauth2.token_urlstringYesURL pointing to the token endpoint at the OAuth2 authorization server.
services[_].credentials.oauth2.client_idstringYesThe client ID to use for authentication.
services[_].credentials.oauth2.client_secretstringYesThe client secret to use for authentication.
services[_].credentials.oauth2.scopes[]stringNoOptional list of scopes to request for the token.
services[_].credentials.oauth2.additional_headersmapNoMap of additional headers to send to token endpoint at the OAuth2 authorization server
services[_].credentials.oauth2.additional_parametersmapNoMap of additional body parameters to send token endpoint at the OAuth2 authorization server

OAuth2 Client Credentials JWT authentication

OPA will authenticate using a bearer token obtained through the OAuth2 client credentials flow. Rather than providing a client secret along with the request for an access token, the client asserts its identity in the form of a signed JWT. Following successful authentication at the token endpoint the returned token will be cached for subsequent requests for the duration of its lifetime. Note that as per the OAuth2 standard, only the HTTPS scheme is supported for the token endpoint URL.

FieldTypeRequiredDescription
services[_].credentials.oauth2.token_urlstringYesURL pointing to the token endpoint at the OAuth2 authorization server.
services[_].credentials.oauth2.grant_typestringNoDefaults to client_credentials.
services[_].credentials.oauth2.client_idstringNoThe client ID to use for authentication.
services[_].credentials.oauth2.signing_keystringNoReference to private key used for signing the JWT. Required if aws_kms is not provided
services[_].credentials.oauth2.thumbprintstringNoCertificate thumbprint to use for x5t header generation.
services[_].credentials.oauth2.additional_claimsmapNoMap of claims to include in the JWT (see notes below)
services[_].credentials.oauth2.include_jti_claimboolNoInclude a uniquely generated jti claim in any issued JWT
services[_].credentials.oauth2.scopes[]stringNoOptional list of scopes to request for the token.
services[_].credentials.oauth2.aws_kms.namestringNoTo specify a KMS key, use its key ID, key ARN, alias name, or alias ARN. Required only for signing with AWS KMS.
services[_].credentials.oauth2.aws_kms.algorithmstringNoSpecifies the signing algorithm used by the key aws_kms.name (ECDSA_SHA_256, ECDSA_SHA_384 or ECDSA_SHA_512). Required only for signing with AWS KMS.
services[_].credentials.oauth2.aws_signing{}NoAWS credentials for signing requests. Required if aws_kms is provided.
services[_].credentials.oauth2.client_assertion_pathstringNoTo specify a path to find a client assertion file. Used for Azure Workload Identity.
services[_].credentials.oauth2.client_assertionstringNoTo specify a client assertion. Used for Azure Workload Identity.

Two claims will always be included in the issued JWT: iat and exp. Any other claims will be populated from the additional_claims map.

For using services[_].credentials.oauth2.aws_kms, a method for setting the AWS credentials has to be specified in the services[_].credentials.oauth2.aws_signing. The value of services[_].credentials.oauth2.aws_signing.service should be kms. Several methods of obtaining the necessary credentials are available; exactly one must be specified, see description for services[_].credentials.s3_signing.

The following is an example of using the client credentials grant type with JWT client authentication replacing client secret as the credential used at the token endpoint.

services:
  remote:
    url: ${BUNDLE_SERVICE_URL}
    credentials:
      oauth2:
        token_url: ${TOKEN_URL}
        grant_type: client_credentials
        client_id: opa-client
        signing_key: jwt_signing_key # references the key in `keys` below
        include_jti_claim: true
        scopes:
        - read
        - write
        additional_claims:
          sub: opa-client
          iss: opa-${POD_NAME}

bundles:
  authz:
    service: remote
    resource: bundles/http/example/authz.tar.gz

keys:
  jwt_signing_key:
    algorithm: ES512
    private_key: ${BUNDLE_SERVICE_SIGNING_KEY}

The following is an example of using the client credentials grant type with JWT client authentication & AWS KMS signing of client assertions.

services:
  remote:
    url: ${BUNDLE_SERVICE_URL}
    credentials:
      oauth2:
        token_url: ${TOKEN_URL}
        grant_type: client_credentials
        client_id: opa-client
        aws_kms:
          name: ${AWS_KMS_KEYID}
          algorithm: ECDSA_SHA_256
        aws_signing: # similar to s3_signing
          service: kms
          environment_credentials:
            aws_default_region: eu-west-1
        include_jti_claim: true
        scopes:
        - read
        - write
        additional_claims:
          sub: opa-client
          iss: opa-${POD_NAME}

bundles:
  authz:
    service: remote
    resource: bundles/http/example/authz.tar.gz

The following is an example of using the client credentials grant type with JWT client authentication via Azure Workload Identity access to the storage account hosting the policies. All referenced environment variables are automatically populated by Azure when deployed via AKS. Note the similarity to managed identity.

services:
  azure_storage_account:
    url: https://YOUR_STORAGE_ACCOUNT.blob.core.windows.net/
    headers:
      x-ms-version: 2017-11-09
    response_header_timeout_seconds: 5
    credentials:
      oauth2:
        grant_type: client_credentials
        client_id: "${AZURE_CLIENT_ID}"
        client_assertion_path: "${AZURE_FEDERATED_TOKEN_FILE}"
        token_url: "${AZURE_AUTHORITY_HOST}/${AZURE_TENANT_ID}/oauth2/v2.0/token"
        scopes:
          - https://storage.azure.com/.default

bundles:
  authz:
    service: azure_storage_account
    resource: YOUR_CONTAINER/YOUR_POLICY_BUNDLE.tar.gz
    persist: true
    polling:
      min_delay_seconds: 60
      max_delay_seconds: 120

OAuth2 JWT Bearer Grant Type

OPA will authenticate using a bearer token obtained through the OAuth2 JWT authorization grant flow. Rather than providing a client secret along with the request for an access token, the client asserts its identity in the form of a signed JWT. Following successful authentication at the token endpoint the returned token will be cached for subsequent requests for the duration of its lifetime. Note that as per the OAuth2 standard, only the HTTPS scheme is supported for the token endpoint URL.

FieldTypeRequiredDescription
services[_].credentials.oauth2.token_urlstringYesURL pointing to the token endpoint at the OAuth2 authorization server.
services[_].credentials.oauth2.grant_typestringNoMust be set to jwt_bearer for JWT bearer grant type. Defaults to client_credentials.
services[_].credentials.oauth2.signing_keystringYesReference to private key used for signing the JWT.
services[_].credentials.oauth2.additional_claimsmapNoMap of claims to include in the JWT (see notes below)
services[_].credentials.oauth2.include_jti_claimboolNoInclude a uniquely generated jti claim in any issued JWT
services[_].credentials.oauth2.scopes[]stringNoOptional list of scopes to request for the token.

Two claims will always be included in the issued JWT: iat and exp. Any other claims will be populated from the additional_claims map.

The following is an example of using a Google Cloud Storage bucket as a bundle service backend from outside the cloud account (for access from inside the account, see the GCP Metadata Token section).

services:
  gcp:
    url: https://storage.googleapis.com/storage/v1/b/${BUCKET_NAME}/o
    credentials:
      oauth2:
        token_url: https://oauth2.googleapis.com/token
        grant_type: jwt_bearer
        signing_key: jwt_signing_key # references the key in `keys` below
        scopes:
        - https://www.googleapis.com/auth/devstorage.read_only
        additional_claims:
          aud: https://oauth2.googleapis.com/token
          iss: opa-client@my-account.iam.gserviceaccount.com

bundles:
  authz:
    service: gcp
    resource: 'bundles%2fhttp%2fexample%2fauthz.tar.gz?alt=media'

keys:
  jwt_signing_key:
    algorithm: RS256
    private_key: ${BUNDLE_SERVICE_SIGNING_KEY}
OPA masks services authentication secrets which make use of the credentials field, in order to prevent the exposure of sensitive tokens. It is important to note that the /v1/config API allows clients to read the runtime configuration of OPA. As such, any credentials used by custom configurations not utilizing the credentials field will be exposed to the caller. Consider requiring authentication in order to prevent unauthorized read access to OPA’s runtime configuration.

AWS Signature

OPA will authenticate with an AWS Version 4 or version 4A signature. While version 4 is the default, version 4A must be used when making requests that might be handled by more than one region, such as an S3 Multi-Region Access Point. You must use version 4A for this or requests will fail when routed to a different region than the one indicated in a version 4 signature. Furthermore, using version 4a also requires that temporary credentials are retrieved from a regional AWS STS endpoint, rather than the global STS endpoint.

Several methods of obtaining the necessary credentials are available; exactly one must be specified to use the AWS signature authentication method.

The AWS service for which to sign the request can be specified in the service field. If omitted, the default is s3.

The AWS signature version to sign the request with can be specified in the signature_version field. If omitted, the default is 4. The only other valid value is 4a.

FieldTypeRequiredDescription
services[_].credentials.s3_signing.servicestringNoThe AWS service to sign requests with, eg execute-api or s3. Default: s3
services[_].credentials.s3_signing.signature_versionstringNoThe AWS signature version to sign requests with, eg 4 or 4a. Default: 4

Using Static Environment Credentials

If specifying environment_credentials, OPA will expect to find environment variables for AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION, in accordance with the convention used by the AWS CLI.

Please note that if you are using temporary IAM credentials (e.g. assumed IAM role credentials) you have to provide additional AWS_SESSION_TOKEN or AWS_SECURITY_TOKEN environment variable.

FieldTypeRequiredDescription
services[_].credentials.s3_signing.environment_credentials{}YesEnables AWS signing using environment variables to source the configuration and credentials

Using Named Profile Credentials

If specifying profile_credentials, OPA will expect to find the access key id, secret access key and session token from the named profiles stored in the credentials file on disk. On each request OPA will re-read the credentials from the file and use them for authentication.

FieldTypeRequiredDescription
services[_].credentials.s3_signing.profile_credentials.pathstringNoThe path to the shared credentials file. If empty, OPA will look for the AWS_SHARED_CREDENTIALS_FILE env variable. If the variable is not set, the path defaults to the current user’s home directory. ~/.aws/credentials (Linux & Mac) or %USERPROFILE%\.aws\credentials (Windows)
services[_].credentials.s3_signing.profile_credentials.profilestringNoAWS Profile to extract credentials from the credentials file. If empty, OPA will look for the AWS_PROFILE env variable. If the variable is not set, the default profile will be used
services[_].credentials.s3_signing.profile_credentials.aws_regionstringNoThe AWS region to use for the AWS signing service credential method. If unset, the AWS_REGION environment variable must be set

Using EC2 Metadata Credentials

If specifying metadata_credentials, OPA will use the AWS metadata services for EC2 or ECS to obtain the necessary credentials when running within a supported virtual machine/container.

To use the EC2 metadata service, the IAM role to use and the AWS region for the resource must both be specified as iam_role and aws_region respectively.

To use the ECS metadata service, specify only the AWS region for the resource as aws_region. ECS containers have at most one associated IAM role. As per the AWS documentation, credentials are sourced from the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI metadata environment variable or the AWS_CONTAINER_CREDENTIALS_FULL_URI metadata environment variable in order.

Providing a value for iam_role will cause OPA to use the EC2 metadata service even if running inside an ECS container. This may result in unexpected problems if, for example, there is no route to the EC2 metadata service from inside the container or if the IAM role is only available within the container and not from the hosting EC2 instance.

FieldTypeRequiredDescription
services[_].credentials.s3_signing.metadata_credentials.aws_regionstringNoThe AWS region to use for the AWS signing service credential method. If unset, the AWS_REGION environment variable must be set
services[_].credentials.s3_signing.metadata_credentials.iam_rolestringNoThe IAM role to use for the AWS signing service credential method

Using AWS Security Token Service (AWS STS) via AssumeRole

If specifying assume_role_credentials, OPA will use AWS STS to obtain temporary security credentials for accessing AWS resources. In order to retrieve temporary security credentials from STS via AssumeRole valid AWS security credentials are required.

For using services[_].credentials.s3_signing.assume_role_credentials, a method for setting the AWS credentials has to be specified in the services[_].credentials.s3_signing.assume_role_credentials.aws_signing. The value of services[_].credentials.s3_signing.assume_role_credentials.aws_signing.service is set to sts. Several methods of obtaining the necessary credentials are available; exactly one must be specified, see description for services[_].credentials.s3_signing. Currently supported methods are services[_].credentials.s3_signing.environment_credentials, services[_].credentials.s3_signing.profile_credentials and services[_].credentials.s3_signing.metadata_credentials. OPA will follow this internally defined order of precedence when multiple credential providers are specified.
FieldTypeRequiredDescription
services[_].credentials.s3_signing.assume_role_credentials.aws_regionstringYesThe AWS region to use for the sts regional endpoint. Uses the global endpoint by default
services[_].credentials.s3_signing.assume_role_credentials.iam_role_arnstringYesThe IAM Role ARN to be assumed. Can also be set via the AWS_ROLE_ARN environment variable (config takes precedence)
services[_].credentials.s3_signing.assume_role_credentials.aws_signing{}YesAWS credentials for signing requests.
services[_].credentials.s3_signing.assume_role_credentials.session_namestringNoThe session name used to identify the assumed role session. Default: open-policy-agent
services[_].credentials.s3_signing.assume_role_credentials.aws_domainstringNoThe AWS domain name to use. Default: amazonaws.com. Can also be set via the AWS_DOMAIN environment variable (config takes precedence)

The following is an example using Assume Role Credentials type with EC2 Metadata Credentials signing plugin:

services:
  remote:
    url: ${BUNDLE_SERVICE_URL}
    credentials:
      assume_role_credentials:
        aws_region: us-east-1
        iam_role_arn: arn:aws::iam::123456789012:role/demo
        session_name: demo
        aws_signing: # similar to s3_signing
          metadata_credentials:
            aws_region: us-east-1
            iam_role: s3access

bundles:
  authz:
    service: remote
    resource: bundles/http/example/authz.tar.gz

Using EKS IAM Roles for Service Account (Web Identity) Credentials

If specifying web_identity_credentials, OPA will expect to find environment variables for AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE, in accordance with the convention used by the AWS EKS IAM Roles for Service Accounts.

FieldTypeRequiredDescription
services[_].credentials.s3_signing.web_identity_credentials.aws_regionstringYesThe AWS region to use for the sts regional endpoint. Uses the global endpoint by default
services[_].credentials.s3_signing.web_identity_credentials.session_namestringNoThe session name used to identify the assumed role session. Default: open-policy-agent
services[_].credentials.s3_signing.web_identity_credentials.aws_domainstringNoThe AWS domain name to use. Default: amazonaws.com. Can also be set via the AWS_DOMAIN environment variable (config takes precedence)

GCP Metadata Token

OPA will authenticate with a GCP access token or identity token fetched from the Compute Metadata Server. When one or more scopes is provided an access token is fetched. When a non-empty audience is provided an identity token is fetched. An audience or scopes array is required.

When authenticating to native GCP services such as Google Cloud Storage an access token should be used with the appropriate set of scopes required by the target resource. When authenticating to a third party application such as an application hosted on Google Cloud Run an identity token should be used.

FieldTypeRequiredDescription
services[_].credentials.gcp_metadata.audiencestringNoThe audience to use when fetching identity tokens.
services[_].credentials.gcp_metadata.endpointstringNoThe metadata endpoint to use.
services[_].credentials.gcp_metadata.scopesarrayNoThe set of scopes to use when fetching access token.
services[_].credentials.gcp_metadata.access_token_pathstringNoThe access token metadata path to use.
services[_].credentials.gcp_metadata.id_token_pathstringNoThe identity token metadata path to use.

The following is an example using a Cloud Run service as a bundle service backend.

services:
  cloudrun:
    url: ${BUNDLE_SERVICE_URL}
    response_header_timeout_seconds: 5
    credentials:
      gcp_metadata:
        audience: ${BUNDLE_SERVICE_URL}

bundles:
  authz:
    service: cloudrun
    resource: bundles/http/example/authz.tar.gz
    persist: true
    polling:
      min_delay_seconds: 60
      max_delay_seconds: 120

Using Google Cloud Storage as a bundle service backend.

services:
  gcs:
    url: https://storage.googleapis.com/storage/v1/b/${BUCKET_NAME}/o
    response_header_timeout_seconds: 5
    credentials:
      gcp_metadata:
        scopes:
          - "https://www.googleapis.com/auth/devstorage.read_only"

bundles:
  authz:
    service: gcs
    resource: 'bundles%2fhttp%2fexample%2fbundle.tar.gz?alt=media'
    persist: true
    polling:
      min_delay_seconds: 60
      max_delay_seconds: 120

When the given resource (the object in the GCS bucket) contains slashes (/) or other special characters, these need to be url-encoded here.

Azure Managed Identities Token

OPA will authenticate with an Azure managed identities token. The token request can be configured via the plugin to customize the base URL, API version, and resource. Specific managed identity IDs can be optionally provided as well. (The token request for Azure App Service or Azure Container Apps is similar to above interface, but the endpoint and the header are different. Please see the individual documents for more details.)

FieldTypeRequiredDescription
services[_].credentials.azure_managed_identity.endpointstringNoRequest endpoint. (Detect endpoint from IDENTITY_ENDPOINT environment variable when you use managed identity on Azure App Service or Container Apps. Otherwise set default: http://169.254.169.254/metadata/identity/oauth2/token, the Azure Instance Metadata Service endpoint (recommended))
services[_].credentials.azure_managed_identity.api_versionstringNoAPI version to use. (default: 2019-08-01 when you use IDENTITY_ENDPONT endpoint, otherwise 2018-02-01, the minimum version)
services[_].credentials.azure_managed_identity.resourcestringNoApp ID URI of the target resource. (default: https://storage.azure.com/)
services[_].credentials.azure_managed_identity.object_idstringNoOptional object ID of the managed identity you would like the token for. Required, if your VM has multiple user-assigned managed identities.
services[_].credentials.azure_managed_identity.client_idstringNoOptional client ID of the managed identity you would like the token for. Required, if your VM has multiple user-assigned managed identities.
services[_].credentials.azure_managed_identity.mi_res_idstringNoOptional Azure Resource ID of the managed identity you would like the token for. Required, if your VM has multiple user-assigned managed identities.

The following is an example of how to use an Azure storage account as a bundle service backend.

Note that the x-ms-version header must be specified for the storage account service, and a minimum version of 2017-11-09 must be provided as per Azure documentation.

services:
  azure_storage_account:
    url: ${STORAGE_ACCOUNT_URL}
    headers:
      x-ms-version: 2017-11-09
    response_header_timeout_seconds: 5
    credentials:
      azure_managed_identity: {}

bundles:
  authz:
    service: azure_storage_account
    resource: bundles/http/example/authz.tar.gz
    persist: true
    polling:
      min_delay_seconds: 60
      max_delay_seconds: 120

OCI Repositories

When using a private image from an OCI registry you need to specify an authentication method. Supported authentication methods are listed in the Services section. The Azure managed identity plugin is not supported at this point in time.

Examples of setting credentials for pulling private images: AWS ECR private images usually require at least basic authentication. The credentials to authenticate can be obtained using the AWS CLI command aws ecr get-login and those can be passed to the service configuration as basic bearer credentials as follows:

credentials:
  bearer:
    scheme: "Basic"
    token: "<username>:<password>"

Other AWS authentication methods also work:

credentials:
  s3_signing:
    service: "ecr"
    metadata_credentials:
      aws_region: us-east-1

Note, that the authentication method s3_signing does work for signing requests to other AWS services.

A special case is that bearer authentication works differently to normal service authentication. The OCI downloader base64-encodes the credentials for you so that they need to be supplied in plain text.

For GHCR (Github Container Registry) you can use a developer PAT (personal access token) when downloading a private image. These can be supplied as:

credentials:
  bearer:
    scheme: "Bearer"
    token: "<PAT>"

The following is a complete exmaple using an OCI service type to download a bundle from an OCI repository.

services:
  ghcr-registry:
    url: https://ghcr.io
    type: oci

bundles:
  authz:
    service: ghcr-registry
    resource: ghcr.io/${ORGANIZATION}/${REPOSITORY}:${TAG}
    persist: true
    polling:
      min_delay_seconds: 60
      max_delay_seconds: 120

persistence_directory: ${PERSISTENCE_PATH}

When using an OCI service type the downloader uses the persistence path to store the layers of the downloaded repository. This storage path should be maintained by the user. If persistence is not configured the OCI downloader will store the layers in the system’s temporary directory to allow automatic cleanup on system restart.

Custom Plugin

If none of the existing credential options work for a service, OPA can authenticate using a custom plugin, enabling support for any authentication scheme.

FieldTypeRequiredDescription
services[_].credentials.pluginstringNoThe name of the plugin to use for authentication

The following is an example of using a custom plugin for service credentials:

services:
  my_service:
    url: https://example.com/v1
    credentials:
      plugin: my_custom_auth
plugins:
  my_custom_auth:
    foo: bar

package plugins

import (
	"github.com/open-policy-agent/opa/plugins"
	"github.com/open-policy-agent/opa/plugins/rest"
	"github.com/open-policy-agent/opa/runtime"
	"github.com/open-policy-agent/opa/util"
)

type Config struct {
	Foo string `json:"foo"`
}

type PluginFactory struct{}

type Plugin struct {
	manager  *plugins.Manager
	config   Config
	stop     chan chan struct{}
	reconfig chan interface{}
}

func (p *PluginFactory) Validate(manager *plugins.Manager, config []byte) (interface{}, error) {
	var parsedConfig Config
	if err := util.Unmarshal(config, &parsedConfig); err != nil {
		return nil, err
	}
	return &parsedConfig, nil
}

func (p *PluginFactory) New(manager *plugins.Manager, config interface{}) plugins.Plugin {
	return &Plugin{
		config:   *config.(*Config),
		manager:  manager,
		stop:     make(chan chan struct{}),
		reconfig: make(chan interface{}),
	}
}

func (p *Plugin) Start(ctx context.Context) error {
	p.manager.UpdatePluginStatus(Name, &plugins.Status{State: plugins.StateOK})
	return nil
}

func (p *Plugin) Stop(ctx context.Context) {
	done := make(chan struct{})
	p.stop <- done
	<-done
	p.manager.UpdatePluginStatus(Name, &plugins.Status{State: plugins.StateNotReady})
	return
}

func (p *Plugin) Reconfigure(ctx context.Context, config interface{}) {
	p.reconfig <- config
	return
}

func (p *Plugin) NewClient(c rest.Config) (*http.Client, error) {
	t, err := rest.DefaultTLSConfig(c)
	if err != nil {
		return nil, err
	}
	return rest.DefaultRoundTripperClient(t, *c.ResponseHeaderTimeoutSeconds), nil
}

func (p *Plugin) Prepare(req *http.Request) error {
	req.Header.Add("X-Custom-Auth-Protocol", "knock knock")
	return nil
}

func init() {
	runtime.RegisterPlugin("my_custom_auth", &PluginFactory{})
}

Bundles

Bundles are defined with a key that is the name of the bundle. This name is used in the status API, decision logs, server provenance, etc.

Each bundle can be configured to verify a bundle signature using the keyid and scope fields. The keyid is the name of one of the keys listed under the keys entry.

Signature verification fails if the bundles[_].signing field is configured on a bundle but no .signatures.json file is included in the actual bundle gzipped tarball.

FieldTypeRequiredDescription
bundles[_].resourcestringNo (default: bundles/<name>)Resource path to use to download bundle from configured service.
bundles[_].servicestringYesName of service to use to contact remote server.
bundles[_].polling.min_delay_secondsint64No (default: 60)Minimum amount of time to wait between bundle downloads.
bundles[_].polling.max_delay_secondsint64No (default: 120)Maximum amount of time to wait between bundle downloads.
bundles[_].triggerstring (default: periodic)NoControls how bundle is downloaded from the remote server. Allowed values are periodic and manual (manual triggers are only possible when using OPA as a Go package).
bundles[_].polling.long_polling_timeout_secondsint64NoMaximum amount of time the server should wait before issuing a timeout if there’s no update available.
bundles[_].persistboolNoPersist activated bundles to disk.
bundles[_].signing.keyidstringNoName of the key to use for bundle signature verification.
bundles[_].signing.scopestringNoScope to use for bundle signature verification.
bundles[_].signing.exclude_filesarrayNoFiles in the bundle to exclude during verification.
bundles[_].size_limit_bytesint64No (default: 1073741824)Size limit for individual files contained in the bundle.

Status

FieldTypeRequiredDescription
status.servicestringYesName of service to use to contact remote server.
status.partition_namestringNoPath segment to include in status updates.
status.consolebooleanNo (default: false)Log the status updates locally to the console. When enabled alongside a remote status update API the service must be configured, the default service selection will be disabled.
status.prometheusbooleanNo (default: false)Export the status (bundle and plugin) metrics to prometheus (see the monitoring documentation). When enabled alongside a remote status update API the service must be configured, the default service selection will be disabled.
status.prometheus_config.collectors.bundle_loading_duration_ns.buckets[]float64No, (Only use when status.prometheus true, default: [1000, 2000, 4000, 8000, 16_000, 32_000, 64_000, 128_000, 256_000, 512_000, 1_024_000, 2_048_000, 4_096_000, 8_192_000, 16_384_000, 32_768_000, 65_536_000, 131_072_000, 262_144_000, 524_288_000])Specifies the buckets for the bundle_loading_duration_ns metric. Each value is a float, it is expressed in nanoseconds.
status.pluginstringNoUse the named plugin for status updates. If this field exists, the other configuration fields are not required.
status.triggerstring (default: periodic)NoControls how status updates are reported to the remote server. Allowed values are periodic and manual (manual triggers are only possible when using OPA as a Go package).

Decision Logs

FieldTypeRequiredDescription
decision_logs.servicestringNoName of the service to use to contact remote server. If no plugin is specified, and console logging is disabled, this will default to the first service name defined in the Services configuration.
decision_logs.partition_namestringNoDeprecated: Use resource instead. Path segment to include in status updates.
decision_logs.resourcestringNo (default: /logs)Full path to use for sending decision logs to a remote server.
decision_logs.reporting.buffer_size_limit_bytesint64NoDecision log buffer size limit in bytes. OPA will drop old events from the log if this limit is exceeded. By default, no limit is set. Only one of buffer_size_limit_bytes, max_decisions_per_second may be set.
decision_logs.reporting.max_decisions_per_secondfloat64NoMaximum number of decision log events to buffer per second. OPA will drop events if the rate limit is exceeded. Only one of buffer_size_limit_bytes, max_decisions_per_second may be set.
decision_logs.reporting.upload_size_limit_bytesint64No (default: 32768)Decision log upload size limit in bytes. OPA will chunk uploads to cap message body to this limit.
decision_logs.reporting.min_delay_secondsint64No (default: 300)Minimum amount of time to wait between uploads.
decision_logs.reporting.max_delay_secondsint64No (default: 600)Maximum amount of time to wait between uploads.
decision_logs.reporting.triggerstringNo (default: periodic)Controls how decision logs are reported to the remote server. Allowed values are periodic and manual (manual triggers are only possible when using OPA as a Go package).
decision_logs.mask_decisionstringNo (default: /system/log/mask)Set path of masking decision.
decision_logs.drop_decisionstringNo (default: /system/log/drop)Set path of drop decision.
decision_logs.pluginstringNoUse the named plugin for decision logging. If this field exists, the other configuration fields are not required.
decision_logs.consolebooleanNo (default: false)Log the decisions locally to the console. When enabled alongside a remote decision logging API the service must be configured, the default service selection will be disabled.
decision_logs.request_context.http.headersarrayNoList of HTTP headers to include in the decision log. OPA will include the values for these headers in the decision log if they exist in the incoming HTTP request.

Discovery

FieldTypeRequiredDescription
discovery.resourcestringYesResource path to use to download bundle from configured service.
discovery.servicestringNoName of the service to use to contact remote server. If omitted, the configuration must contain exactly one service. Discovery will default to this service.
discovery.decisionstringNoThe path of the decision to evaluate in the discovery bundle. By default, OPA will evaluate data in the discovery bundle to produce the configuration.
discovery.polling.min_delay_secondsint64No (default: 60)Minimum amount of time to wait between configuration downloads.
discovery.polling.max_delay_secondsint64No (default: 120)Maximum amount of time to wait between configuration downloads.
discovery.triggerstring (default: periodic)NoControls how bundle is downloaded from the remote server. Allowed values are periodic and manual (manual triggers are only possible when using OPA as a Go package).
discovery.polling.long_polling_timeout_secondsint64NoMaximum amount of time the server should wait before issuing a timeout if there’s no update available.
discovery.signing.keyidstringNoName of the key to use for bundle signature verification.
discovery.signing.scopestringNoScope to use for bundle signature verification.
discovery.signing.exclude_filesarrayNoFiles in the bundle to exclude during verification.
discovery.persistboolNoPersist activated discovery bundle to disk.

⚠️ The plugin trigger mode configured on the discovery plugin will be inherited by the bundle, decision log and status plugins. For example, if the discovery plugin is configured to use the manual trigger mode, all other plugins will use manual triggering as well. If any of the plugins explicitly specify a different mode (for ex. periodic), OPA will generate a configuration error.

The following discovery configuration fields are supported but deprecated:

FieldTypeRequiredDescription
discovery.prefixstringNo (default: bundles)Deprecated: Use resource instead. Path prefix to use to download configuration from remote server.
discovery.namestringNoDeprecated: Use resource instead. Name of the discovery configuration to download. If discovery.name is specified and discovery.resource is unset, the discovery.decision field will default to the discovery.name value.

Keys

Keys is a dictionary mapping the key name to the actual key and optionally the algorithm and scope.

FieldTypeRequiredDescription
keys[_].keystringYes (unless private_key provided)PEM encoded public key to use for signature verification.
keys[_].private_keystringYes (unless key provided`)PEM encoded private key to use for signing.
keys[_].algorithmstringNo (default: RS256)Name of the signing algorithm.
keys[_].scopestringNoScope to use for bundle signature verification.

Note: If the scope is provided in a bundle’s signing configuration (ie. bundles[_].signing.scope), it takes precedence over keys[_].scope.

The following signing algorithms are supported:

NameDescription
ES256ECDSA using P-256 and SHA-256
ES384ECDSA using P-384 and SHA-384
ES512ECDSA using P-521 and SHA-512
HS256HMAC using SHA-256
HS384HMAC using SHA-384
HS512HMAC using SHA-512
PS256RSASSA-PSS using SHA256 and MGF1-SHA256
PS384RSASSA-PSS using SHA384 and MGF1-SHA384
PS512RSASSA-PSS using SHA512 and MGF1-SHA512
RS256RSASSA-PKCS-v1.5 using SHA-256
RS384RSASSA-PKCS-v1.5 using SHA-384
RS512RSASSA-PKCS-v1.5 using SHA-512

Caching

Caching represents the configuration of the inter-query cache that built-in functions can utilize. Of the built-in functions provided by OPA, http.send is currently the only one to utilize the inter-query cache. See the documentation on the http.send built-in function for information about the available caching options.

It also represents the configuration of the inter-query value cache that built-in functions can utilize. Currently, this cache is utilized by the regex and glob built-in functions for compiled regex and glob match patterns respectively, and the json.schema_match built-in function for compiled JSON schemas.

FieldTypeRequiredDescription
caching.inter_query_builtin_cache.max_size_bytesint64NoInter-query cache size limit in bytes. OPA will drop old items from the cache if this limit is exceeded. By default, no limit is set.
caching.inter_query_builtin_cache.forced_eviction_threshold_percentageint64NoThreshold limit configured as percentage of caching.inter_query_builtin_cache.max_size_bytes, when exceeded OPA will start dropping old items permaturely. By default, set to 100.
caching.inter_query_builtin_cache.stale_entry_eviction_period_secondsint64NoStale entry eviction period in seconds. OPA will drop expired items from the cache every stale_entry_eviction_period_seconds. By default, set to 0 indicating stale entry eviction is disabled.
caching.inter_query_builtin_value_cache.max_num_entriesintNoMaximum number of entries in the Inter-query value cache. OPA will drop random items from the cache if this limit is exceeded. By default, set to 0 indicating unlimited size.

Distributed tracing

Distributed tracing represents the configuration of the OpenTelemetry Tracing.

FieldTypeRequiredDescription
distributed_tracing.typestringNoSetting this to “grpc” enables distributed tracing with an collector gRPC endpoint
distributed_tracing.addressstringNo (default: localhost:4317)Address of the OpenTelemetry Collector gRPC endpoint.
distributed_tracing.service_namestringNo (default: opa)Logical name of the service.
distributed_tracing.sample_percentageintNo (default: 100)Percentage of traces that are sampled and exported.
distributed_tracing.encryptionstringNo (default: off)Configures TLS.
distributed_tracing.allow_insecure_tlsboolNo (default: false)Allow insecure TLS.
distributed_tracing.tls_ca_cert_filestringNoThe path to the root CA certificate.
distributed_tracing.tls_cert_filestringNo (unless encryption equals mtls)The path to the client certificate to authenticate with.
distributed_tracing.tls_private_key_filestringNo (unless tls_cert_file provided)The path to the private key of the client certificate.
distributed_tracing.resource.service_versionstringNoService version
distributed_tracing.resource.service_instance_idstringNoService instance id
distributed_tracing.resource.service_namespacestringNoService namespace

The following encryption methods are supported:

NameDescription
offDisable TLS
tlsEnable TLS
mtlsEnable mutual TLS

Disk Storage

The storage configuration key allows for enabling, and configuring, the persistent on-disk storage of an OPA instance.

If disk is set to something, the server will enable the on-disk store with data put into the configured directory.

FieldTypeRequiredDescription
storage.disk.directorystringYesThis is the directory to use for storing the persistent database.
storage.disk.auto_createboolNo (default: false)If set to true, the configured directory will be created if it does not exist.
storage.disk.partitionsarray[string]NoNon-overlapping data prefixes used for partitioning the data on disk.
storage.disk.badgerstringNo (default: empty)“Superflags” passed to Badger allowing to modify advanced options.

See the docs on disk storage for details about the settings.

Server

The server configuration sets:

  • for all incoming requests:
    • maximum allowed request size
    • maximum decompressed gzip payload size
  • the gzip compression settings for responses from the /v0/data, /v1/data and /v1/compile HTTP POST endpoints The gzip compression settings are used when the client sends Accept-Encoding: gzip
  • buckets for http_request_duration_seconds histogram
FieldTypeRequiredDescription
server.decoding.max_lengthintNo, (default: 268435456)Specifies the maximum allowed number of bytes to read from a request body.
server.decoding.gzip.max_lengthintNo, (default: 536870912)Specifies the maximum allowed number of bytes to read from the gzip decompressor for gzip-encoded requests.
server.encoding.gzip.min_lengthintNo, (default: 1024)Specifies the minimum length of the response to compress.
server.encoding.gzip.compression_levelintNo, (default: 9)Specifies the compression level. Accepted values: a value of either 0 (no compression), 1 (best speed, lowest compression) or 9 (slowest, best compression). See https://pkg.go.dev/compress/flate#pkg-constants
server.metrics.prom.http_request_duration_seconds.buckets[]float64No, (default: [1e-6, 5e-6, 1e-5, 5e-5, 1e-4, 5e-4, 1e-3, 0.01, 0.1, 1 ])Specifies the buckets for the http_request_duration_seconds metric. Each value is a float, it is expressed in seconds and subdivisions of it. E.g 1e-6 is 1 microsecond, 1e-3 1 millisecond, 0.01 10 milliseconds

Miscellaneous

FieldTypeRequiredDescription
labelsobjectYesSet of key-value pairs that uniquely identify the OPA instance. Labels are included when OPA uploads decision logs and status information.
default_decisionstringNo (default: /system/main)Set path of default policy decision used to serve queries against OPA’s base URL.
default_authorization_decisionstringNo (default: /system/authz/allow)Set path of default authorization decision for OPA’s API.
persistence_directorystringNo (default $PWD/.opa)Set directory to use for persistence with options like bundles[_].persist.
pluginsobjectNo (default: {})Location for custom plugin configuration. See Plugins for details.
nd_builtin_cachebooleanNo (default: false)Enable the non-deterministic builtins caching system during policy evaluation, and include the contents of the cache in decision logs. Note that decision logs that are larger than upload_size_limit_bytes will drop the nd_builtin_cache key from the log entry before uploading.

Using Environment Variables in Configuration

Only supported with the OPA runtime (opa run).

Environment variables referenced with the ${...} notation within the configuration will be replaced with the value of the environment variable.

Example using BASE_URL and BEARER_TOKEN environment variables:

services:
  acmecorp:
    url: "${BASE_URL}"
    credentials:
      bearer:
        token: "${BEARER_TOKEN}"

discovery:
  resource: /configuration/example/discovery
  decision: example

The environment variables BASE_URL and BEARER_TOKEN will be substituted in when the config file is loaded by the OPA runtime.

If the variable is undefined then an empty string ("") is substituted. It will not raise an error.

Setting Configuration via CLI Arguments

Only supported with the OPA runtime (opa run).

Using opa run there are CLI options to explicitly set config values. These will override any values set in the config file.

There are two options to use: --set and --set-file

Both options take in a key=value format where the key is a selector for the yaml config structure, for example: decision_logs.reporting.min_delay_seconds=300 is equivalent to JSON {"decision_logs": {"reporting": {"min_delay_seconds": 300}}}. Multiple values can be specified with comma separators (key1=value,key2=value2,..). Or with additional --set parameters.

Example using several different options:

opa run \
  --set "default_decision=/http/example/authz/allow" \
  --set "services.acmecorp.url=https://test-env/control-plane-api/v1" \
  --set "services.acmecorp.credentials.bearer.token=\${TOKEN}"
  --set "labels.app=myapp,labels.region=west"

This is equivalent to a YAML config file that looks like:

services:
  acmecorp:
    url: https://test-env/control-plane-api/v1
    credentials:
      bearer:
        token: ${TOKEN}

labels:
  app: myapp
  region: west

default_decision: /http/example/authz/allow

The --set-file option is expecting a file path for the value. This allows keeping secrets in files and loading them into the config at run time. For Example:

With a file /var/run/secrets/bearer_token.txt that has contents:

bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm

Then using the --set-file flag for OPA

opa run --set-file "services.acmecorp.credentials.bearer.token=/var/run/secrets/bearer_token.txt"

It will read the contents of the file and set the config value with the token.

Override Limitations with Lists

If using arrays/lists in the configuration the --set and --set-file overrides will not be able to patch sub-objects of the list. They will overwrite the entire index with the new object.

For example, a opa-config.yaml file with contents:

services:
  - name: acmecorp
    url: https://test-env/control-plane-api/v1
    credentials:
      bearer:
        token: ""

Used with overrides:

opa run \
  --config-file opa-config.yaml
  --set-file "services[0].credentials.bearer.token=/var/run/secrets/bearer_token.txt"

Will result in configuration like:

services:
  - credentials:
      bearer:
        token: bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm

Because the entire 0 index was overwritten.

It is highly recommended to use objects/maps instead of lists for configuration for this reason.

Remote Bundles Override Shorthand

When running the server to quickly try a remote public bundle — such as those published from the Rego Playground, you may find it convenient to provide the URL of the bundle directly, rather than via repeated --set flags:

opa run -s https://example.com/bundles/bundle.tar.gz

The above shorthand command is identical to:

opa run -s --set "services.cli1.url=https://example.com" \
           --set "bundles.cli1.service=cli1" \
           --set "bundles.cli1.resource=/bundles/bundle.tar.gz" \
           --set "bundles.cli1.persist=true"

Empty Objects

If you need to set an empty object with the CLI overrides, for example with plugin configuration like:

decision_logs:
  plugin: my_plugin

plugins:
  my_plugin:
    # empty

You can do this by setting the value with null. For example:

opa run --set "decision_logs.plugin=my_plugin" --set "plugins.my_plugin=null"

Keys with Special Characters

If you have a key which contains a special character (=, [, ,, .), like opa.example.com, and want to use the --set or --set-file options you will need to escape the character with a backslash (\).

For example a config section like:

services:
  opa.example.com:
    url: https://opa.example.com

Could be specified with something like:

--set services.opa\.example\.com.url=https://opa.example.com

Note that when using it in a shell you may need to put it in quotes or escape the \ character too. For example:

--set services."opa\.example\.com".url=https://opa.example.com

or

--set services.opa\\.example\\.com.url=https://opa.example.com

Where the end result passed into OPA still has the \. preserved.