How To Write Your Policies
Policy Language: Rego (Open Policy Agent)
PayMongo policies are written using Rego, the policy language from Open Policy Agent (OPA).
Rego is a purpose-built language for defining authorization and decision rules. It is widely used to express who can do what, under which conditions, in a clear and auditable way.
By using Rego, PayMongo enables you to:
- Write expressive and flexible policy rules
- Evaluate policies consistently at runtime
- Update business rules without changing application code
How PayMongo Uses Rego
When an operation is performed (for example, a wallet transfer), PayMongo:
- Identifies all active policies that match the resource and operation
- Evaluates each policy using Rego
- Collects the decision (allow or deny) from each policy
- Allows the operation only if all policies allow it
Your Rego policy does not execute the action itself. It only decides whether the action should be allowed.
Resources and Operations
Policies are always evaluated against:
- A
resource(what the policy applies to) - An
operation(the action being performed)
PayMongo provides a predefined set of supported resources and operations. Examples include:
- Resource:
wallet - Operation:
CreateTransfer
Only these predefined combinations are evaluated by the system.
ImportantThe full and up-to-date list of supported resources and operations is available on the Parameters page.
Violations
When a policy blocks an operation, PayMongo returns not only a deny decision, but also a list of violations explaining why the action was rejected. Violations allow you to display clear, user-friendly error messages in your application.
A violation is a structured reason returned by a policy when a rule is not satisfied.
For example, a policy might determine:
- The user is not authorized
- The amount exceeds a limit
- The destination account is not approved
Instead of only returning “denied”, the policy includes violation codes that describe the exact issue.
PayMongo maintains a predefined list of supported violation codes and their corresponding error messages. These are documented on the Parameters page. Each violation code maps to a specific message that your system should display.
Example (conceptual):
| Violation | Error Message |
|---|---|
identity:required | Authentication required |
destination_account:not found | Destination account not found |
transfer:exceeded | Transfer amount exceeded the allowed limit |
Always refer to the Parameters page for the official list.
When writing your policy:
- Use only violation codes listed on the Parameters page
- Return violations only when a rule fails
- Ensure violations accurately describe the failed condition
This ensures your application can reliably map violations to the correct user message. If your policy returns a violation code that is not listed on the Parameters page:
- PayMongo cannot map it to a specific message
- A generic error message will be used instead
Example of generic message:
“This action is not allowed due to policy restrictions.”
To avoid this, always use the official violation codes.
Policy Input Data
When your policy is evaluated, PayMongo passes structured input data into the Rego engine. This input contains contextual data relevant to the operation. You can use this input data to define your policy rules.
Rego policies evaluate the input provided by PayMongo.
Conceptually, a policy answers questions like:
- Is the user’s role allowed?
- Is the transfer amount within limits?
- Is the destination account approved?
- Is the operation happening at an allowed time?
Example (Conceptual)
“Allow wallet transfers only if the user role is finance_admin and the amount is below the maximum limit.”
Your policy would:
- Read the user role from the input
- Read the transfer amount from the input
- Return allow = true only if both conditions are met
All of these checks are done using the input data where the exact field names and structure are defined in the Parameters page
Policy Structure and Conventions
When writing Rego policies for PayMongo:
- Policies must return a clear allow or deny decision
- Use only documented input fields
- Avoid assumptions about missing data
- Keep policies focused and readable
PayMongo evaluates policies in a standardized way to ensure consistent behavior across all merchants. This is achieved by defining the output of the policies that merchants must follow and achieve when writing their policies.
Output example:
{
"allow": false,
"violations": [
"source_account_daily_limit_exceeded"
]
}
You can use this Rego template to achieve that desired output.
package <resource>.<operation>
default allow := false
allow if {
count(violations) == 0
}
Example
PayMongo evaluates wallet resource and CreateTransfer operation upon creating a transfer with input data sent into the evaluation as follows:
{
"account_limits" : {
"daily": {
"in" : 99999999999,
"out": 250000
},
"monthly": {
"in" : 15000000,
"out": 99999999999
}
},
"current_usage" : {
"daily": {
"in" : 0,
"out": 200000
},
"monthly": {
"in" : 0,
"out": 0
}
},
"type": "out",
"current_transaction_amount": 100000
}
With this input, you can create a policy to check whether the transfer will exceed the daily cash out limit of the account as follows:
package wallet.CreateTransfer
default allow := false
allow if {
count(violations) == 0
}
violations contains "source_account_daily_limit_exceeded" if {
input.current_usage.daily.out + input.current_transaction_amount > input.account_limits.daily.out
}
This policy will deny the transaction as the current transaction will violates the account daily limit if carried. The response of the policy evaluation will be :
{
"allow": false,
"violations": [
"source_account_daily_limit_exceeded"
]
}Updated 21 days ago