OPA Policies¶
Mayo ASPM uses the Open Policy Agent (OPA) engine to let you codify security decisions as policy. Policies are written in Rego and evaluate findings, assets, and scan results to automate triage, prioritization, ownership assignment, project mapping, and PR scan gates.
Why policy-as-code?¶
| Traditional approach | Policy-as-code with Mayo ASPM |
|---|---|
| Manual triage in spreadsheets | Automated triage at ingest time |
| "Ask the security team" for priority | Consistent priority scoring via policy |
| Tribal knowledge about ownership | Ownership rules codified and auditable |
| Ad-hoc PR review criteria | Deterministic PR scan gates |
Policy kinds¶
Mayo ASPM supports five kinds of policies, each serving a different purpose:
| Kind | Purpose | Evaluated when |
|---|---|---|
| Triage | Accept, reject, or defer findings | New findings arrive |
| Priority | Assign a priority score to findings | After triage |
| Ownership | Assign findings to teams or individuals | After triage |
| Project | Map assets to projects | New assets discovered |
| PR Scan | Pass/fail gates for pull requests | PR scan completes |
Policy lifecycle¶
Create (draft) ──▶ Test (playground) ──▶ Activate ──▶ Evaluate ──▶ Version
│ │
└──── iterate ◀──────────────────────────────┘
- Create — write a policy in the editor or via the API.
- Test — validate in the Policy Playground with sample inputs.
- Activate — enable the policy so it runs on real data.
- Evaluate — the policy runs automatically when its trigger condition is met.
- Version — every save creates a new version; roll back at any time.
Quick example¶
A triage policy that auto-accepts critical CVEs and rejects informational findings:
package mayo.triage
import rego.v1
decision := "accept" if {
input.finding.severity == "critical"
input.finding.cve_id != ""
}
decision := "reject" if {
input.finding.severity == "info"
}
Managing policies¶
In the UI¶
Navigate to Policies in the left sidebar to:
- View all policies grouped by kind
- Create, edit, and delete policies
- See evaluation statistics (how many findings each policy affected)
- Toggle policies active/inactive
Via the API¶
# List all policies
curl https://mayoaspm.com/api/policies \
-H "Authorization: Bearer mayo_ak_..."
# Create a policy
curl -X POST https://mayoaspm.com/api/policies \
-H "Authorization: Bearer mayo_ak_..." \
-H "Content-Type: application/json" \
-d '{
"name": "reject-info-findings",
"kind": "triage",
"rego": "package mayo.triage\n\nimport rego.v1\n\ndecision := \"reject\" if {\n input.finding.severity == \"info\"\n}",
"active": true
}'
Key concepts¶
- Rego v1 syntax — Mayo ASPM uses Rego v1. See Writing Rego for syntax details.
- Input structure — each policy kind receives a specific
inputobject. See the individual kind references. - Scoping — policies can be scoped to the organization, a project, or a sub-project. See Scoping.
- Versioning — every edit creates a snapshot. See Versioning.
Next steps¶
- Getting started with policies — create your first policy
- Writing Rego for Mayo ASPM — syntax guide and examples
- Policy Playground — test policies interactively
- Best practices — patterns and anti-patterns