Skip to main content
CoreSDK
Authorization & Policy

Writing Rego Policies

Fine-grained authorization with OPA-compatible Rego (regorus engine).

Writing Rego Policies

CoreSDK embeds regorus — a Rust-native OPA-compatible Rego evaluator. Policies are written in .rego files, loaded from a directory, and hot-reloaded without a service restart.

Load a policy bundle

export CORESDK_POLICY_DIR=./policy

Or in coresdk.toml:

[sdk]
policy_dir = "./policy"

Policy input shape

The input object your Rego policy receives from evaluate_policy():

{
  "tenant_id":       "acme-corp",
  "subject":         "alice",
  "action":          "read",
  "resource":        "documents/doc-1",
  "resource_owner":  "alice",
  "resource_tenant": "acme-corp",
  "context": {
    "roles": ["viewer", "editor"]
  }
}

You control this shape — pass whatever you need:

_sdk.evaluate_policy("data.authz.allow", {
    "tenant_id":      tenant,
    "subject":        user.get("sub"),
    "action":         "read",
    "resource":       f"documents/{doc_id}",
    "resource_owner": doc["owner"],
    "context":        {"roles": user.get("roles", [])},
})

RBAC policy

# policy/authz.rego
package authz
import rego.v1

default allow := false

# Admin can do anything
allow if {
    "admin" in input.context.roles
}

# Editor can read, write, create, update
allow if {
    "editor" in input.context.roles
    input.action in {"read", "write", "create", "update"}
}

# Viewer can only read
allow if {
    "viewer" in input.context.roles
    input.action == "read"
}

ABAC policy

# policy/authz.rego — add to the RBAC rules above
package authz
import rego.v1

# Owner can always read/update their own resource
allow if {
    input.action in {"read", "update"}
    input.resource_owner == input.subject
}

# Editor in same tenant can manage
allow if {
    input.tenant_id == input.resource_tenant
    "editor" in input.context.roles
}

Tenant isolation policy

# policy/tenant_isolation.rego
package tenants
import rego.v1

default allowed := false

# Request's tenant must match the resource's tenant
allowed if {
    input.request_tenant == input.resource_tenant
}

Call from your app

# RBAC check
allowed = _sdk.evaluate_policy("data.authz.allow", {
    "tenant_id": "acme-corp",
    "subject":   "alice",
    "action":    "read",
    "resource":  "products/123",
    "context":   {"roles": ["viewer"]},
})

# Tenant isolation check
allowed = _sdk.evaluate_policy("data.tenants.allowed", {
    "request_tenant":  "acme-corp",
    "resource_tenant": "acme-corp",
})

Policy loading path

$CORESDK_POLICY_DIR/
  authz.rego              → evaluates as data.authz.*
  tenant_isolation.rego   → evaluates as data.tenants.*
  billing.rego            → evaluates as data.billing.*

Rules are addressed by package + rule name: data.<package>.<rule>.

Rego version

CoreSDK uses import rego.v1 (OPA 0.59+ syntax). Always add this at the top of your policies:

package authz
import rego.v1

default allow := false

Dry-run a policy

Test a policy without running the full app:

export CORESDK_POLICY_DIR=./policy

python -c "
from coresdk import CoreSDKClient, SDKConfig
sdk = CoreSDKClient(SDKConfig.from_env())
result = sdk.evaluate_policy('data.authz.allow', {
    'tenant_id': 'acme-corp',
    'subject':   'alice',
    'action':    'read',
    'resource':  'documents/doc-1',
    'resource_owner': 'alice',
    'context':   {'roles': ['viewer']},
})
print('allowed:', result)
"

Full working examples

On this page