diff --git a/README.md b/README.md index 11be68a..b94c89d 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,23 @@ -

- Deploy Gate blocked symbol -

+# Deploy Gate -

Deploy Gate

+**Stop AI coding agents from shipping production changes you didn't authorize.** -

- Block AI deploys until a human signs. -

+When Cursor / Codex / Copilot / Claude Code opens a PR that touches `deploy/`, `.github/workflows/`, or any path you mark sensitive, Deploy Gate blocks the merge until a named human signs an approval and produces a signed receipt that proves who authorized what against which policy. -

- AI agents can open PRs. They should not deploy to production.
- This GitHub Action enforces that boundary. -

+- ⛔ **Fails closed by default** for production environments +- ✍️ **Ed25519-signed receipts** bound to the exact action +- ⚡ **<200ms enforcement** in the GitHub status check +- 🆓 **MIT-licensed action** -

- - Tests - -

+> "GitHub asks 'did a reviewer approve?' Deploy Gate asks 'did a named human authorize this exact AI action?' and gives you signed proof." ---- - -## See it in action - -

- ▶ Try the interactive demo — no login, no setup, 15 seconds. -

+## Why this exists -

- - Deploy Gate: PR blocked → human signs → merge unlocked - -

+AI agents are moving from "suggest text" to "take actions": committing code, modifying workflows, and deploying to production. GitHub controls like branch protection, environments, and required reviewers gate humans, not agents. -``` -PR opened → ❌ Deploy blocked → Human authorizes → ✅ Signed → Merge unlocked -``` +Deploy Gate is the missing primitive: a deterministic gate keyed to the exact action the agent is taking, with a signed authority receipt as the audit artifact. ---- +When audit time comes, you do not want to hand over a mutable PR comment thread. You want a chain of signed receipts that can be independently verified. ## Quickstart @@ -61,103 +41,76 @@ jobs: pp-api-key: ${{ secrets.PP_API_KEY }} ``` -1. Get API key → https://app.permissionprotocol.com +1. Get API key at https://app.permissionprotocol.com 2. Add secret: + ```bash gh secret set PP_API_KEY -b "pp_live_..." ``` -3. Open a PR → watch it get blocked → approve → merge -**Takes ~3 minutes. One secret.** +3. Open a PR and watch deploy-sensitive changes block until approval -👉 [Full install guide →](./INSTALL.md) +Full install guide: [INSTALL.md](./INSTALL.md) ## Failure modes -`v2` defaults to fail-closed when the Permission Protocol API is unavailable. +`v2` defaults to fail-closed when the Permission Protocol API is unavailable. **A security tool that fails open in a network blip is not a security tool.** -| Environment | `fail-mode` | Result on API unavailable | Log line | -|---|---|---|---| -| Production match (`production,prod,live` by default) | `closed` or `open` | Fail (exit non-zero) | `::error ... Failing CLOSED for production ...` | -| Non-production | `closed` (default) | Fail (exit non-zero) | `::error ... Failing CLOSED for non-production ...` | -| Non-production | `open` (opt-in) | Pass (exit 0) | `::warning ... Fail-mode=open (opt-in) ...` | +| Environment | `fail-mode` | Result on API unavailable | +| --- | --- | --- | +| Production (`production`, `prod`, `live` by default) | `closed` or `open` (forced to closed) | ❌ Fails closed. No deploy. | +| Non-production (`staging`, `preview`, etc.) | `closed` (default) | ❌ Fails closed. No deploy. | +| Non-production | `open` (opt-in) | ✅ Pass with `::warning::` log | Inputs: -- `fail-mode`: `closed` (default) or `open` (only honored in non-production) -- `production-environments`: comma-separated production names, default `production,prod,live` -- `fail-open-timeout`: timeout only (deprecated as policy control). It controls API timeout duration, not fail-open/fail-closed policy. - -## Release notes - -- **BREAKING**: defaults to fail-closed. To restore v1 behavior, set fail-mode: open and remove production-environments. - ---- - -## What it does -- Blocks risky PRs with a required status check -- Posts a PR comment with a direct approval link -- Sends the reviewer to Permission Protocol to approve and sign -- Unblocks the PR instantly after approval -- Produces a tamper-evident approval record +- `fail-mode`: `closed` (default) or `open` — only honored in non-production environments. +- `production-environments`: comma-separated environment names treated as production, default `production,prod,live`. +- `fail-open-timeout`: API timeout in seconds. It controls timeout duration only, not failure policy. ---- +### Release notes (v2) -## Why this exists - -AI agents can write code, open PRs, and trigger workflows — but they should not have authority to deploy on their own. - -Today: -- approvals are mutable -- logs are not proof -- systems trust state, not intent - -Deploy Gate enforces: - -- Explicit human signer (Ed25519) -- Signature bound to exact action (commit, repo, environment) -- Single-use receipt (replay fails) -- Tamper-evident — mutation invalidates approval - -It does not trust database state. Only signed receipts. - ---- +- **BREAKING**: defaults to fail-closed. To restore v1 behavior, set `fail-mode: open` and remove `production-environments`. ## How it works -``` +*Block -> Approve -> Verify -> Merge.* + +```text PR opened │ ▼ Deploy Gate checks for valid receipt │ - ├── Receipt exists ───────────────► Merge allowed + ├── Receipt exists ----------> Merge allowed │ - └── No receipt ───────────────────► Blocked - │ - ▼ - PR comment with approval link - │ - ▼ - Human approves + signs - │ - ▼ - Re-run CI → Merge allowed + └── No receipt --------------> Blocked + │ + ▼ + PR comment with approval link + │ + ▼ + Human approves + signs + │ + ▼ + Re-run CI -> Merge allowed ``` ---- - -## Try it live (30 seconds) +## What it does -No install required: +- Blocks risky PRs with a required status check +- Posts a PR comment with a direct approval link +- Unblocks the PR instantly after approval +- Produces a tamper-evident approval receipt -1. Open demo PR - https://github.com/permission-protocol/pp-demo/pull/35 -2. Click Authorize Deploy -3. Approve → see your signed receipt +## Comparison ---- +| Option | Human authorization on AI action | Cryptographic proof | Default under outage | +| --- | --- | --- | --- | +| GitHub required reviewer only | Partial | No | Often workflow-dependent | +| PR comments + screenshots | No | No | Open to mutation | +| Deploy Gate | Yes | Yes (Ed25519 receipt) | Fails closed for production | ## License -MIT — see LICENSE +MIT - see [LICENSE](./LICENSE)