Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,44 @@ Temporal.io Worker Interceptor for Predicate Authority Zero-Trust authorization.

This package provides a pre-execution security gate for all Temporal Activities, enforcing cryptographic authorization mandates before any activity code runs.

## Prerequisites
## Sidecar Prerequisite

This package requires the **Predicate Authority Sidecar** daemon to be running. The sidecar is a lightweight Rust binary that handles policy evaluation and mandate signing.
This package requires the **Predicate Authority Sidecar** daemon to be running. The sidecar is a high-performance Rust binary that handles policy evaluation and mandate signing locally—no data leaves your infrastructure.

| Resource | Link |
|----------|------|
| Sidecar Repository | [github.com/PredicateSystems/predicate-authority-sidecar](https://github.com/PredicateSystems/predicate-authority-sidecar) |
| Sidecar Repository | [predicate-authority-sidecar](https://github.com/PredicateSystems/predicate-authority-sidecar) |
| Download Binaries | [Latest Releases](https://github.com/PredicateSystems/predicate-authority-sidecar/releases) |
| License | MIT / Apache 2.0 |

### Quick Sidecar Setup

**Option A: Docker (Recommended)**
```bash
# Download the latest release for your platform
# Linux x64, macOS x64/ARM64, Windows x64 available
docker run -d -p 8787:8787 ghcr.io/predicatesystems/predicate-authorityd:latest
```

# Extract and run
tar -xzf predicate-authorityd-*.tar.gz
**Option B: Download Binary**
```bash
# macOS (Apple Silicon)
curl -fsSL https://github.com/PredicateSystems/predicate-authority-sidecar/releases/latest/download/predicate-authorityd-darwin-arm64.tar.gz | tar -xz
chmod +x predicate-authorityd
./predicate-authorityd --port 8787 --policy-file policy.json

# Start with a policy file
# Linux x64
curl -fsSL https://github.com/PredicateSystems/predicate-authority-sidecar/releases/latest/download/predicate-authorityd-linux-x64.tar.gz | tar -xz
chmod +x predicate-authorityd
./predicate-authorityd --port 8787 --policy-file policy.json
```

See [all platform binaries](https://github.com/PredicateSystems/predicate-authority-sidecar/releases) for Linux ARM64, macOS Intel, and Windows.

**Verify it's running:**
```bash
curl http://localhost:8787/health
# {"status":"ok"}
```

## Installation

```bash
Expand Down
21 changes: 21 additions & 0 deletions examples/demo/Dockerfile.demo
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Demo application container
FROM python:3.11-slim

WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# Copy pyproject.toml and install dependencies
COPY pyproject.toml ./
RUN pip install --no-cache-dir .

# Copy source code
COPY src/ ./src/
COPY examples/demo/ ./examples/demo/

# Set Python path
ENV PYTHONPATH=/app/src

# Run the demo
CMD ["python", "examples/demo/demo.py"]
25 changes: 25 additions & 0 deletions examples/demo/Dockerfile.sidecar
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Predicate Authority Sidecar container
FROM debian:bookworm-slim

# Install curl for downloading binary and health checks
RUN apt-get update && apt-get install -y curl ca-certificates && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Detect architecture and download appropriate binary
ARG TARGETARCH
RUN ARCH=$(echo ${TARGETARCH:-$(uname -m)} | sed 's/amd64/x64/' | sed 's/x86_64/x64/' | sed 's/aarch64/arm64/') && \
echo "Detected architecture: $ARCH" && \
curl -fsSL -o /tmp/sidecar.tar.gz \
"https://github.com/PredicateSystems/predicate-authority-sidecar/releases/latest/download/predicate-authorityd-linux-${ARCH}.tar.gz" && \
tar -xzf /tmp/sidecar.tar.gz -C /usr/local/bin && \
chmod +x /usr/local/bin/predicate-authorityd && \
rm /tmp/sidecar.tar.gz

# Copy policy file
COPY examples/demo/policy.demo.json /app/policy.json

EXPOSE 8787

# Run sidecar
CMD ["predicate-authorityd", "--host", "0.0.0.0", "--port", "8787", "--mode", "local_only", "--policy-file", "/app/policy.json", "--log-level", "info", "run"]
197 changes: 197 additions & 0 deletions examples/demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Predicate Temporal Demo: Hack vs Fix

**See how Predicate Authority blocks dangerous Temporal activities in real-time.**

This demo shows Temporal workflows attempting to:
1. Process a legitimate order (allowed)
2. Delete an order (blocked)
3. Override payment as admin (blocked)
4. Drop the database (blocked)

## Quick Start

```bash
git clone https://github.com/PredicateSystems/predicate-temporal
cd predicate-temporal/examples/demo
./start-demo-native.sh
```

That's it. The script starts Temporal and runs the demo with local policy evaluation.

## What You'll See

```
========================================
PREDICATE TEMPORAL: Hack vs Fix Demo
========================================

Temporal: localhost:7233
Policy: /path/to/policy.demo.json

Connecting to Temporal...
Connected!

──────────────────────────────────────────────────────────────────────
[1/4] Legitimate Order Processing
Activity: check_inventory, charge_payment, send_confirmation
Expected: ALLOWED

✓ ALLOWED (245ms)
Reason: Order completed: txn-ORD-1234

──────────────────────────────────────────────────────────────────────
[2/4] Delete Order Attack
Activity: delete_order
Expected: BLOCKED

✗ BLOCKED (18ms)
Reason: deny-delete-operations

──────────────────────────────────────────────────────────────────────
[3/4] Admin Override Attack
Activity: admin_override_payment
Expected: BLOCKED

✗ BLOCKED (15ms)
Reason: deny-admin-operations

──────────────────────────────────────────────────────────────────────
[4/4] Drop Database Attack
Activity: drop_database
Expected: BLOCKED

✗ BLOCKED (12ms)
Reason: deny-drop-operations

======================================================================

Demo Complete!

Results:
✓ Legitimate activities executed successfully
✗ 3 dangerous activities blocked by Predicate Authority

All authorization decisions made in real-time by Predicate Authority.
Zero code changes needed in your activities.

======================================================================
```

## How It Works

```
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ Temporal │───▶│ Predicate │───▶│ Sidecar │
│ Worker │ │ Interceptor │ │ (policy) │
│ │ │ │ │ │
│ activity: │ │ action: │ │ DENY or │
│ delete_order│ │ delete_order │ │ ALLOW │
└─────────────┘ └──────────────────┘ └─────────────┘
PermissionError
(Activity never runs)
```

1. Temporal dispatches an activity to the worker
2. **Before** the activity code runs, the `PredicateInterceptor` extracts the activity name
3. The interceptor calls the sidecar's `/v1/authorize` endpoint
4. Decision returned in <25ms
5. DENY = raise `PermissionError`, ALLOW = execute activity

## Key Properties

| Property | Value |
|----------|-------|
| **Deterministic** | Policy-based rules, not probabilistic |
| **Fast** | p50 < 25ms authorization latency |
| **Auditable** | Every decision logged with mandate ID |
| **Fail-closed** | Sidecar errors block execution |
| **Zero code changes** | Activities don't need modification |

## Customize the Policy

Edit `policy.demo.json` to add your own rules:

```json
{
"rules": [
{
"name": "deny-dangerous-ops",
"effect": "deny",
"principals": ["*"],
"actions": ["delete_*", "drop_*", "admin_*"],
"resources": ["*"]
},
{
"name": "allow-order-processing",
"effect": "allow",
"principals": ["temporal-worker"],
"actions": ["check_inventory", "charge_payment", "send_confirmation"],
"resources": ["*"]
}
]
}
```

Then re-run `./start-demo.sh`.

## Requirements

- Docker (with Docker Compose)

No other dependencies. Everything runs in containers.

## Native Mode (No Docker)

If you prefer to run without Docker:

```bash
./start-demo-native.sh
```

This requires:
- Python 3.11+
- Temporal CLI (`brew install temporal`)
- Predicate sidecar binary (auto-downloaded)

## Install in Your Project

```bash
pip install predicate-temporal predicate-authority
```

```python
from temporalio.worker import Worker
from predicate_temporal import PredicateInterceptor
from predicate_authority import AuthorityClient

# Initialize Predicate Authority
ctx = AuthorityClient.from_sidecar(sidecar_url="http://localhost:8787")

# Create the interceptor
interceptor = PredicateInterceptor(
authority_client=ctx.client,
principal="temporal-worker",
)

# Create worker with the interceptor
worker = Worker(
client=temporal_client,
task_queue="my-task-queue",
workflows=[MyWorkflow],
activities=[my_activity],
interceptors=[interceptor], # <-- This is all you need
)
```

## Links

- [GitHub: predicate-temporal](https://github.com/PredicateSystems/predicate-temporal)
- [PyPI: predicate-temporal](https://pypi.org/project/predicate-temporal/)
- [Predicate Authority SDK (Python)](https://github.com/PredicateSystems/predicate-authority)
- [Predicate Authority Sidecar](https://github.com/PredicateSystems/predicate-authority-sidecar)

## License

MIT / Apache 2.0
Loading