Skip to main content

Policy Configuration

The Policy section controls how Synentra evaluates authorization policies.

Synentra supports multiple policy providers. The active provider is selected using DefaultProvider:

  • Internal — Loads policy definitions from local JSON files and evaluates them in-process.
  • Opa — Delegates policy decisions to an external Open Policy Agent (OPA) server.

Properties

PropertyTypeDefaultDescription
Enabledbool?trueEnable or disable policy evaluation globally
DefaultProviderstring"Internal"Active policy provider. Supported values: "Internal" or "Opa"
Providers.Internal.Directorystring""Directory containing internal JSON policy definitions
Providers.Opa.BaseUrlstring""Base URL of the OPA server
Providers.Opa.Pathstring"/v1/data/synentra/authz"OPA decision API path
Providers.Opa.TimeoutTimeSpan?00:00:05Timeout for OPA HTTP requests

Configuration Example

"Policy": {
"Enabled": true,
"DefaultProvider": "Internal",
"Providers": {
"Internal": {
"Directory": "./policies"
},
"Opa": {
"BaseUrl": "http://localhost:8181",
"Path": "/v1/data/synentra/authz",
"Timeout": "00:00:05"
}
}
}

Internal Provider

The Internal provider evaluates policies locally inside Synentra.

Policies are loaded from JSON files using FileSystemPolicyLoader.

Policy Directory

The configured directory can be either:

  • An absolute path.
  • A relative path resolved from the Synentra application directory.

Example:

"Internal": {
"Directory": "./policies"
}

Each policy file must:

  • Have a .json extension.
  • Contain a valid PolicyDefinition.
  • Define a unique policy Name.

Example directory:

policies/
├── customer-api.json
├── payment-service.json
└── admin-access.json

Policies are loaded automatically when required and cached in memory through the policy cache service.


Policy Evaluation

Internal policy evaluation follows these steps:

  1. Load the requested policy.
  2. Evaluate rules ordered by descending Priority.
  3. Evaluate all conditions inside a rule.
  4. Return the rule effect when all conditions match.
  5. If no rule matches, return the policy default effect.

Supported policy effects:

EffectDescription
AllowRequest is permitted
DenyRequest is rejected
HitlRequest requires human approval

Example rule flow:

Policy
├── Rule (Priority: 100)
│ ├── Condition 1
│ ├── Condition 2
│ └── Effect: Allow

├── Rule (Priority: 50)
│ └── Effect: Hitl

└── Default: Deny

Supported Condition Operators

The internal evaluator supports the following operators:

OperatorDescription
eqEqual comparison
neNot equal comparison
gtGreater than
ltLess than
geGreater than or equal
leLess than or equal
inValue exists in collection
containsString or collection contains value
startswithString prefix match
endswithString suffix match
regexRegular expression match

Conditions support nested input properties:

{
"field": "agent.trustScore",
"operator": "ge",
"value": 80
}

Policy Examples

A collection of ready-to-use policy files for common governance scenarios.

Read-Only Agent

Blocks any mutating HTTP methods.

policies/read-only.json
{
"name": "read-only",
"description": "Agent may only perform read operations",
"owner": "platform-team",
"default": "Deny",
"rules": [
{
"name": "allow-reads",
"priority": 10,
"effect": "Allow",
"conditions": [
{ "field": "input.method", "operator": "in", "value": ["GET", "HEAD", "OPTIONS"] }
]
}
]
}

Delete Requires Human Approval

All DELETE requests are held for human review.

policies/safe-delete.json
{
"name": "safe-delete",
"description": "Deletes require manual approval",
"owner": "security-team",
"default": "Allow",
"rules": [
{
"name": "hitl-on-delete",
"reason": "Deletion requires human approval",
"priority": 100,
"effect": "Hitl",
"conditions": [
{ "field": "input.method", "operator": "eq", "value": "DELETE" }
]
}
]
}

Block Admin Endpoints

Denies access to paths containing /admin/.

