Discovery
OPA can be configured to download bundles of policy and data, report status, and upload decision logs to remote endpoints. The discovery feature helps you centrally manage the OPA configuration for these features. You should use the discovery feature if you want to avoid managing OPA configuration updates in number of different locations.
When the discovery feature is enabled, OPA will periodically download a discovery bundle. Like regular bundles, the discovery bundle may contain JSON and Rego files. OPA will evaluate the data and policies contained in the discovery bundle to generate the rest of the configuration. There are two main ways to structure the discovery bundle:
- Include static JSON configuration files that define the OPA configuration.
- Include Rego files that can be evaluated to produce the OPA configuration.
If you need OPA to select which policy to download dynamically (e.g., based on environment variables like the region where OPA is running), use the second option.
If discovery is enabled, other features like bundle downloading and status reporting cannot be configured manually. Similarly, discovered configuration cannot override the original discovery settings in the configuration file that OPA was booted with.
See the Configuration Reference for configuration details.
Discovery Service API
OPA expects the service to expose an API endpoint that serves bundles.
GET /<service_url>/<discovery.prefix>/<discovery.name> HTTP/1.1
If the bundle exists, the server should respond with an HTTP 200 OK status followed by a gzipped tarball in the message body.
HTTP/1.1 200 OK
Content-Type: application/gzip
You can enable discovery with an OPA configuration file similar to the example below. In some places in the documentation, the initial configuration provided to OPA is referred to as the “boot configuration”.
services:
- name: acmecorp
url: https://example.com/control-plane-api/v1
credentials:
bearer:
token: "bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm"
discovery:
name: /example/discovery
prefix: configuration
Using the boot configuration above, OPA will fetch discovery bundles from:
https://example.com/control-plane-api/v1/configuration/example/discovery
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
services[0].url | |
+ discovery.prefix |
+ discovery.name
The
discovery.prefix
field defaults tobundles
. The default is convenient if you want to serve discovery bundles and normal bundles from the same API endpoint.
OPA generates it’s subsequent configuration by querying the Rego and JSON files contained inside the discovery bundle. The query is defined by the discovery.name
field from the boot configuration: data.<discovery.name>
. For example. with the boot configuration above, OPA executes the following query:
data.example.discovery
If the discovery bundle contained the following Rego file:
package example
discovery = {
"bundle": {"name": bundle_name},
"default_decision": "acmecorp/httpauthz/allow"
}
bundle_name = "acmecorp/httpauthz"
The subsequent configuration would be:
{
"bundle": {
"name": "acmecorp/httpauthz"
},
"default_decision": "acmecorp/httpauthz/allow"
}
The discovery bundle contents above are essentially static. The same result could be achieved by constructing the discovery bundle with a static JSON file:
{
"example": {
"discovery": {
"bundle": {
"name": "acmecorp/httpauthz"
},
"default_decision": "acmecorp/httpauthz/allow"
}
}
}
For an example of how to configure OPA dynamically see the Example section below.
The subsequent configuration does not have to specify services
or include a reference to a service in the bundle
, status,
or decision_log
sections. If the either the services
or references to services are missing, OPA will default them to the value from the boot configuration.
Example
Let’s see an example of how the discovery feature can be used to dynamically configure an OPA to download one of two bundles based on a label in the boot configuration. Let’s say the label region
indicates the region in which the OPA is running and it’s value will decide the bundle to download.
Below is a policy file which generates an OPA congfiguration.
example.rego
package example
discovery = {
"bundle": {
"name": bundle_name # line 5
}
}
rt = opa.runtime()
region = rt.config.labels.region
bundle_name = region_bundle[region]
# region-bundle information
region_bundle = {
"US": "example/test1/p",
"UK": "example/test2/p"
}
The bundle_name
variable in line 5
of the above policy will be dynamically selected based on the value of the label region
. So if an OPA was started with region: "US"
, then the bundle_name
will be example/test1/p
.
Start an OPA with a boot configuration as shown below:
config.yaml
services:
- name: acmecorp
url: https://example.com/control-plane-api/v1
credentials:
bearer:
token: "bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm"
discovery:
name: /example/discovery
labels:
region: "US"
Run OPA:
opa run -s -c config.yaml
You should see a log like below, which shows the bundle being downloaded. In this case, the bundle name is example/test1/p
as region
is US
.
INFO Bundle downloaded and activated successfully. name=example/test1/p plugin=bundle
Now start another OPA with a boot configuration as shown below. Notice the region
is UK
:
config.yaml
services:
- name: acmecorp
url: https://example.com/control-plane-api/v1
credentials:
bearer:
token: "bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm"
discovery:
name: /example/discovery
labels:
region: "UK"
Run OPA:
opa run -s -c config.yaml
In this case, the bundle being downloaded is example/test2/p
as region
is UK
.
INFO Bundle downloaded and activated successfully. name=example/test2/p plugin=bundle
This shows how the discovery feature can help in centrally managing the bundle to be downloaded by an OPA based on a configuration label. You can use the same strategy to dynamically configure other plugins based on the running OPA’s configuration labels or environment variables.
Limitations
The discovery feature cannot be used to dynamically modify services
, labels
and discovery
. This means that these configuration settings should be included in the bootup configuration file provided to OPA.