OPA JSON Data Desgin
Overview
In the last blog post, we discussed adding external data to OPA. We mentioned that there is only one ‘data.json’ file in the OPA bundle.
However, what if you need multiple JSON data files during the development phase? In this blog post, we will demonstrate how to handle multiple JSON data files under the OPA directory structure.
The test is based on the latest OPA version 0.55.0.
Folder Structure and JSON Schema
As illustrated in the example, you can have multiple ‘data.json’ files under different folders. When the ‘data.json’ is located under the root folder, you have to add the entire namespace to the JSON object itself. However, for the ‘data.json’ file under a sub-directory, you will omit the namespace and let the OPA bundle build to add the namespace automatically.
During development and test phases, you will also need to evaluate the policy against a bundle. Otherwise you might encounter conflicting data or inconsistent namespace for the data.
By the way, the ‘roots’ field and ‘.manifest’ are optional, but it’s a good practice to include them in the initial configuration. Doing so provides a solid foundation in case you need to push data to the OPA server at a later stage.
Build a Bundle
Next you run the ‘opa build . -b’ CLI command to generate the ‘bundle.tar.gz’. By inspecting the bundle file, we learned that all JSON data is collapsed into one single ‘data.json’ file under the root directory.
opa build . -b
$ tar -tzvf bundle.tar.gz
tar: Removing leading `/' from member names
-rw------- 0/0 585 1969-12-31 19:00 /data.json
-rw------- 0/0 386 1969-12-31 19:00 /com\\example\\policy.rego
-rw------- 0/0 40 1969-12-31 19:00 /.manifest
Here is the content of the ‘data.json’ file.
{
"com": {
"example": {
"datafolder": {
"users": {
"alice": {
"manager": "charlie",
"title": "salesperson"
},
"bob": {
"manager": "charlie",
"title": "salesperson"
},
"charlie": {
"manager": "dave",
"title": "manager"
},
"dave": {
"manager": null,
"title": "ceo"
},
"fake": {
"manager": "1",
"title": "2"
}
}
},
"finance": {
"users": {
"team1_1": {
"manager": "charlie",
"title": "salesperson"
},
"team1_2": {
"manager": "charlie",
"title": "team1 engineer"
}
}
},
"sales": {
"users": {
"team2_a": {
"manager": "Joe",
"title": "salesperson"
},
"team2_b": {
"manager": "Joe",
"title": "team2 engineer"
}
}
}
}
}
}