M0 + M1 done

This commit is contained in:
marcos.lohmann_at_orcl
2026-09-11 15:04:34 -03:00
parent 5ebec725ec
commit 439f60598e
51 changed files with 2991 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
client_id: finance-payments-agent
profile: Finance.Payments
environment: production
description: "Finance agent authorized to create/execute payments (R3, approval above threshold)"

View File

@@ -0,0 +1,17 @@
# README.md §7.2, §17 (R3), §26 (payment.execute < 10k ALLOW, >= 10k REQUIRE_APPROVAL)
name: Finance.Payments
owner: finance-platform
environment: production
risk_ceiling: R3
allowed_tools:
- finance.invoice.get
- finance.payment.create
- finance.payment.execute
restrictions:
max_transaction_value: 10000000
approval_threshold: 10000
credential_policy:
workload_identity: true
short_lived: true
audit:
level: full

View File

@@ -0,0 +1,12 @@
# README.md §7.2, §17 (R1)
name: Finance.Read
owner: finance-platform
environment: production
risk_ceiling: R1
allowed_tools:
- finance.invoice.get
credential_policy:
workload_identity: true
short_lived: true
audit:
level: full

View File

@@ -0,0 +1,18 @@
# README.md §7.1
name: Sales.Approve
owner: sales-platform
environment: production
risk_ceiling: R2
allowed_tools:
- sales.customer.search
- sales.quote.get
- sales.quote.approve
- sales.discount.approve
restrictions:
max_transaction_value: 1000000
allowed_regions: ["BR-SP", "BR-RJ"]
credential_policy:
workload_identity: true
short_lived: true
audit:
level: full

View File

@@ -0,0 +1,15 @@
# README.md §7.1
name: Sales.Read
owner: sales-platform
environment: production
risk_ceiling: R1
allowed_tools:
- sales.customer.search
- sales.customer.get
- sales.order.get
- sales.inventory.check
credential_policy:
workload_identity: true
short_lived: true
audit:
level: full

View File

@@ -0,0 +1,20 @@
# README.md §7.1, §41
name: Sales.Write
owner: sales-platform
environment: production
risk_ceiling: R2
allowed_tools:
- sales.customer.search
- sales.customer.get
- sales.order.get
- sales.inventory.check
- sales.quote.create
- sales.quote.update
restrictions:
max_transaction_value: 500000
allowed_regions: ["BR-SP", "BR-RJ"]
credential_policy:
workload_identity: true
short_lived: true
audit:
level: full

View File

@@ -0,0 +1,4 @@
client_id: sales-read-agent
profile: Sales.Read
environment: production
description: "Read-only Sales conversational agent"

View File

@@ -0,0 +1,4 @@
client_id: sales-write-agent
profile: Sales.Write
environment: production
description: "Sales agent authorized to create/update quotes"

View File

@@ -0,0 +1,20 @@
# Entitlement policy (EP-03-T02, README.md §25 Passo 1, §6.5.A).
#
# permit if requested_tool IN entitlement(authenticated_client)
#
# `input.client_profile` is the client profile *name* the Gateway already
# resolved from the authenticated client_id (EP-01-T03 -> identity/models.py
# ClientRegistration.profile) -- never a value read from the request body.
# `data.emcp.client_profiles` is pushed into OPA by the Entitlement Manager
# (EP-04-T02) from the validated ClientProfile YAML (EP-04-T01); this policy
# never parses YAML itself.
package emcp.entitlement
import rego.v1
default allow := false
allow if {
profile := data.emcp.client_profiles[input.client_profile]
input.tool in profile.allowed_tools
}

View File

@@ -0,0 +1,21 @@
package emcp.entitlement_test
import rego.v1
import data.emcp.entitlement
test_allow_when_tool_in_entitlement if {
entitlement.allow with input as {"client_profile": "Sales.Read", "tool": "sales.customer.get"}
with data.emcp.client_profiles as {"Sales.Read": {"allowed_tools": ["sales.customer.get"]}}
}
test_deny_when_tool_not_in_entitlement if {
# README.md §45 Teste 1/2: finance.createPayment must never be reachable
# by a Sales.Read client, discovered or not.
not entitlement.allow with input as {"client_profile": "Sales.Read", "tool": "finance.createPayment"}
with data.emcp.client_profiles as {"Sales.Read": {"allowed_tools": ["sales.customer.get"]}}
}
test_deny_when_client_profile_unknown if {
not entitlement.allow with input as {"client_profile": "NoSuchProfile", "tool": "sales.customer.get"}
with data.emcp.client_profiles as {"Sales.Read": {"allowed_tools": ["sales.customer.get"]}}
}

View File

