financial.rego
Allow rules for the most common transactional and read-side actions. Unlike the other modules, financial.rego defines deny and hitl as partial sets (no default boolean) so YAML-compiled rules — which emit deny[reason] if { … } and hitl[reason] if { … } — can extend them without colliding with a boolean default.
Package: kitelogik.financial · Source: kitelogik/policies/financial.rego
Rules
| Action | Allowed when | Risk-tier hint (set by main.rego) |
|---|---|---|
read_customer_record, list_transactions | Session has the read_customer scope | INFORMATIONAL |
approve_refund (≤ $100) | Role ∈ {support_agent, manager, worker_agent} and scope approve_refund_under_100 and amount in [0, 100] | TRANSACTIONAL_LOW |
approve_refund (≤ $1000) | Role = manager and scope approve_refund_under_1000 and amount in [0, 1000] | TRANSACTIONAL_HIGH (HITL on > $100, by main.rego) |
send_notification | Session has the send_notifications scope | (default OPERATIONAL) |
query_memory | Any active session (non-empty session_id) | (default OPERATIONAL) |
write_memory | Session has the memory_write scope | (default OPERATIONAL) |
execute_code | context.sandbox_verified == true | (default OPERATIONAL) — without sandbox, security.rego hard-denies |
All amount checks use is_number(...) first to close the OPA structural-ordering bypass (null < 0 would otherwise satisfy inequality silently).
Selected source
# Allow low-value refunds for support agents and delegated workers
allow if {
input.action == "approve_refund"
input.context.user_role in {"support_agent", "manager", "worker_agent"}
"approve_refund_under_100" in input.context.session_scopes
is_number(input.args.amount)
input.args.amount >= 0
input.args.amount <= 100
}
# Allow higher-value refunds for managers with elevated scope
allow if {
input.action == "approve_refund"
input.context.user_role == "manager"
"approve_refund_under_1000" in input.context.session_scopes
is_number(input.args.amount)
input.args.amount >= 0
input.args.amount <= 1000
}How main.rego uses this module
main.rego propagates this module two ways:
# Allow if a sub-policy grants access AND security/delegation don't deny
allow if { not deny; financial.allow }
# Propagate financial-package hard denies (typically YAML-compiled)
deny if { some msg; financial.deny[msg] }
# Propagate financial-package HITL routes (`then: hitl` in YAML)
requires_hitl if { some msg; financial.hitl[msg] }So extending this module via YAML — adding then: deny or then: hitl rules — automatically gets picked up by the aggregator without touching main.rego.
Extending in your own project
The intended path is YAML rather than editing the OSS rego directly:
# policies/refund_extras.yaml
version: 1
package: kitelogik.financial # same package — extends the OSS rules
rules:
- name: block_weekend_refunds
when:
action: approve_refund
args:
amount: { gt: 0 }
then: deny
reason: "Refunds disabled outside business hours"Compile with kitelogik compile policies/refund_extras.yaml. The main.rego aggregator then sees financial.deny["Refunds disabled outside business hours"] on every refund event, which becomes a hard deny.
For more complex extensions (cross-event invariants, time-of-day rules), write Rego directly. Same package; new rules merge.