Complete reference for integrating Predicate Authority with your Temporal.io workers.
pip install predicate-temporalThe Predicate Authority Sidecar must be running. See Sidecar and Operations for detailed setup.
Quick start:
# Docker (recommended)
docker run -d -p 8787:8787 ghcr.io/predicatesystems/predicate-authorityd:latest
# Or download binary
curl -fsSL https://github.com/PredicateSystems/predicate-authority-sidecar/releases/latest/download/predicate-authorityd-darwin-arm64.tar.gz | tar -xz
./predicate-authorityd --port 8787 --policy-file policy.jsonfrom temporalio.worker import Worker
from predicate_temporal import PredicateInterceptor
from predicate_authority import AuthorityClient
# Initialize the Predicate Authority client
ctx = AuthorityClient.from_env()
# Create the interceptor
interceptor = PredicateInterceptor(
authority_client=The interceptor sits in the Temporal activity execution pipeline:
action)AuthorityClient.authorize() to request a mandateThis ensures that no untrusted code or payload reaches your OS until it has been cryptographically authorized.
# Required for AuthorityClient.from_env()
export PREDICATE_AUTHORITY_POLICY_FILE=/path/to/policy.json
export PREDICATE_AUTHORITY_SIGNING_KEY=your-secret-key
export PREDICATE_AUTHORITY_MANDATE_TTL_SECONDS=300from predicate_temporal import PredicateInterceptor
from predicate_authority import AuthorityClient
interceptor = PredicateInterceptor(
# Required: The Predicate Authority client instance
authority_client=AuthorityClient.from_env().client,
# Optional: Principal ID (default: "temporal-worker")
principal="my-worker",| Parameter | Type | Required | Description |
|---|---|---|---|
authority_client / authorityClient | AuthorityClient | Yes | The Predicate Authority client instance |
principal | string | No | Principal ID for authorization requests (default: "temporal-worker") |
tenant_id / tenantId | string | No | Tenant ID for multi-tenant deployments |
session_id / sessionId | string | No | Session ID for request correlation and auditing |
When authorization is denied, the interceptor raises an error that propagates to the workflow:
from temporalio.exceptions import ActivityError, ApplicationError
try:
await workflow.execute_activity(
dangerous_activity,
args,
start_to_close_timeout=timedelta(seconds=30),
)Create a policy file that defines allowed and denied activities:
{
"rules": [
{
"name": "allow-safe-activities",
"effect": "allow",
"principals": ["temporal-worker"],
"actions": ["process_order", "send_notification", "fetch_data"],
"resources": ["*"]
},
{
"name": "deny-dangerous-activities",
"effect": "deny",
"principals": ["*"],
"actions": ["delete_*", "drop_*", "admin_*"],
"resources": ["*"]
}
]
}Starter policy packs: The sidecar repository includes ready-to-use policy templates for common use cases including Temporal workers, database access, and file system operations.
| Field | Description | Example |
|---|---|---|
name | Rule identifier for auditing | "deny-delete-operations" |
effect | "allow" or "deny" | "deny" |
principals | Worker principals this rule applies to | ["temporal-worker", "admin-worker"] |
actions | Activity names (glob patterns supported) | ["delete_", "drop_"] |
resources | Resource scopes (glob patterns supported) | ["*"] or ["db:orders", "db:users"] |
Here's a full example with workflow, activities, and interceptor:
# activities.py
from temporalio import activity
@activity.defn
async def process_order(order_id: str) -> dict:
"""Safe activity - allowed by policy."""
returnAll authorization decisions are logged by the sidecar. For production deployments, connect to the Predicate Control Plane for:
See Audit Logging & Provenance for configuration details.
| SDK | Repository | License |
|---|---|---|
| Python | temporal-predicate-py | MIT |
| TypeScript | temporal-predicate-typescript | MIT |