Hexr uses Open Policy Agent (OPA) to evaluate authorization decisions for every request your agents make to cloud services or platform APIs. Before any credential exchange happens, OPA checks whether the requesting agent’s SPIFFE identity is permitted to access the requested service. You write the rules in Rego, deploy them as Kubernetes ConfigMaps, and Hexr enforces them at runtime — without touching your agent code.
How OPA fits into the request flow
Every outbound request from an agent passes through Envoy, which calls OPA before forwarding:
Agent → Envoy → OPA (allow/deny?) → Credential Injector → Cloud STS
OPA receives the agent’s verified SPIFFE identity and the requested service, evaluates your Rego policies, and returns allow or deny. A denied request never reaches the credential exchange.
OPA receives this input for every request:
{
"spiffe_id": "spiffe://hexr.cloud/agent/acme-corp/content-crew/researcher",
"tenant": "acme-corp",
"agent": "content-crew",
"role": "researcher",
"service": "gcp_bigquery",
"action": "query",
"timestamp": "2026-01-15T10:30:00Z"
}
Your policies can use any combination of these fields to make access decisions.
Example policies
Service access by role
The most common pattern — control which roles can access which services:
package hexr.authz
default allow = false
# Researchers can access BigQuery and S3 (read-only)
allow {
input.role == "researcher"
input.service in {"gcp_bigquery", "aws_s3"}
}
# Writers can only write to S3
allow {
input.role == "writer"
input.service == "aws_s3"
input.action == "PutObject"
}
# Editors have no cloud access
# (implicitly denied by default allow = false)
Time-based access
Restrict access to business hours:
# Only allow access during business hours (UTC)
allow {
input.role == "researcher"
time.clock(time.now_ns())[0] >= 8 # After 8 AM
time.clock(time.now_ns())[0] < 18 # Before 6 PM
}
Rate limiting
Prevent runaway agents from exhausting your quota:
# Allow max 100 tool calls per minute per agent
allow {
count(recent_calls) < 100
}
recent_calls[call] {
call := data.audit_log[_]
call.agent == input.agent
call.timestamp > time.now_ns() - 60000000000 # 1 minute
}
Deploying policies
Policies deploy as Kubernetes ConfigMaps and reload within 30 seconds of an update. On self-hosted deployments, apply the ConfigMap directly to your cluster:
apiVersion: v1
kind: ConfigMap
metadata:
name: opa-policy
namespace: hexr-system # The namespace where Hexr runs
data:
policy.rego: |
package hexr.authz
default allow = false
allow {
input.role == "researcher"
input.service in {"gcp_bigquery", "aws_s3"}
}
On Hexr Cloud, manage policies through the dashboard or contact support to apply custom policies to your tenant.
Policy changes reload within 30 seconds. You don’t need to restart any agents or platform services when you update a policy.
Testing policies
Use OPA’s built-in test framework to validate your policies before deploying them:
test_researcher_bigquery_allowed {
allow with input as {
"role": "researcher",
"service": "gcp_bigquery",
"action": "query"
}
}
test_writer_bigquery_denied {
not allow with input as {
"role": "writer",
"service": "gcp_bigquery",
"action": "query"
}
}
Write tests for both allowed and denied cases. The default allow = false pattern means untested paths are implicitly denied — but explicit tests document your intent and catch regressions when you update policies.