OPAL Scopes
OPAL Scopes allows OPAL to serve different policies and data sources, serving them to multiple clients. Every scope contains its own policy and data sources. All clients using the same Scope ID will get the same policy and data.
Scopes are an easy way to use OPAL with multiple Git repositories (or other sources of policy), and are a core feature to enable using OPAL itself as a multi-tenant service.
Scopes are dynamic, and can be created on the fly through the scopes
API (/scopes)
Setting up scopes
Prerequisites
Scopes are supported in OPAL 0.2.0 and above. Use the provided docker compose example to quickly get started.
The server must be started with the environment variable
OPAL_SCOPES=1.The scope clones are kept under
OPAL_BASE_DIR, which two running servers must not share: at each start, the pre-fork scope preload removes the lock files and partial packs in every clone there, whichever server's git op left them.
Use a REST API call to create or change a scope
In this scenario, we create two different scopes (internal and external), that, for example, can be used for an internal and external facing app. The internal scope uses policies located in the internal directory, and external uses policies defined in the external directory. We can set different directories, different branches, different repositories, and any other setting.
The authorization used in this example are GitHub Personal Access Tokens that can be generated here.
curl --request PUT 'http://opal_server/scopes'
--header 'Content-Type: application/json'
--header 'Authorization: $OPAL_TOKEN'
--data-raw '{
"scope_id": "internal",
"policy": {
"source_type": "git",
"url": "https://github.com/company/policy",
"auth": {
"auth_type": "github_token",
"token": "github_token"
},
"directories": [
"internal"
],
"extensions": [
".rego",
".json"
],
"manifest": ".manifest",
"poll_updates": true,
"branch": "main"
},
"data": {
"entries": []
}
}'
curl --request PUT 'http://opal_server/scopes'
--header 'Content-Type: application/json'
--header 'Authorization: $OPAL_TOKEN'
--data-raw '{
"scope_id": "external",
"policy": {
"source_type": "git",
"url": "https://github.com/company/policy",
"auth": {
"auth_type": "github_token",
"token": "github_token"
},
"directories": [
"external"
],
"extensions": [
".rego",
".json"
],
"manifest": ".manifest",
"poll_updates": true,
"branch": "main"
},
"data": {
"entries": []
}
}'
PUT /scopes refuses, with 422, a branch name git can't fetch (such as x~1
or an empty name), since such a scope can't follow a branch. A scope stored
with such a name before this release keeps being served as it was until it is
changed. A scope whose branch is not on the remote gets no policy
(GET /scopes/<scope_id>/policy answers 409), and the server logs
Did not find target branch on remote: <branch> (<url>) at ERROR; a sync pass
logs it once for each branch of each clone.
Launch OPAL Client with a scope
docker run -it \
--env OPAL_CLIENT_TOKEN \
--env OPAL_SERVER_URL \
--env OPAL_DATA_TOPICS \
--env OPAL_SCOPE_ID=internal \
-p 7766:7000 \
-p 8181:8181 \
permitio/opal-client