This repository contains the rego
and json data to
model all some of the examples in the abc branch security presentation (warning: video).
This repo does not demonstrate the use of opa
as an agent or sidecar process. It does not
demonstrate any data syncing or API usage.
You'll need to install opa v0.43.0 from here.
org_chart_data
for a company. The org chart is a DAG.
Leaf nodes are calledbranches
(as in, "Scranton Branch"). Alevel
is the depth of a node as measured from the leaf nodes. A branch is level 1, by definition.role_data
, which contains a tree,role -> securable_object -> level -> security_level
. Asecurable_object
in these examples are screens in an application. They could also be actual entities from an application's data model. Asecurity_level
is one of 4 values, "full", "read_only", "limited", and null/none (we might call these "permissions" in other contexts).- A
user
who hasallowed_branches
, which are the branches the user is allowed to visit.default_branch
, the user's regular branch.current_branch
, which is another branch they may be working "in".
We define the effective_level
as the level
of the first intersection between two paths:
- The path from the user's
default_branch
to the root node. - The path from the user's
current_branch
to the root node.
Example: If a user's default branch is 001
and their current branch is 006
, then the two paths back to the root node
intersect at "lumber company", so the effective level is 3.
We don't have an explicit deny
as a value (at least, within the innards of the system - we could add a top-level default).
This is because as we search the user's roles, we are looking for explicit permissions and accumulating
them as we go. One could read "deny" as an explicit override, rather than simply not having the permission.
This is debatable, but it's what I did here.
A role has a set of securable_objects
, each of which has a security_level
for each level
.
Example: a user with roles SALES3 and VIEWER-REPORTS.
If the user's current branch is 006
, then her effective branch, using the org chart above, is "lumber company",
which is at level 3. So her candidate permissions on "sales order entry screen" are read_only
and full
.
The algorithm should pick the most permissive, so she would get full
access.
You can evaluate different expressions from the command line. We will pass two files in.
- input.json, which models data you pass to opa, e.g. username and branch. In practice, the input data may be a JWT, entitlements from ADFS, LDAP attributes, etc.
- data.json, which is data stored in the agent. This is data you would sync out to the agents. In this example, it includes
user_data
- the user's roles and default branchorg_chart_data
- a DAG of the org chartrole_data
- roles, securable_objects, and the security_level for each level
You can modify the values in input.json to mimic different current_branch
scenarios.
opa eval -b . -f pretty -d data.json -i input.json 'data.rules.effective_security_level'
Output:
{
"CM_ENTRY": "read_only",
"PRINT_ACKNOWLEDGEMENTS": "full",
"SO_ENTRY": "read_only"
}
data.rules.effective_security_levels
data.rules.effective_security_level.SO_ENTRY
data.rules.effective_security_level.CM_ENTRY
data.rules.effective_security_level["SO_ENTRY"]
data.rules.user_permissions
You can interactively work with policies in opa's repl. Tab-completion is available (start with data
).
make repl
opa test . -v
If you're bolting this onto a monolith, you might have something like this.
edit: I have no idea what I'm talking about here.
- Admins manage the org chart and roles.
- Developers write policies.
- Use any data store to hold the authoritative org chart, role, and (possibly) user data.
- Push or pull data into the agent.
- Implementation of the data store is loosely coupled to the OPA interfaces.
- Use a separate identity provider, or not. OPA doesn't care.