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 aggregates this module's allow rules:
# Allow if a sub-policy grants access AND security/delegation don't deny
allow if { not deny; financial.allow }To extend financial governance with your own rules, write them in YAML (then: allow / then: hitl / then: deny) and compile — they land in the kitelogik.userpolicy package, which main.rego aggregates the same way:
allow if { not deny; userpolicy.allow }
deny if { some msg; userpolicy.deny[msg] }
requires_hitl if { some msg; userpolicy.hitl[msg] }So you never edit main.rego or this module directly — your compiled YAML is picked up automatically.
Extending in your own project
The intended path is YAML rather than editing the OSS rego directly:
# policies/refund_extras.yaml
version: 1
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 rules land in the kitelogik.userpolicy package. The main.rego aggregator then sees userpolicy.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 in the kitelogik.userpolicy package using a set-valued deny[reason] if {...} rule — main.rego aggregates those the same way.