// Reading the shelf: Redline Fieldbook Atrium v1.0 · 2026-04
Documentation / Atrium · Policy /Policy/Rego How-to · 26 min

Authoring Rego policy bundles.

Disclosure decisions, access requests, ethical walls, and admin gates are all expressed in Rego, evaluated by an embedded OPA-compatible engine. Versioned, signed, and replayable.

TypeHow-to
Reading26 min
Revisedv1.0 · 2026-04
Applies toAtrium · all tiers

/ 01Why OPA / Rego

Authorisation logic in code is hard to audit, hard to change, and hard to prove correct. Rego separates policy from product: policies are declarative, expressed in a language designed for this, and live in a separate signed bundle.

Three properties matter:

  • Replayable — every decision logs the bundle version and inputs hash; identical inputs always produce identical outputs
  • Auditable — bundles are versioned in git, signed, deployed through a controlled endpoint
  • Performantregorus partial-evaluates hot paths; median decision < 2ms

/ 02Bundle layout

policies/
├── disclosure/
│   ├── ladder.rego              # L0..L6 enforcement
│   ├── ceiling.rego             # Classification ceilings per silo-pair
│   └── silo_pair.rego           # Sharing matrices
├── access_request/
│   ├── auto_grant.rego          # Eligibility for auto-approval
│   └── conflict_check.rego      # Pre-check on grant
├── ethical_wall/
│   └── deny.rego                # Absolute DENY (precedes everything)
├── admin/
│   ├── config_mutation.rego     # Who can change what
│   └── sub_processor.rego       # Sub-processor change controls
├── temporal/
│   ├── grant_expiry.rego
│   └── time_of_day.rego
└── lib/
    ├── helpers.rego             # Shared predicates
    └── inputs.rego              # Canonical input shape

/ 03Disclosure policies

The shape of a disclosure policy:

package disclosure

# Maximum disclosure level for this requester against this asset.
# Result is one of "L0".."L6".
max_level := level {
    not ethical_wall.recused
    not conflict_screen.applies
    level := compute_ceiling
}

# Default — if anything above fails, we deny.
default max_level := "L0"

compute_ceiling := level {
    base := ceiling[input.document.classification][input.requester.silo][input.document.silo]
    author := input.document.author_setting
    steward := input.document.steward_override
    level := min({base, author, steward})
}

Each module is small, single-purpose, and unit-tested with golden inputs.

/ 04Access-request policies

An access request goes through three gates: eligibility, conflict pre-check, approval.

package access_request

# Auto-approve when the requester is on the matter team
# and the requested level is <= L5.
auto_grant {
    input.requester.matter_assignments[_].matter_id == input.target.matter_id
    input.requested_level <= "L5"
    not conflict_check.fails
}

Manual-approval policies define who can approve: author by default, CRP for sensitive clients, group compliance for L6.

/ 05Ethical wall (absolute DENY)

Wall policies take precedence over everything. They are evaluated before disclosure ceilings, before clearances, before step-up. If a wall denies, nothing else matters.

package ethical_wall

# DENY — no override, no exception. The wall is the wall.
deny[reason] {
    matter := input.document.matter
    matter == input.requester.ethical_wall_recusals[_]
    reason := sprintf("Recused from matter %s", [matter])
}

deny[reason] {
    client := input.document.client
    client == input.requester.conflict_screens[_]
    reason := sprintf("Conflict screen on client %s", [client])
}

/ 06Signing & verification

Bundles are Ed25519-signed. The Atrium engine refuses to load an unsigned or invalid bundle.

  1. Compile

    opa build policies/ --bundle policies.tar.gz — produces a bundle

  2. Sign

    atrium policies sign policies.tar.gz --key signing.pem — emits policies.tar.gz.sig

  3. Deploy

    Upload both to the bundle endpoint; engines pull at the next reload tick and verify the signature before loading

  4. Verify in CI

    atrium policies verify policies.tar.gz --key signing.pub — required step in your deploy pipeline

/ 07Decision logs

Every decision is shipped to the audit log with:

  • bundle_version — e.g. atrium-policies@v3.2.1
  • decisionallow · deny · disclosure level
  • rule — the specific rule that fired
  • inputs_hash — SHA-256 of the canonical input (privacy-preserving)

Decisions are replayable: given the bundle and the inputs, you can re-evaluate locally and confirm the same outcome. This is the foundation of "what did the platform decide, and why" being a defensible answer.

Read carefully. Then begin.

Request access Back to documentation