Skip to main content

Policy Engine

The policy module decides whether a request should be:

  • allow
  • approval_required
  • deny

How decisions are evaluated​

Policies are created in the dashboard with a simple rule builder. The API stores each policy as a JSON rule object.

This module sits inside the Governance Decisions part of the product architecture.

How it works​

  1. A client sends a request to /v1/evaluate or /v1/proxy/evaluate. The Console playground uses /v1/playground/decision and is not an application contract.
  2. The engine loads the asset's active policies.
  3. It evaluates every policy's condition against the request.
  4. Among the policies that match, the most restrictive outcome wins: deny beats approval_required beats allow.
  5. If no policy matches, the engine returns allow with reason no_matching_policy.
  6. If a policy is invalid, the API returns a clear validation error.

Governance is opt-in: an asset with no policies attached allows every request. Add a policy for any workflow you want restricted or reviewed. Before you author a policy, define the assets and groups that describe the workflow you want to govern.

Where this module fits​

  • Identity and workspace provides the user and organization context.
  • Inventory provides the assets and groups used by policies.
  • Approvals and delivery records the result when a request needs review, and covers how customers choose sync, retry, or webhook delivery.

Rule model​

Simple rule​

{
"field": "amount",
"operator": ">",
"value": 5000
}

Composite rule​

{
"all": [
{
"field": "amount",
"operator": ">",
"value": 5000
},
{
"field": "environment",
"operator": "=",
"value": "production"
}
]
}

Supported operators:

  • =
  • !=
  • >
  • >=
  • <
  • <=
  • in
  • not_in
  • contains

Request context fields​

Policy conditions can address distinct namespaces so rules can tell trusted identity from application-supplied data:

  • asset.id, asset.key, asset.application, asset.service, and asset.environment identify the governed asset.
  • principal.kind, principal.id, principal.role, and principal.attributes.<claim> come from authenticated server or adapter context, not from metadata.
  • transport.http.method, transport.http.path, transport.http.host, transport.http.scheme, transport.http.route_id, and allowlisted transport.http.headers.<name> describe HTTP requests.
  • transport.grpc.full_method, transport.grpc.service, transport.grpc.method, transport.grpc.rpc_type, transport.grpc.route_id, and allowlisted transport.grpc.metadata.<name> describe gRPC calls.
  • metadata.<path> addresses application context supplied with the authorization request.

A transport-specific field is nonmatching when the request uses another transport. For example, an HTTP request cannot match a transport.grpc.* condition. Principal fields are populated only from trusted authentication context; values in metadata.actor or similar application fields are not authenticated identities.

Authoring flow​

  1. Choose an asset.
  2. Confirm the action.
  3. Choose the decision result.
  4. Add one or more rule rows.
  5. Pick a field, operator, and value.
  6. Save the policy.

You can start from an existing policy if you want a template for a similar workflow.

Example​

Policy:

  • Name: Require approval for high-value payments
  • Action: payment.execute
  • Rule: amount > 5000
  • Decision: approval_required

Request:

{
"workflow": "invoice-payment",
"asset": "invoice-agent",
"action": "payment.execute",
"amount": 12000,
"metadata": {
"environment": "production"
}
}

Expected result:

  • decision: approval_required
  • reason: policy matched

Best practices​

  • Start with narrow rules by action.
  • Prefer approval_required for risky operations.
  • Keep metadata keys consistent, for example environment, riskLevel, or vendor.
  • Test new policies in Decision Playground before using them broadly.