Skip to main content

Policy Authoring

Well-structured Rego is easier to review in Git, test in CI, and promote through EnforceAuth environments. These conventions match what we see in enterprise Policy-as-Code repos.

Package layout

Organize by domain, not by team member:

policies/
├── authz/
│ ├── api.rego # HTTP / API authorization
│ ├── data.rego # data-layer rules
│ └── admin.rego # break-glass
├── data/
│ └── role_permissions.json
└── tests/
├── api_test.rego
└── data_test.rego

Set policy_path in the console to policies/ (or your root). See Policy sources.

Naming conventions

DoDon't
allow_read_billingrule7
deny_cross_tenant_accesstemp_fix
Package authz.apiSingle 2,000-line policy.rego

Rule names appear in decision logs and code review — make intent obvious.

Document the input contract

Every package should declare expected input fields in a colocated README or header comment:

# authz.api — expects input.user.id, input.user.roles,
# input.action, input.resource.type, input.resource.id

The PEP and PDP must agree on shape. EnforceAuth stores evaluated input in decision logs — consistent schemas speed up investigations.

Default deny

Start every package with:

default allow := false

Fail closed. Explicit deny rules override allow when you need compliance hard-stops — see Rego patterns.

No secrets in Rego

Never embed API keys, connection strings, or passwords in policy files. Use:

  • PIP (Policy Information Point) calls from OPA
  • EnforceAuth secrets for Git and cloud credentials referenced by policy sources
  • Bundle data.json for non-secret reference data only

Composition over copy-paste

Use import and shared helpers:

import data.authz.common.is_authenticated

allow if {
is_authenticated(input)
# domain-specific checks...
}

Duplicated logic drifts between files — one fix should not require editing twelve copies.

Review checklist (PR)

Before merging to the branch EnforceAuth deploys:

  1. opa test ./policies --verbose passes locally
  2. New rules have positive and negative test cases
  3. No broad allow if { true } without comment and ticket reference
  4. Input changes documented; PEP owners notified
  5. Bundle size impact considered (large data.json slows activation)

EnforceAuth runs tests in the Testing deployment phase — failing tests block promotion.

Console workflow

Authors with Git write access use Create Policy or Save as Draft — both open a PR. Reviewers merge; deployments publish the bundle.

Read-only contributors can still browse policies and propose changes via fork/PR outside the console.