diff --git a/apps/authz/src/app/opa/rego/lib/criterias/principal.rego b/apps/authz/src/app/opa/rego/lib/criterias/principal.rego index 93a465dc8..7881ec779 100644 --- a/apps/authz/src/app/opa/rego/lib/criterias/principal.rego +++ b/apps/authz/src/app/opa/rego/lib/criterias/principal.rego @@ -2,6 +2,14 @@ package main import future.keywords.in +is_principal_root_user { + principal.role == "root" +} + +is_principal_assigned_to_wallet { + principal.uid in resource.assignees +} + check_principal_id(values) { values == wildcard } @@ -25,4 +33,4 @@ check_principal_groups(values) { check_principal_groups(values) { group := principal_groups[_] group in values -} \ No newline at end of file +} diff --git a/apps/authz/src/app/opa/rego/lib/criterias/resource.rego b/apps/authz/src/app/opa/rego/lib/criterias/resource.rego index a77becf40..30e03cbe3 100644 --- a/apps/authz/src/app/opa/rego/lib/criterias/resource.rego +++ b/apps/authz/src/app/opa/rego/lib/criterias/resource.rego @@ -38,4 +38,4 @@ check_wallet_assignees(values) { check_wallet_assignees(values) { assignee := resource.assignees[_] assignee in values -} \ No newline at end of file +} diff --git a/apps/authz/src/app/opa/rego/lib/criterias/source.rego b/apps/authz/src/app/opa/rego/lib/criterias/source.rego index b56b045e4..5fb59c3ef 100644 --- a/apps/authz/src/app/opa/rego/lib/criterias/source.rego +++ b/apps/authz/src/app/opa/rego/lib/criterias/source.rego @@ -28,4 +28,4 @@ check_source_classification(values) { check_source_classification(values) { source.classification in values -} \ No newline at end of file +} diff --git a/apps/authz/src/app/opa/rego/lib/criterias/transfer_token.rego b/apps/authz/src/app/opa/rego/lib/criterias/transfer_token.rego index 5af5f757f..990ef3cb1 100644 --- a/apps/authz/src/app/opa/rego/lib/criterias/transfer_token.rego +++ b/apps/authz/src/app/opa/rego/lib/criterias/transfer_token.rego @@ -62,4 +62,4 @@ check_transfer_token_operation(operation) { check_transfer_token_operation(operation) { operation.operator == "lte" operation.value >= input.intent.amount -} \ No newline at end of file +} diff --git a/apps/authz/src/app/opa/rego/lib/data.json b/apps/authz/src/app/opa/rego/lib/data.json index 23d384213..8d73987d5 100644 --- a/apps/authz/src/app/opa/rego/lib/data.json +++ b/apps/authz/src/app/opa/rego/lib/data.json @@ -22,7 +22,7 @@ "uid": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e", "address": "0xddcf208f219a6e6af072f2cfdc615b2c1805f98e", "accountType": "eoa", - "assignees": ["test-bob-uid", "test-bar-uid"] + "assignees": ["test-bob-uid", "test-bar-uid", "test-foo-uid"] }}, "user_groups": { "test-user-group-one-uid": { diff --git a/apps/authz/src/app/opa/rego/lib/input.json b/apps/authz/src/app/opa/rego/lib/input.json index a7445df3b..114c32006 100644 --- a/apps/authz/src/app/opa/rego/lib/input.json +++ b/apps/authz/src/app/opa/rego/lib/input.json @@ -1,6 +1,6 @@ { "action": "signTransaction", - "principal": {"uid": "test-bob-uid"}, + "principal": {"uid": "test-foo-uid"}, "resource": {"uid": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e"}, "request": { "type": "eip1559", diff --git a/apps/authz/src/app/opa/rego/lib/main.rego b/apps/authz/src/app/opa/rego/lib/main.rego index 5e3a3f655..5318ace37 100644 --- a/apps/authz/src/app/opa/rego/lib/main.rego +++ b/apps/authz/src/app/opa/rego/lib/main.rego @@ -12,21 +12,22 @@ default evaluate := { } evaluate := decision { - confirm_set := {p | p = permit[_]} + permit_set := {p | p = permit[_]} forbid_set := {f | f = forbid[_]} - count(confirm_set) > 0 + count(forbid_set) == 0 + count(permit_set) > 0 - # If ALL Approval in confirm_set has count(approval.approvalsMissing) == 0, set "permit": true. + # If ALL Approval in permit_set has count(approval.approvalsMissing) == 0, set "permit": true. # We "Stack" approvals, so multiple polices that match & each have different requirements, ALL must succeed. # If you want to avoid this, the rules should get upper bounded so they're mutually exlusive, but that's done at the policy-builder time, not here. - # Filter confirm_set to only include objects where approvalsMissing is empty - filtered_confirm_set := {p | p = confirm_set[_]; count(p.approvalsMissing) == 0} + # Filter permit_set to only include objects where approvalsMissing is empty + filtered_permit_set := {p | p = permit_set[_]; count(p.approvalsMissing) == 0} decision := { - "permit": count(filtered_confirm_set) == count(confirm_set), - "reasons": confirm_set, + "permit": count(filtered_permit_set) == count(permit_set), + "reasons": permit_set, } } @@ -44,6 +45,16 @@ evaluate := decision { } } -forbid[{"policyId": "test-forbid-policy"}] { - 2 == 1 +permit[{"policyId": "allow-root-user"}] := reason { + is_principal_root_user + + reason := { + "policyId": "allow-root-user", + "approvalsSatisfied": [], + "approvalsMissing": [], + } +} + +forbid[{"policyId": "default-forbid-policy"}] { + false } diff --git a/apps/authz/src/app/opa/rego/lib/policies/policy1.rego b/apps/authz/src/app/opa/rego/lib/policies/policy1.rego deleted file mode 100644 index 8bdd1a9f4..000000000 --- a/apps/authz/src/app/opa/rego/lib/policies/policy1.rego +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import future.keywords.in - -permit[{"policyId": "test-policy-1"}] := reason { - check_principal_id({"test-bob-uid"}) - check_wallet_assignees({"test-bob-uid"}) - check_transfer_token_type({"transferToken"}) - check_transfer_token_address({"0x2791bca1f2de4661ed88a30c99a7a9449aa84174"}) - check_transfer_token_operation({"operator": "eq", "value": 1000000000000000000}) - - approvalsRequired = [ - { - "threshold": 1, - "countPrincipal": true, - "entityType": "Narval::UserGroup", - "entityIds": ["test-user-group-one-uid"], - }, - { - "threshold": 2, - "countPrincipal": true, - "entityType": "Narval::User", - "entityIds": ["test-bob-uid", "test-bar-uid", "test-signer-uid"], - }, - ] - - approvalsResults = [res | - approval := approvalsRequired[_] - res := check_approval(approval) - ] - - approvals := get_approvals_result(approvalsResults) - - reason := { - "policyId": "test-policy-1", - "approvalsSatisfied": approvals.approvalsSatisfied, - "approvalsMissing": approvals.approvalsMissing, - } -} \ No newline at end of file diff --git a/apps/authz/src/app/opa/rego/lib/policies/policy2.rego b/apps/authz/src/app/opa/rego/lib/policies/policy2.rego deleted file mode 100644 index 380bbd69d..000000000 --- a/apps/authz/src/app/opa/rego/lib/policies/policy2.rego +++ /dev/null @@ -1,35 +0,0 @@ -package main - -import future.keywords.in - -permit[{"policyId": "test-policy-2"}] := reason { - check_principal_id({"test-bob-uid"}) - check_wallet_assignees({"test-bob-uid"}) - check_transfer_token_type({"transferToken"}) - check_transfer_token_address({"0x2791bca1f2de4661ed88a30c99a7a9449aa84174"}) - check_transfer_token_operation({"operator": "eq", "value": 1000000000000000000}) - approvalsRequired = [ - { - "threshold": 1, - "countPrincipal": true, - "entityType": "Narval::UserGroup", - "entityIds": ["test-user-group-one-uid"], - }, - { - "threshold": 2, - "countPrincipal": true, - "entityType": "Narval::User", - "entityIds": ["test-bob-uid", "test-bar-uid", "test-signer-uid"], - }, - ] - approvalsResults = [res | - approval := approvalsRequired[_] - res := check_approval(approval) - ] - approvals := get_approvals_result(approvalsResults) - reason := { - "policyId": "test-policy-2", - "approvalsSatisfied": approvals.approvalsSatisfied, - "approvalsMissing": approvals.approvalsMissing, - } -} diff --git a/apps/authz/src/app/opa/rego/lib/policies/policy3.rego b/apps/authz/src/app/opa/rego/lib/policies/policy3.rego deleted file mode 100644 index 6862c9c9d..000000000 --- a/apps/authz/src/app/opa/rego/lib/policies/policy3.rego +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import future.keywords.in - -permit[{"policyId": "test-policy-3"}] := reason { - check_principal_id({"test-bob-uid"}) - check_wallet_assignees({"test-bob-uid"}) - check_transfer_token_type({"transferToken"}) - check_transfer_token_address({"0x2791bca1f2de4661ed88a30c99a7a9449aa84174"}) - check_transfer_token_operation({"operator": "eq", "value": 1000000000000000000}) - - approvalsRequired = [{ - "threshold": 2, - "countPrincipal": false, - "entityType": "Narval::UserRole", - "entityIds": ["admin"], - }] - approvalsResults = [res | - approval := approvalsRequired[_] - res := check_approval(approval) - ] - - approvals := get_approvals_result(approvalsResults) - - reason := { - "policyId": "test-policy-3", - "approvalsSatisfied": approvals.approvalsSatisfied, - "approvalsMissing": approvals.approvalsMissing, - } -} diff --git a/apps/authz/src/app/opa/rego/lib/utils/utils.rego b/apps/authz/src/app/opa/rego/lib/utils/utils.rego index 788a81c1c..62e8e637d 100644 --- a/apps/authz/src/app/opa/rego/lib/utils/utils.rego +++ b/apps/authz/src/app/opa/rego/lib/utils/utils.rego @@ -73,4 +73,4 @@ signers_groups = result { check_transfer_resource_integrity { contains(input.resource.uid, input.request.from) input.resource.uid == input.intent.from.uid -} \ No newline at end of file +}