Skip to main content

Policies

Reference for the declarative manifests that define Catalyst policies. For the conceptual story see Policies. For end-to-end usage see Resiliency and App IDs.

Policies are applied with the diagrid CLI. The target project is provided by the --project flag, not by a field in the manifest:

diagrid resiliency create -f resiliency.yaml --project my-project
diagrid configuration create -f configuration.yaml --project my-project

Manifest envelope

Every policy manifest shares the same top-level shape:

apiVersion: dapr.io/v1alpha1
kind: <Resiliency | Configuration>
metadata:
name: <policy-name>
scopes:
- <app-id-1>
- <app-id-2>
spec:
# ...kind-specific spec below
FieldTypeRequiredDescription
apiVersionstringyesMust be dapr.io/v1alpha1.
kindstringyesResiliency or Configuration.
metadata.namestringyesUnique policy name within the project.
scopesstring[]noApp IDs the policy applies to. Top-level (sibling of spec). Omit to leave the policy unbound.

Resiliency policy

A resiliency policy defines named retry, timeout, and circuit-breaker behaviours, then binds them to outbound calls by target.

Spec

spec:
policies:
timeouts:
<policy-name>: <duration>
retries:
<policy-name>:
policy: constant | exponential
duration: <duration>
maxInterval: <duration> # exponential only
maxRetries: <int> # -1 for unlimited
matching:
httpStatusCodes: "<comma-separated codes or ranges>"
gRPCStatusCodes: "<comma-separated codes>"
circuitBreakers:
<policy-name>:
maxRequests: <int>
interval: <duration>
timeout: <duration>
trip: "<CEL expression>"
targets:
apps:
<app-id>:
timeout: <timeout-policy-name>
retry: <retry-policy-name>
circuitBreaker: <circuit-breaker-policy-name>
circuitBreakerCacheSize: <int>
components:
<component-name>:
inbound:
timeout: <timeout-policy-name>
retry: <retry-policy-name>
circuitBreaker: <circuit-breaker-policy-name>
outbound:
timeout: <timeout-policy-name>
retry: <retry-policy-name>
circuitBreaker: <circuit-breaker-policy-name>

Retry policy fields

FieldTypeDescription
policyconstant | exponentialBackoff shape. Constant waits duration between attempts; exponential grows the wait up to maxInterval.
durationduration string (e.g. 5s)Wait between attempts (constant) or initial wait (exponential).
maxIntervalduration stringUpper bound on the wait for exponential policies. Ignored for constant.
maxRetriesintMaximum attempts after the initial call. -1 means retry indefinitely.
matching.httpStatusCodesstringComma-separated HTTP codes or ranges to retry, e.g. "500,501,502,503,504". Unmatched codes fail immediately.
matching.gRPCStatusCodesstringComma-separated gRPC status codes to retry, e.g. "14,4,8".

Circuit-breaker fields

FieldTypeDescription
maxRequestsintNumber of probe requests permitted while the breaker is half-open.
intervalduration stringSliding window over which failures are counted.
timeoutduration stringTime the breaker stays open before transitioning to half-open.
tripCEL expressionTrip condition. Evaluated against the variables below, e.g. "consecutiveFailures > 5".

The trip expression is evaluated as CEL with the following variables in scope:

VariableDescription
requestsTotal requests observed in the current window.
consecutiveFailuresConsecutive failures since the last success.
consecutiveSuccessesConsecutive successes since the last failure.
totalFailuresTotal failures in the current window.
totalSuccessesTotal successes in the current window.

Target fields

apps.<app-id> binds policies to outbound service invocations to that App ID. components.<component-name>.outbound binds policies to calls out to the component; inbound binds policies to deliveries from the component (for example pub/sub message delivery into the app).

Each target slot accepts the name of a policy defined in policies.timeouts, policies.retries, or policies.circuitBreakers. Bindings are optional; omit a slot to leave that dimension unbounded for the target.

