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
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Alert event emission for `injection_blocked`, `rate_limit_exceeded`, and `scan_error`
- Generic webhook sink with optional Bearer token and Slack Incoming Webhook sink
- Alerting config/env surface: `alerting.*` and `PIF_ALERTING_*`
- **Phase 3 Step 4 -- PagerDuty Sink (Trigger-only)**
- PagerDuty Events API v2 sink integration with sequential fail-open dispatch
- Trigger payload mapping with severity conversion and full `custom_details` projection
- Config/env surface for `alerting.pagerduty.*` and `PIF_ALERTING_PAGERDUTY_*`
- **Phase 3 Full Closure -- Multi-tenant + Replay/Forensics + Community Marketplace**
- Tenant-aware runtime policy resolution via `X-PIF-Tenant` with per-tenant action/threshold/rate-limit/adaptive overrides
- Replay/forensics local JSONL store with rotation, redaction, dashboard list/detail/rescan APIs
- Dashboard replay panel and tenant breakdown in summary/metrics views
- Community marketplace CLI (`pif marketplace list|install|update`) with checksum-verified installs
- Rule loader support for directory-based custom paths and marketplace source metadata in dashboard rule inventory
- Config/env surface additions:
- `tenancy.*` / `PIF_TENANCY_*`
- `replay.*` / `PIF_REPLAY_*`
- `marketplace.*` / `PIF_MARKETPLACE_*`

## [1.2.0] - 2026-03-07

Expand Down
104 changes: 98 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ PIF addresses this critical gap by providing a **transparent, low-latency detect
- **Health check endpoint** (`/healthz`)
- **Prometheus metrics endpoint** (`/metrics`)
- **Embedded monitoring dashboard + custom rule management** (`/dashboard`, optional)
- **Real-time alerting (Webhook + Slack)** with async fail-open delivery
- **Real-time alerting (Webhook + Slack + PagerDuty)** with async fail-open delivery
- **Multi-tenant runtime policies** via `X-PIF-Tenant` + config map
- **Replay/forensics capture** with local JSONL store and dashboard rescan
- **Community rule marketplace** (`pif marketplace list|install|update`)
- **golangci-lint** and race-condition-tested CI

</td>
Expand Down Expand Up @@ -171,7 +174,7 @@ prompt-injection-firewall/
│ ├── firewall/ # Backward-compatible CLI/proxy binary entry point
│ └── webhook/ # Kubernetes validating admission webhook binary
├── internal/
│ └── cli/ # CLI commands (scan, proxy, rules, version)
│ └── cli/ # CLI commands (scan, proxy, rules, marketplace, version)
├── pkg/
│ ├── detector/ # Detection engine (regex, ML/ONNX, ensemble, types)
│ ├── proxy/ # HTTP reverse proxy, middleware, API adapters
Expand Down Expand Up @@ -402,6 +405,19 @@ pif rules list
pif rules validate rules/
```

### Marketplace Commands

```bash
# List available community packages
pif marketplace list

# Install a specific package version
pif marketplace install community-rule@1.2.0