@@ -0,0 +1,68 @@
# Transaction policy (EP-03-T03, README.md §25 Passo 2, §6.5.B, §26).
#
# permit quote.create if
# amount <= client.transaction_limit
# AND region IN client.allowed_regions
# AND customer.classification != "restricted"
#
# Restricts a tool *already granted* by entitlement.rego -- this policy never
# adds a tool absent from the client's entitlement (README.md §25, "A
# Transaction Policy pode negar ou restringir. Ela não pode adicionar uma
# tool inexistente no Client Entitlement."). `allow` here is meaningless on
# its own; the PDP client (EP-03-T04) only consults it after entitlement.rego
# already allowed the same (client_profile, tool) pair.
#
# input: {
# "client_profile": "Sales.Write",
# "tool": "sales.quote.create",
# "arguments": {"amount": 100000, "region": "BR-SP"},
# "customer_classification": "standard"
# }
package emcp.transaction
import rego.v1
default allow := false
default require_approval := false
allow if {
profile := data.emcp.client_profiles[input.client_profile]
within_transaction_limit(profile)
within_allowed_regions(profile)
not restricted_customer
}
# README.md §26: above the profile's approval_threshold, a transaction that
# would otherwise be allowed instead requires human approval (EP-14) -- it is
# never silently allowed, and never silently upgraded to a hard deny either.
require_approval if {
allow
profile := data.emcp.client_profiles[input.client_profile]
threshold := profile.restrictions.approval_threshold
amount := object.get(input.arguments, "amount", 0)
amount > threshold
}
within_transaction_limit(profile) if {
not profile.restrictions.max_transaction_value
}
within_transaction_limit(profile) if {
limit := profile.restrictions.max_transaction_value
amount := object.get(input.arguments, "amount", 0)
amount <= limit
}
within_allowed_regions(profile) if {
not profile.restrictions.allowed_regions
}
within_allowed_regions(profile) if {
region := object.get(input.arguments, "region", "")
region in profile.restrictions.allowed_regions
}
restricted_customer if {
input.customer_classification == "restricted"
}

View File

@@ -0,0 +1,72 @@
package emcp.transaction_test
import rego.v1
import data.emcp.transaction
sales_write_profile := {"restrictions": {
"max_transaction_value": 500000,
"allowed_regions": ["BR-SP", "BR-RJ"],
"approval_threshold": 100000,
}}
test_allow_within_limit_and_region if {
transaction.allow with input as {
"client_profile": "Sales.Write",
"tool": "sales.quote.create",
"arguments": {"amount": 50000, "region": "BR-SP"},
"customer_classification": "standard",
} with data.emcp.client_profiles as {"Sales.Write": sales_write_profile}
}
test_deny_above_transaction_limit if {
not transaction.allow with input as {
"client_profile": "Sales.Write",
"tool": "sales.quote.create",
"arguments": {"amount": 600000, "region": "BR-SP"},
"customer_classification": "standard",
} with data.emcp.client_profiles as {"Sales.Write": sales_write_profile}
}
test_deny_outside_allowed_region if {
not transaction.allow with input as {
"client_profile": "Sales.Write",
"tool": "sales.quote.create",
"arguments": {"amount": 50000, "region": "BR-MG"},
"customer_classification": "standard",
} with data.emcp.client_profiles as {"Sales.Write": sales_write_profile}
}
test_deny_restricted_customer if {
not transaction.allow with input as {
"client_profile": "Sales.Write",
"tool": "sales.quote.create",
"arguments": {"amount": 50000, "region": "BR-SP"},
"customer_classification": "restricted",
} with data.emcp.client_profiles as {"Sales.Write": sales_write_profile}
}
test_require_approval_above_threshold if {
# README.md §26: allowed, but only with human approval, above threshold.
transaction.allow with input as {
"client_profile": "Sales.Write",
"tool": "sales.quote.create",
"arguments": {"amount": 150000, "region": "BR-SP"},
"customer_classification": "standard",
} with data.emcp.client_profiles as {"Sales.Write": sales_write_profile}
transaction.require_approval with input as {
"client_profile": "Sales.Write",
"tool": "sales.quote.create",
"arguments": {"amount": 150000, "region": "BR-SP"},
"customer_classification": "standard",
} with data.emcp.client_profiles as {"Sales.Write": sales_write_profile}
}
test_no_approval_required_below_threshold if {
not transaction.require_approval with input as {
"client_profile": "Sales.Write",
"tool": "sales.quote.create",
"arguments": {"amount": 50000, "region": "BR-SP"},
"customer_classification": "standard",
} with data.emcp.client_profiles as {"Sales.Write": sales_write_profile}
}