WorkflowAccessPolicy spec
The WorkflowAccessPolicy is a Dapr resource that controls which applications can perform workflow operations (schedule, terminate, raise event, pause, resume, purge, get, rerun) and schedule activities cross-app on a target application. Policies are a pure allow-list: a call is permitted if any loaded rule matches.
Cross-namespace workflows are not supported
Workflows are always scoped to a single namespace. Cross-namespace workflow and activity calls are always denied, regardless of policy contents and regardless of whether any policy is loaded. All callers and targets in a multi-application workflow must be in the same namespace.Format
apiVersion: dapr.io/v1alpha1
kind: WorkflowAccessPolicy
metadata:
name: <REPLACE-WITH-NAME>
namespace: <NAMESPACE>
scopes:
- <TARGET-APP-ID>
spec:
rules:
- callers:
- appID: <CALLER-APP-ID>
workflows:
- name: <WORKFLOW-NAME-OR-GLOB-PATTERN>
operations: [schedule, terminate, raise, pause, resume, purge, get, rerun]
activities:
- name: <ACTIVITY-NAME-OR-GLOB-PATTERN>
Spec fields
Fields are listed in the order they appear in the YAML document.
| Field | Required | Type | Description | Example |
|---|---|---|---|---|
scopes | N | list | Target App IDs that this policy applies to. If omitted or empty, the policy applies to all applications. The policy is enforced on the callee (target) side. | ["order-service"] |
rules | N | list | Allow-list of rules. A call is permitted if any rule matches. If rules is omitted or empty while policies are loaded, all cross-app calls are denied. | See below |
rules[].callers | Y | list | List of caller objects that this rule applies to. Must contain at least one entry. | See below |
rules[].callers[].appID | Y | string | The Dapr App ID of the calling application. The caller must be in the same namespace as the target; cross-namespace workflow calls are always denied and are not supported. | frontend-app |
rules[].workflows | N* | list | Workflow rules granted to the matched callers. | See below |
rules[].workflows[].name | Y | string | Exact name or glob pattern of the workflow. Supports *, ?, and [abc] character classes. | OrderWF, Report* |
rules[].workflows[].operations | Y | list | Set of granted operations: schedule, terminate, raise, pause, resume, purge, get, rerun. Each operation is enforced when a cross-app caller invokes it against the named workflow. | [schedule, terminate] |
rules[].workflows[].requires | N | list | Optional ordered list of history events (max 20) that must all be present, in order, in the caller’s propagated history for the rule to apply. Only valid when the rule’s single operation is schedule. Requires history signing; with signing disabled a requires rule always denies. | See below |
rules[].activities | N* | list | Activity rules granted to the matched callers. Activities only support scheduling, so there is no operations field. | See below |
rules[].activities[].name | Y | string | Exact name or glob pattern of the activity. | ChargePayment, Refund* |
rules[].activities[].requires | N | list | Optional ordered list of history events (max 20) that must all be present, in order, in the caller’s propagated history for the rule to apply. Same entry shape as rules[].workflows[].requires. | See below |
rules[].workflows[].requires[].eventType | Y | string | The history event to match: one of activity.started, activity.completed, workflow.started, workflow.completed, event.raised. workflow.started matches a child workflow the caller scheduled, not its own execution. Activity requires entries use the same fields. | activity.completed |
rules[].workflows[].requires[].name | Y | string | The activity name (activity.*), child-workflow name (workflow.*), or external event name (event.raised). | fraud-check |
rules[].workflows[].requires[].appID | Y | string | The App ID that must have produced the event; the event only matches when it came from this app’s propagated history. | checkout |
* At least one of workflows or activities must be present in each rule.
The schema also sets size limits, so a large or generated policy can fail validation: rules, rules[].callers, rules[].workflows, and rules[].activities hold at most 100 entries each, operations holds at most 8, and each requires list holds at most 20. Every appID and name value is 1 to 256 characters. With the 1.19 CRD applied, the Kubernetes API server rejects a policy that breaks these limits. The sidecar also validates each policy against the same schema when it loads or reloads it, in both Kubernetes and self-hosted mode, and skips an invalid policy with a warning in its log.
Example
The policy below applies to the order-service application. It grants frontend-app and api-gateway permission to schedule OrderWF, CheckoutWF, and the ProcessPayment activity. A second rule grants admin-app permission to schedule any workflow or activity on order-service.
apiVersion: dapr.io/v1alpha1
kind: WorkflowAccessPolicy
metadata:
name: order-processing-policy
namespace: production
scopes:
- order-service
spec:
rules:
- callers:
- appID: frontend-app
- appID: api-gateway
workflows:
- name: OrderWF
operations: [schedule]
- name: CheckoutWF
operations: [schedule]
activities:
- name: ProcessPayment
- callers:
- appID: admin-app
workflows:
- name: "*"
operations: [schedule]
activities:
- name: "*"
Example with requires
This policy allows checkout to schedule the ChargeCard activity on payments-service only when checkout’s propagated history shows a completed fraud-check followed by a completed human-approval, both produced by checkout. requires needs history signing enabled.
apiVersion: dapr.io/v1alpha1
kind: WorkflowAccessPolicy
metadata:
name: payments-requires
namespace: production
scopes:
- payments-service
spec:
rules:
- callers:
- appID: checkout
activities:
- name: ChargeCard
requires:
- eventType: activity.completed
name: fraud-check
appID: checkout
- eventType: activity.completed
name: human-approval
appID: checkout