# Update installed packages to latest available versions
pif marketplace update
```

---

## Proxy Mode
Expand Down Expand Up @@ -551,17 +567,84 @@ alerting:
timeout: "3s"
max_retries: 3
backoff_initial_ms: 200
pagerduty:
enabled: false
url: "https://events.pagerduty.com/v2/enqueue"
routing_key: "" # PagerDuty Events API v2 routing key
timeout: "3s"
max_retries: 3
backoff_initial_ms: 200
source: "prompt-injection-firewall"
component: "proxy"
group: "pif"
class: "security"

# Note:
# - Alert delivery is async and fail-open: request path is never blocked by sink failures.
# - Initial event scope: block, rate-limit, and scan-error.
# - PagerDuty sink uses trigger-only Events API v2 payloads in this phase.

# Multi-tenant policy overrides (optional)
tenancy:
enabled: false
header: "X-PIF-Tenant"
default_tenant: "default"
tenants:
default:
policy:
action: "block"
threshold: 0.5
rate_limit:
requests_per_minute: 120
burst: 30
adaptive_threshold:
enabled: true
min_threshold: 0.25
ewma_alpha: 0.2
staging:
policy:
action: "flag"
threshold: 0.7
rate_limit:
requests_per_minute: 300
burst: 60

# Attack replay & forensics (optional)
replay:
enabled: false
storage_path: "data/replay/events.jsonl"
max_file_size_mb: 50
max_files: 5
capture_events:
block: true
rate_limit: true
scan_error: true
flag: true
redact_prompt_content: true
max_prompt_chars: 512

# Community marketplace (optional)
marketplace:
enabled: false
index_url: ""
cache_dir: ".cache/pif-marketplace"
install_dir: "rules/community"
refresh_interval_minutes: 60
require_checksum: true

# Notes:
# - Replay storage is local JSONL with size-based rotation.
# - `POST /api/dashboard/replays/{id}/rescan` re-evaluates captured prompts locally (no upstream call).
# - Marketplace install writes YAML files under `install_dir`; keep that path in `rules.custom_paths` or enable marketplace in proxy runtime.

# Rule file paths
rules:
paths:
- "rules/owasp-llm-top10.yaml"
- "rules/jailbreak-patterns.yaml"
- "rules/data-exfil.yaml"
custom_paths:
- "rules/community" # Marketplace installs and custom rule sets

# Allowlist (bypass scanning)
allowlist:
Expand Down Expand Up @@ -597,6 +680,15 @@ PIF_ALERTING_WEBHOOK_URL=https://alerts.example.com/pif
PIF_ALERTING_WEBHOOK_AUTH_BEARER_TOKEN=replace-me
PIF_ALERTING_SLACK_ENABLED=true
PIF_ALERTING_SLACK_INCOMING_WEBHOOK_URL=https://hooks.slack.com/services/T000/B000/XXX
PIF_ALERTING_PAGERDUTY_ENABLED=true
PIF_ALERTING_PAGERDUTY_ROUTING_KEY=replace-with-routing-key
PIF_ALERTING_PAGERDUTY_SOURCE=prompt-injection-firewall
PIF_TENANCY_ENABLED=true
PIF_TENANCY_HEADER=X-PIF-Tenant
PIF_REPLAY_ENABLED=true
PIF_REPLAY_STORAGE_PATH=data/replay/events.jsonl
PIF_MARKETPLACE_ENABLED=true
PIF_MARKETPLACE_INDEX_URL=https://example.com/index.json
PIF_LOGGING_LEVEL=debug
```

Expand Down Expand Up @@ -740,10 +832,10 @@ Automated quality gates on every push and pull request:
- [x] Web-based read-only dashboard UI for monitoring (MVP)
- [x] Dashboard rule management (write/edit workflows)
- [x] Real-time alerting: Webhook + Slack (MVP)
- [ ] Real-time alerting: PagerDuty sink
- [ ] Multi-tenant support with per-tenant policies
- [ ] Attack replay and forensic analysis tools
- [ ] Community rule marketplace
- [x] Real-time alerting: PagerDuty sink (trigger-only MVP)
- [x] Multi-tenant support with per-tenant policies
- [x] Attack replay and forensic analysis tools
- [x] Community rule marketplace

---

Expand Down
38 changes: 38 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,44 @@ alerting:
timeout: "3s"
max_retries: 3
backoff_initial_ms: 200
pagerduty:
enabled: false
url: "https://events.pagerduty.com/v2/enqueue"
routing_key: ""
timeout: "3s"
max_retries: 3
backoff_initial_ms: 200
source: "prompt-injection-firewall"
component: "proxy"
group: "pif"
class: "security"

tenancy:
enabled: false
header: "X-PIF-Tenant"
default_tenant: "default"
tenants: {}

replay:
enabled: false
storage_path: "data/replay/events.jsonl"
max_file_size_mb: 50
max_files: 5
capture_events:
block: true
rate_limit: true
scan_error: true
flag: true
redact_prompt_content: true
max_prompt_chars: 512

marketplace:
enabled: false
index_url: ""
cache_dir: ".cache/pif-marketplace"
install_dir: "rules/community"
refresh_interval_minutes: 60
require_checksum: true

webhook:
listen: ":8443"
Expand Down
131 changes: 130 additions & 1 deletion docs/API_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ Delivery model:
- Async queue + worker dispatcher
- Retry with exponential backoff and jitter
- Fail-open behavior (delivery failure never blocks proxy request handling)
- Sink execution order is sequential (`webhook` then `slack` when both are enabled)
- Sink execution order is sequential (`webhook` -> `slack` -> `pagerduty` when enabled)

Supported sinks:

- Generic webhook (`alerting.webhook.*`)
- Slack Incoming Webhook (`alerting.slack.*`)
- PagerDuty Events API v2 (`alerting.pagerduty.*`)

Generic webhook sends JSON payloads with the following contract:

Expand Down Expand Up @@ -92,6 +93,45 @@ Notes:
- `aggregate_count` is used by aggregated events (`rate_limit_exceeded`, `scan_error`).
- When configured, webhook sink sends `Authorization: Bearer <token>`.

PagerDuty sink sends trigger-only Events API v2 payloads:

