Authorization, OPA integration
Open Policy Agent for fine-grained authz
Open Policy Agent (OPA) is a general-purpose policy engine. Rego, its policy language, expresses authz decisions concisely. Pairs well with Olympus's auth.
Architecture
Your app
↓ "Can user X do action Y on resource Z?"
OPA (sidecar or library)
↓ evaluates Rego policy
↓ returns true/false (and reason)
Your app proceeds or deniesOPA doesn't authenticate (that's Olympus). It decides what authenticated users can do.
Deploy modes
A: Sidecar
OPA runs as a separate process; your app calls its HTTP API:
# Add to your compose
opa:
image: openpolicyagent/opa:latest
command: run --server --addr :8181 /policies
volumes:
- ./policies:/policies:roYour app posts:
const response = await fetch("http://opa:8181/v1/data/olympus/authz/allow", {
method: "POST",
body: JSON.stringify({
input: {
subject: { sub: session.id, role: session.role },
action: "delete",
resource: { id: doc.id, owner_id: doc.owner }
}
})
});
const { result } = await response.json();
if (!result) return Response.json({ error: "forbidden" }, { status: 403 });B: Embedded
Use OPA as a Go library, embed in your service. Lower latency than the sidecar, but couples policy and code lifecycle.
Example policy
policies/olympus.rego:
package olympus.authz
import future.keywords.if
default allow := false
# Owners always allowed
allow if {
input.subject.sub == input.resource.owner_id
}
# Admins can read anything
allow if {
input.subject.role == "admin"
input.action == "read"
}
# Department members can edit their own department's resources
allow if {
input.subject.department == input.resource.department
input.action in {"read", "write"}
}
# Deny if classified beyond clearance
allow := false if {
input.resource.classification == "secret"
input.subject.clearance_level < 3
}Policy testing
Rego is testable:
package olympus.authz_test
test_owner_can_delete if {
allow with input as {
"subject": {"sub": "alice"},
"action": "delete",
"resource": {"owner_id": "alice"}
}
}
test_non_owner_cannot_delete if {
not allow with input as {
"subject": {"sub": "bob", "role": "user"},
"action": "delete",
"resource": {"owner_id": "alice"}
}
}Run with opa test policies/.
Policy bundles
For production, distribute policies via OPA bundles:
- CI builds the bundle on every policy change.
- Bundle published to S3 / GCS / GitHub release.
- OPA polls the bundle URL; new policies hot-reload.
Changes propagate without restarting your app.
Decision logs
OPA can ship every decision to a sink (Kafka, HTTP, etc.). Useful for:
- Audit (every authz decision is recorded).
- Debugging ("why was this denied?", look at the decision log).
- Compliance (SOC 2 evidence).
Performance
OPA decision: ~10-100 microseconds typical. For most apps, this is below the noise floor.