ANILA SOMAN
10/26/2023, 11:11 AMCREATE DATABASE IF NOT EXISTS cerbos CHARACTER SET utf8mb4;
USE cerbos;
CREATE TABLE IF NOT EXISTS policy (
id BIGINT PRIMARY KEY,
kind VARCHAR(128) NOT NULL,
name VARCHAR(1024) NOT NULL,
version VARCHAR(128) NOT NULL,
scope VARCHAR(512),
description TEXT,
disabled BOOLEAN default false,
definition BLOB);
CREATE TABLE IF NOT EXISTS policy_dependency (
policy_id BIGINT NOT NULL,
dependency_id BIGINT NOT NULL,
PRIMARY KEY (policy_id, dependency_id),
FOREIGN KEY (policy_id) REFERENCES policy(id) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS policy_ancestor (
policy_id BIGINT NOT NULL,
ancestor_id BIGINT NOT NULL,
PRIMARY KEY (policy_id, ancestor_id),
FOREIGN KEY (policy_id) REFERENCES policy(id) ON DELETE CASCADE);
CREATE TABLE IF NOT EXISTS policy_revision (
revision_id INTEGER AUTO_INCREMENT PRIMARY KEY,
action ENUM('INSERT', 'UPDATE', 'DELETE'),
id BIGINT NOT NULL,
kind VARCHAR(128),
name VARCHAR(1024),
version VARCHAR(128),
scope VARCHAR(512),
description TEXT,
disabled BOOLEAN,
definition BLOB,
update_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
CREATE TABLE IF NOT EXISTS attr_schema_defs (
id VARCHAR(255) PRIMARY KEY,
definition JSON);
ANILA SOMAN
10/26/2023, 11:16 AMEric Brisco
10/28/2023, 4:38 PMDmitry Meyerson
10/30/2023, 6:59 PMThomas Henson
11/02/2023, 10:24 AMAkash LM
11/02/2023, 5:11 PMThomas Henson
11/07/2023, 3:42 PMAre there any additional network implications as a service that result in longer calls than would exist as a coupled process? If you loop over a list of objects to filter a list of N items by policy, we want to be sure that its not going to add 10s of seconds on.A service deployment looks as though it will be better for our particular use case, but we just want to be sure it isn't going to impact performance drastically. Cheers 😄
Ashwyn Nair
11/07/2023, 6:23 PMactions: ['read', 'update, 'delete']
, i would like for the policy to respond with all of the authorised actions the user can take. If I'm thinking about things correctly, this would make things a little more simple at call site?Charles Moga
11/08/2023, 4:11 PMCharles Moga
11/08/2023, 4:11 PMTobias
11/10/2023, 3:00 PMcerbos.yaml
configuration:
...
engine:
defaultPolicyVersion: 'default'
globals:
some_variable: ${SOME_ENV_VARIABLE}
...
The custom_policy.yaml
looks like this:
apiVersion: api.cerbos.dev/v1
resourcePolicy:
version: 'default'
resource: some_resource
rules:
- actions: ['view']
effect: EFFECT_ALLOW
roles:
- user
condition:
match:
all:
of:
- expr: R.attr.some_field == true
- expr: P.attr.some_attr == false
- expr: G.some_variable == true
And the custom_policy_test.yaml
(in it's current state) looks like this:
name: CustomTests
description: Tests for custom policy.
principals:
someUser:
id: u1
roles:
- user
attr:
some_attr: false
resources:
someResource:
id: restricted-network-request
kind: some_resource
policyVersion: default
attr:
some_field: true
tests:
- name: Test custom policy
input:
principals:
- someUser
resources:
- someResource
actions:
- view
expected:
- principal: someUser
resource: someResource
actions:
view: EFFECT_ALLOW
The tests are executed with ./cerbos compile --tests=/path_to_tests /path_to_policies
with Version 0.30.0
Bradey Wood
11/13/2023, 5:08 PMBradey Wood
11/13/2023, 5:09 PMBradey Wood
11/13/2023, 5:09 PMBradey Wood
11/13/2023, 5:11 PMapiVersion: "api.cerbos.dev/v1"
description: |-
This policy defines who can access an app
resourcePolicy:
version: "template"
resource: "mua:app"
rules:
- actions: ["access"]
roles: ["*"]
effect: EFFECT_ALLOW
condition:
match:
expr: R.id in P.attr.appsEnabled
Test:
---
name: access app
description: Tests for verifying who can access an app
principals:
ioi_enabled:
id: ioi_user
roles: [user]
attr:
appsEnabled: ["ioi"]
ecm_enabled:
id: ecm_user
roles: [user]
attr:
appsEnabled: ["ecm"]
both_enabled:
id: ioi_and_ecm_user
roles: [user]
attr:
appsEnabled: ["ecm", "ioi"]
resources:
ioi:
id: ioi
kind: "mua:app"
ecm:
id: ecm
kind: "mua:app"
tests:
- name: app enabled users can access the relevant app
input:
principals:
- ioi_enabled
resources:
- ioi
actions:
- access
expected:
- principal: ioi_enabled
resource: ioi
actions:
access: EFFECT_ALLOW
Bradey Wood
11/13/2023, 5:12 PMrequest = {
"resource": {
"kind": "mua:app",
"id": "ioi"
},
"principal": {
"id": "ioi_user",
"roles": [
"user"
],
"attr": {
"appsEnabled": [
"ioi"
]
}
}
}
Rules:
-> :rules
Conditional rules in 'resource.mua_app.vtemplate'
[#0]
actions:
- access
condition:
match:
expr: R.id in P.attr.appsEnabled
effect: EFFECT_ALLOW
roles:
- '*'
-> :exec #0
└──R.id in P.attr.appsEnabled [true]
Tests:
cerbos compile policies --verbose --run=app
Test results
├──view deal (resource_policies/ECM/deal_test.yaml) [SKIPPED]
└─┬access app (resource_policies/MUA/app_test.yaml) [1 FAILED]
└─┬app enabled users can access the relevant app
└─┬ioi_enabled
└─┬ioi
└─┬access [FAILED]
└──OUTCOME: expected: EFFECT_ALLOW, actual: EFFECT_DENY
TRACES
access app - ioi_enabled.ioi.access
action=access
activated
effect → deny
No matching policies
16 tests executed [15 SKIPPED] [1 FAILED]
cerbos: error: tests failed
Bradey Wood
11/13/2023, 5:15 PMBradey Wood
11/13/2023, 5:22 PMtestdata
...
cerbos compile policies --verbose --run=app
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x11f238a]
goroutine 1 [running]:
<http://github.com/cerbos/cerbos/internal/verify.(*TestFixture).lookupResource(0xc001869320|github.com/cerbos/cerbos/internal/verify.(*TestFixture).lookupResource(0xc001869320>, 0x7f8263477878?, {0xc000890f50, 0x8})
<http://github.com/cerbos/cerbos/internal/verify/test_fixture.go:484|github.com/cerbos/cerbos/internal/verify/test_fixture.go:484> +0x4a
<http://github.com/cerbos/cerbos/internal/verify.(*TestFixture).buildTest(0xc0018f6090|github.com/cerbos/cerbos/internal/verify.(*TestFixture).buildTest(0xc0018f6090>?, 0xc000f6a370, 0xc0018f6090, {{0xc001635350, 0x0}, {{0xc000890f00, 0xc}, {0xc000890f50, 0x8}}})
<http://github.com/cerbos/cerbos/internal/verify/test_fixture.go:432|github.com/cerbos/cerbos/internal/verify/test_fixture.go:432> +0x12d
<http://github.com/cerbos/cerbos/internal/verify.(*TestFixture).buildTests(0x0|github.com/cerbos/cerbos/internal/verify.(*TestFixture).buildTests(0x0>?, 0x0?, 0x0?)
<http://github.com/cerbos/cerbos/internal/verify/test_fixture.go:411|github.com/cerbos/cerbos/internal/verify/test_fixture.go:411> +0x107
<http://github.com/cerbos/cerbos/internal/verify.(*TestFixture).getTests|github.com/cerbos/cerbos/internal/verify.(*TestFixture).getTests>(0x4163b0?, 0xc000f6a370)
<http://github.com/cerbos/cerbos/internal/verify/test_fixture.go:391|github.com/cerbos/cerbos/internal/verify/test_fixture.go:391> +0xee
<http://github.com/cerbos/cerbos/internal/verify.(*TestFixture).runTestSuite(0x1e|github.com/cerbos/cerbos/internal/verify.(*TestFixture).runTestSuite(0x1e>?, {0x34876e0, 0xc000ff4ac0}, {0x345d780, 0xc0014c0de0}, 0x34874e8?, {0xc001015560, 0x24}, 0xc000f6a370, 0x1)
<http://github.com/cerbos/cerbos/internal/verify/test_fixture.go:187|github.com/cerbos/cerbos/internal/verify/test_fixture.go:187> +0x1fc
<http://github.com/cerbos/cerbos/internal/verify.Verify.func5({0xc001015560|github.com/cerbos/cerbos/internal/verify.Verify.func5({0xc001015560>, 0x24})
<http://github.com/cerbos/cerbos/internal/verify/verify.go:143|github.com/cerbos/cerbos/internal/verify/verify.go:143> +0x5ef
<http://github.com/cerbos/cerbos/internal/verify.Verify(|github.com/cerbos/cerbos/internal/verify.Verify(>{0x34876e0, 0xc000ff4ac0}, {0x345da20, 0xc0013923f0}, {0x345d780, 0xc0014c0de0}, {{0xc0008707d0?, 0xc000e0f170?}, 0xc0?})
<http://github.com/cerbos/cerbos/internal/verify/verify.go:151|github.com/cerbos/cerbos/internal/verify/verify.go:151> +0x48f
<http://github.com/cerbos/cerbos/cmd/cerbos/compile.(*Cmd).Run(0xc001408d00|github.com/cerbos/cerbos/cmd/cerbos/compile.(*Cmd).Run(0xc001408d00>, 0xc000d1c280)
<http://github.com/cerbos/cerbos/cmd/cerbos/compile/compile.go:146|github.com/cerbos/cerbos/cmd/cerbos/compile/compile.go:146> +0x886
reflect.Value.call({0x2809480?, 0xc001408d00?, 0x2b93da0?}, {0x2bb01d5, 0x4}, {0xc0006fa480, 0x1, 0x0?})
reflect/value.go:596 +0xce7
reflect.Value.Call({0x2809480?, 0xc001408d00?, 0x2797460?}, {0xc0006fa480?, 0x2b93da0?, 0xc000130f70?})
reflect/value.go:380 +0xb9
<http://github.com/alecthomas/kong.callFunction(|github.com/alecthomas/kong.callFunction(>{0x2809480?, 0xc001408d00?, 0x0?}, 0x2baf710?)
<http://github.com/alecthomas/kong@v0.8.1/callbacks.go:98|github.com/alecthomas/kong@v0.8.1/callbacks.go:98> +0x40b
<http://github.com/alecthomas/kong.(*Context).RunNode(0xc0007cb880|github.com/alecthomas/kong.(*Context).RunNode(0xc0007cb880>, 0xc000f6c4b0, {0x0, 0x0, 0xc000d1c280?})
<http://github.com/alecthomas/kong@v0.8.1/context.go:765|github.com/alecthomas/kong@v0.8.1/context.go:765> +0x810
<http://github.com/alecthomas/kong.(*Context).Run(0x25f1be0|github.com/alecthomas/kong.(*Context).Run(0x25f1be0>?, {0x0?, 0xc00149fee0?, 0x7?})
<http://github.com/alecthomas/kong@v0.8.1/context.go:790|github.com/alecthomas/kong@v0.8.1/context.go:790> +0x132
main.main()
<http://github.com/cerbos/cerbos/cmd/cerbos/main.go:45|github.com/cerbos/cerbos/cmd/cerbos/main.go:45> +0x2b6
Bradey Wood
11/13/2023, 5:23 PMresources.yaml
in my test data, I mistakenly named it deals.yaml
and this seems to cause the segfault... just in case you guys weren't aware.Bradey Wood
11/13/2023, 5:23 PMcerbos --version
0.31.0
Build timestamp: 2023-10-31T07:58:39Z
Build commit: 625bc0d022e55377f6f9e70ec634d1493916a265
Go version: go1.21.3
vcs: git
vcs.revision: 625bc0d022e55377f6f9e70ec634d1493916a265
vcs.time: 2023-10-31T07:55:53Z
vcs.modified: false
Charles Moga
11/14/2023, 11:11 AMCharles Moga
11/14/2023, 11:12 AMI am trying to workout this snippet and adapt for our use case:
CheckResult result=client.check(
Principal.newInstance("john","employee")
.withPolicyVersion("20210210")
.withAttribute("department",stringValue("marketing"))
.withAttribute("geography",stringValue("GB")),
Resource.newInstance("leave_request","xx125")
.withPolicyVersion("20210210")
.withAttribute("department",stringValue("marketing"))
.withAttribute("geography",stringValue("GB"))
.withAttribute("owner",stringValue("john")),
"view:public","approve");
if(result.isAllowed("approve")){ // returns true if `approve` action is allowed
...
}
Our use case is a rest API with post, get, update and delete, and I have mapped against resources.
Fo example, we have "admin" with the following access:
resource|create |read |update |delete
---------------------------------------
user | true | true | true | true
payment | false | true | false | false
Now when request hits '/user', we have an interceptor,
that takes "user" as the resource, action (post, get, update, or delete) JWT that contains user data including the role, which is admin.
And I am trying to figure out how I can adapt the code above to authorize/deny a request
Bradey Wood
11/14/2023, 11:41 AMEFFECT_ALLOW
or EFFECT_DENY
alongside the OK
-- I have PO's who are looking at test output and confusing OK
(it passed the test) with EFFECT_ALLOW
-- the action was allowed.Charles Moga
11/15/2023, 3:43 AMCharles Moga
11/15/2023, 3:43 AMjava.lang.NoClassDefFoundError: io/grpc/internal/AbstractManagedChannelImplBuilder
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1013)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
Charles Moga
11/15/2023, 3:44 AMimplementation("dev.cerbos:cerbos-sdk-java:0.7.0")
implementation("io.grpc:grpc-core:1.59.0")
Bradey Wood
11/15/2023, 9:54 AMAnkit Khosla
11/18/2023, 4:38 PMcondition
is not working. It should only ALLOW
when tenantId
and organizationId
matches. But it’s not working as expected. Any suggestions?
org_staff_roles.yaml
# yaml-language-server: $schema=<https://api.cerbos.dev/latest/cerbos/policy/v1/Policy.schema.json>
# docs: <https://docs.cerbos.dev/cerbos/latest/policies/derived_roles>
apiVersion: api.cerbos.dev/v1
derivedRoles:
name: org_staff_roles
definitions:
- name: MANAGER
parentRoles:
- admin
condition:
match:
all:
of:
- expr: R.attr.tenantId == P.attr.tenantId
- expr: R.attr.organizationId == P.attr.organizationId
- name: READ_ONLY
parentRoles:
- user
condition:
match:
all:
of:
- expr: R.attr.tenantId == P.attr.tenantId
- expr: R.attr.organizationId == P.attr.organizationId
- name: APPROVER
parentRoles:
- user
condition:
match:
all:
of:
- expr: R.attr.tenantId == P.attr.tenantId
- expr: R.attr.organizationId == P.attr.organizationId
resource-policy.yml
apiVersion: api.cerbos.dev/v1
resourcePolicy:
resource: inventory
version: default
importDerivedRoles:
- user_roles
- admin_roles
- org_staff_roles
rules:
- actions: ["*"]
effect: EFFECT_ALLOW
roles:
- ORG_ADMIN
- SUPER_ADMIN
name: inventory_admin_rule
- actions:
[
"create",
"read",
"update",
"delete",
"approve"
]
effect: EFFECT_ALLOW
roles:
- MANAGER
name: inventory_manager_rule
- actions:
[
"approve"
]
effect: EFFECT_ALLOW
roles:
- APPROVER
name: inventory_creator_rule
- actions:
[
"read",
]
effect: EFFECT_ALLOW
roles:
- CHECKER
name: inventory_checker_rule
request body:
Should be DENY
all actions since, organizationId
does not match between, resource and principal. But it’s being ALLOWED
.
{
"requestId": "123123",
"principal": {
"id": "123",
"roles": [
"MANAGER"
],
"attr": {
"organizationId": "123",
"tenantId": "1234"
}
},
"resources": [
{
"resource": {
"kind": "inventory",
"id": "1234",
"attr": {
"organizationId": "123333",
"tenantId": "1234"
}
},
"actions": [
"approve",
"create",
"delete",
"read",
"update"
]
}
]
}
Bradey Wood
11/20/2023, 4:22 PMSai Kumar Gade
11/21/2023, 9:28 AM