```json
{
"routing_key": "your-routing-key",
"event_action": "trigger",
"payload": {
"summary": "pif injection_blocked action=block path=/v1/chat/completions reason=blocked_by_policy",
"source": "prompt-injection-firewall",
"severity": "critical",
"timestamp": "2026-03-08T01:02:03Z",
"component": "proxy",
"group": "pif",
"class": "security",
"custom_details": {
"event_id": "evt-1741395723000000000-1",
"event_type": "injection_blocked",
"action": "block",
"client_key": "203.0.113.10",
"method": "POST",
"path": "/v1/chat/completions",
"target": "https://api.openai.com",
"score": 0.92,
"threshold": 0.5,
"findings_count": 2,
"reason": "blocked_by_policy",
"aggregate_count": 1,
"sample_findings": []
}
}
}
```

PagerDuty severity mapping:

- `injection_blocked` -> `critical`
- `scan_error` -> `error`
- `rate_limit_exceeded` -> `warning`

### Embedded Dashboard (Optional)

When `dashboard.enabled=true`, PIF exposes a monitoring dashboard:
Expand All @@ -101,12 +141,18 @@ GET /dashboard
GET /api/dashboard/summary
GET /api/dashboard/metrics
GET /api/dashboard/rules
GET /api/dashboard/replays
GET /api/dashboard/replays/{id}
POST /api/dashboard/replays/{id}/rescan
```

- `GET /dashboard` serves embedded HTML/CSS/JS.
- `GET /api/dashboard/summary` returns high-level counters, uptime, p95 scan latency, and a safe runtime config snapshot.
- `GET /api/dashboard/metrics` returns normalized JSON metrics for UI polling (totals, label breakdowns, quantiles).
- `GET /api/dashboard/rules` returns loaded rule set metadata plus managed custom rules.
- `GET /api/dashboard/replays` returns replay event list (`tenant`, `event_type`, `decision`, `payload_hash`, findings, request metadata).
- `GET /api/dashboard/replays/{id}` returns full replay record.
- `POST /api/dashboard/replays/{id}/rescan` rescans captured prompts with the current detector (no upstream forwarding).

If `dashboard.auth.enabled=true`, both UI and dashboard API endpoints require Basic Auth and return:

Expand Down Expand Up @@ -156,6 +202,89 @@ Notes:
- `severity` is integer `0..4` (`info..critical`).
- Built-in OWASP/jailbreak/data-exfil files are not edited via dashboard.
- Dashboard writes only to managed custom rules and applies changes with hot reload.
- Rule-set response includes source metadata (`source`, `path`, optional marketplace metadata).

### Replay / Forensics API (Optional)

Replay API is available only when both `dashboard.enabled=true` and `replay.enabled=true`.

Behavior:

- `dashboard.enabled=false` -> all dashboard routes return `404`.
- `replay.enabled=false` -> replay routes return `404`.
- If dashboard auth is enabled, replay routes require Basic Auth.

Replay event schema (JSONL-backed):

```json
{
"replay_id": "rpl_1741395723000000000_1",
"timestamp": "2026-03-08T01:30:45Z",
"tenant": "default",
"event_type": "block",
"decision": "block",
"score": 0.91,
"threshold": 0.50,
"findings": [],
"request_meta": {
"method": "POST",
"path": "/v1/chat/completions",
"target": "https://api.openai.com",
"client_key": "203.0.113.10"
},
"payload_hash": "sha256-hex",
"prompts": [
{
"role": "user",
"text": "ignore all previous instructions",
"truncated": false,
"redacted": true
}
]
}
```

Captured replay event types:

- `block`
- `rate_limit`
- `scan_error`
- `flag`

### Multi-Tenant Runtime Policy (Optional)

When `tenancy.enabled=true`, request policy can be resolved from `tenancy.header` (default `X-PIF-Tenant`) with fallback to `tenancy.default_tenant`.

Per-tenant policy override surface:

- `action`
- `threshold`
- `rate_limit.requests_per_minute`
- `rate_limit.burst`
- `adaptive_threshold.enabled`
- `adaptive_threshold.min_threshold`
- `adaptive_threshold.ewma_alpha`

Unknown tenant values fall back to default tenant policy.

Dashboard summary includes tenant breakdown for configured tenants.

### Community Marketplace CLI

Marketplace is a CLI surface (no inbound HTTP routes):

```bash
pif marketplace list
pif marketplace install <id>@<version>
pif marketplace update
```

Contract:

- Catalog index (`marketplace.index_url`) exposes entries:
- `id`, `name`, `version`, `download_url`, `sha256`, `categories`, `maintainer`
- Install verifies checksum when `marketplace.require_checksum=true`
- Installed files are written to `marketplace.install_dir` and can be loaded as custom rules

### Proxy (All Other Paths)

Expand Down
Loading
Loading