circuitBreakerCacheSize (apps only) caps the number of per-instance breakers cached for that target.

Defaults

If you omit a dimension, Catalyst applies these defaults at the data plane:

DimensionDefault value
Timeout10s
Retryconstant, 5s between attempts, 5 retries, matching HTTP 500,501,502,503,504 and gRPC 14,4,8
Circuit breakermaxRequests: 1, interval: 5s, timeout: 20s, trip: consecutiveFailures > 5

Worked example

apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: order-service-resiliency
scopes:
- order-service
spec:
policies:
timeouts:
fastCall: 2s
retries:
transientRetry:
policy: exponential
duration: 200ms
maxInterval: 5s
maxRetries: 4
matching:
httpStatusCodes: "503,504"
gRPCStatusCodes: "14"
circuitBreakers:
defaultBreaker:
maxRequests: 1
interval: 30s
timeout: 60s
trip: "consecutiveFailures > 5"
targets:
apps:
inventory-service:
timeout: fastCall
retry: transientRetry
circuitBreaker: defaultBreaker
components:
orders-statestore:
outbound:
timeout: fastCall
retry: transientRetry
circuitBreaker: defaultBreaker

Configuration

A configuration sets App ID-level runtime behaviour: access control lists, HTTP pipelines, distributed tracing (private regions only), and workflow runtime parameters.

Spec

spec:
accessControl:
defaultAction: allow | deny
trustDomain: <trust-domain>
policies:
- appId: <caller-app-id>
defaultAction: allow | deny
trustDomain: <trust-domain>
namespace: <namespace>
operations:
- name: <operation-name>
httpVerb: ["GET", "POST", ...]
action: allow | deny
appHttpPipeline:
handlers:
- name: <middleware-name>
type: <middleware-type>
httpPipeline:
handlers:
- name: <middleware-name>
type: <middleware-type>
tracing: # private regions only
samplingRate: "<float-as-string>"
otel:
endpointAddress: <url>
isSecure: <bool>
protocol: <http | grpc>
workflow:
maxConcurrentWorkflowInvocations: <int>
maxConcurrentActivityInvocations: <int>

Field reference

FieldNotes
accessControlService-invocation ACLs. The top-level defaultAction applies when no per-caller policy matches. Per-caller policies[] can refine to specific operations and HTTP verbs.
appHttpPipelineMiddleware applied to traffic from the data plane to your application (inbound to the app).
httpPipelineMiddleware applied to traffic from your application out through the data plane (outbound).
tracingDistributed tracing config. Only honored on projects in private regions. samplingRate is a string between "0" and "1".
workflowTuning for the workflow runtime. Bounds concurrency for workflow and activity invocations.

Worked example

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: order-service-config
spec:
accessControl:
defaultAction: deny
trustDomain: public
policies:
- appId: api-gateway
defaultAction: deny
trustDomain: public
namespace: default
operations:
- name: /orders
httpVerb: ["POST"]
action: allow
workflow:
maxConcurrentWorkflowInvocations: 100
maxConcurrentActivityInvocations: 200

Applying and inspecting policies

# Apply or update
diagrid resiliency create -f resiliency.yaml --project <project>
diagrid resiliency update -f resiliency.yaml --project <project>
diagrid configuration create -f configuration.yaml --project <project>
diagrid configuration update -f configuration.yaml --project <project>

# Inspect
diagrid resiliency list --project <project>
diagrid resiliency get <name> --project <project>
diagrid configuration list --project <project>
diagrid configuration get <name> --project <project>

# Remove
diagrid resiliency delete <name> --project <project>
diagrid configuration delete <name> --project <project>

See the diagrid resiliency and diagrid configuration CLI references for the full flag set.

See also

  • Policies: conceptual overview.
  • Resiliency: retries, timeouts, and circuit breakers in depth.
  • App IDs: how policies are bound and managed day-2.