policies/no-admin.json
{
"name": "no-admin",
"description": "Agents may not access admin endpoints",
"owner": "security-team",
"default": "Allow",
"rules": [
{
"name": "deny-admin-paths",
"reason": "Admin access is restricted",
"priority": 100,
"effect": "Deny",
"conditions": [
{ "field": "input.path", "operator": "regex", "value": "/admin/" }
]
}
]
}

Low-Trust Agent Policy

Routes low-trust-score agents to HITL for any write operations.

policies/low-trust.json
{
"name": "low-trust",
"description": "Extra scrutiny for low-trust agents",
"owner": "security-team",
"default": "Allow",
"rules": [
{
"name": "hitl-writes-for-low-trust",
"reason": "Low trust score — write requires approval",
"priority": 50,
"effect": "Hitl",
"conditions": [
{ "field": "input.trustScore", "operator": "lt", "value": 0.4 },
{ "field": "input.method", "operator": "in", "value": ["POST", "PUT", "PATCH", "DELETE"] }
]
}
]
}

Bulk-Export HITL + Delete Deny

Combines multiple rules at different priorities.

policies/data-agent.json
{
"name": "data-agent",
"description": "Governs a data-pipeline agent",
"owner": "data-team",
"default": "Deny",
"rules": [
{
"name": "deny-delete",
"reason": "Data agents may not delete",
"priority": 200,
"effect": "Deny",
"conditions": [
{ "field": "input.method", "operator": "eq", "value": "DELETE" }
]
},
{
"name": "hitl-bulk-export",
"reason": "Bulk operations require approval",
"priority": 150,
"effect": "Hitl",
"conditions": [
{ "field": "input.path", "operator": "regex", "value": "/export|/bulk|/dump" }
]
},
{
"name": "allow-reads",
"priority": 10,
"effect": "Allow",
"conditions": [
{ "field": "input.method", "operator": "in", "value": ["GET", "HEAD"] }
]
},
{
"name": "allow-standard-writes",
"priority": 5,
"effect": "Allow",
"conditions": [
{ "field": "input.method", "operator": "in", "value": ["POST", "PUT", "PATCH"] }
]
}
]
}

OPA Provider

The OPA provider delegates policy evaluation to an external Open Policy Agent service.

"Policy": {
"Enabled": true,
"DefaultProvider": "Opa",
"Providers": {
"Opa": {
"BaseUrl": "http://localhost:8181",
"Path": "/v1/data/synentra/authz",
"Timeout": "00:00:05"
}
}
}

Synentra sends the evaluation input to OPA:

{
"input": {
"agentId": "agent-123",
"method": "POST",
"path": "/api/payment",
"policyName": "payment-policy"
}
}

The configured OPA endpoint is called using:

POST {BaseUrl}{Path}

Example:

POST http://localhost:8181/v1/data/synentra/authz

OPA Response Format

OPA responses can return multiple formats.

Boolean Response

Allow:

{
"result": true
}

Deny:

{
"result": false
}

Effect Response

OPA can return an explicit decision:

{
"result": {
"effect": "hitl",
"reason": "Additional approval required"
}
}

Supported effects:

EffectResult
allowAllow request
hitlRequire human approval
Any other valueDeny request

Extended Response

OPA may also return:

{
"result": {
"allow": true,
"reason": "Trusted agent"
}
}

or:

{
"result": {
"hitl": true,
"reason": "Sensitive operation"
}
}

Policy Cache

Synentra caches loaded policies to avoid reading policy files or querying providers repeatedly.

Cached data includes:

  • Loaded internal policy definitions.
  • Evaluated policy lookup data.

When the cache does not contain policies, Synentra reloads them using the configured policy loader.

Disabling Policy Evaluation

Set Enabled to false to disable policy evaluation globally.

"Policy": { "Enabled": false }

When disabled:

  • Policy evaluation is skipped.
  • Other request processing features continue to execute normally.

Provider Selection

The active provider is controlled by DefaultProvider.

Internal evaluation:

{
"DefaultProvider": "Internal"
}

OPA evaluation:

{
"DefaultProvider": "Opa"
}

If OPA is selected but no BaseUrl is configured, Synentra denies the request and logs the configuration issue.

Was this helpful?