diff --git a/README.md b/README.md index 6f3c015..6a267db 100644 --- a/README.md +++ b/README.md @@ -2,63 +2,38 @@ Deploy Gate blocked symbol

-

- No receipt. No merge. -

-

Deploy Gate

- Permission Protocol is the approval layer for autonomous systems. Deploy Gate is its GitHub Action. + AI tried to deploy. It got blocked.

- One workflow. Human approval required. No exceptions. + No AI action executes without an explicit human signer.
+ One workflow. One secret. Works on your first PR.

Tests - - Marketplace -

--- -## Badge Usage - -

- deploy gate blocked badge - deploy gate approved badge -

- -

- blocked gate symbol - approved gate symbol -

+## How it works -```markdown -![deploy gate blocked](./assets/badge-blocked.svg) -![deploy gate approved](./assets/badge-approved.svg) +``` +PR opened → ❌ Deploy blocked → Human signs → ✅ Deploy proceeds ``` ---- - -## What It Does - -**Blocks merges to `main` until a human approves.** +Open a PR. Deploy Gate blocks the merge. Click the approval link. Sign. Merge proceeds. Receipt recorded. -Every PR to a protected branch creates a Permission Protocol request. Approval state is enforced via commit status, and protected-path matches are sent as risk metadata (not used for gating). +**Takes ~3 minutes to install. One secret.** --- -## Install (3 minutes) - -**👉 [Full install guide](./INSTALL.md)** with screenshots and troubleshooting. - -**Quick version:** +## Install ```yaml # .github/workflows/deploy-gate.yml @@ -81,11 +56,37 @@ jobs: 1. Get API key from [app.permissionprotocol.com](https://app.permissionprotocol.com) 2. Add secret: `gh secret set PP_API_KEY -b "pp_live_..."` 3. Add workflow above -4. Open PR → Permission request created automatically → approve if needed → merge +4. Open a PR → see it blocked → approve → merge + +**[Full install guide →](./INSTALL.md)** --- -## How It Works +## Why this exists + +AI agents can deploy code, delete data, and modify infrastructure. + +Today, they do this with: + +- ❌ No explicit approval +- ❌ No accountability +- ❌ No audit trail + +"Approved" is a mutable DB flag. An agent, a backend, or a bug can flip it. + +Deploy Gate enforces: + +- ✅ Explicit human signer (Ed25519) +- ✅ Signature bound to exact args (commit, repo, environment) +- ✅ Single-use receipt (replay fails) +- ✅ Tamper-evident — any post-signing mutation fails verification +- ✅ Verifiable audit trail + +It does not trust database state. Only the signed receipt. + +--- + +## Flow

PR Created to Deploy Gate flow @@ -95,68 +96,36 @@ jobs: PR opened │ ▼ - Deploy Gate verifies/creates PP request + Deploy Gate verifies/creates request │ - ├─────────────── Auto-approved / verified ───────────────► ✅ Merge OK + ├── Receipt exists + valid ──────────────► ✅ Merge OK │ - └─────────────── Approval required ───────────────────────► ⏳ Pending status + PR comment with review link - │ - ▼ - Human approves in dashboard - │ - ▼ - Re-run CI → ✅ Merge OK + └── No receipt ──────────────────────────► ⏳ Blocked + PR comment with approval link + │ + ▼ + Human approves in dashboard + │ + ▼ + Re-run CI → ✅ Merge OK ``` --- -## Advanced Setup +## PR Comments -### 1. Get API Key +Deploy Gate posts directly on your PR: -Sign up at [app.permissionprotocol.com](https://app.permissionprotocol.com) and create an API key. - -### 2. Add Secret - -```bash -gh secret set PP_API_KEY -b "pp_live_your_key_here" +Approval required: ``` - -### 3. Add Workflow - -Create `.github/workflows/deploy-gate.yml`: - -```yaml -name: Deploy Gate - -on: - pull_request: - branches: [main] - -jobs: - gate: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: permission-protocol/deploy-gate@v1 - with: - pp-api-key: ${{ secrets.PP_API_KEY }} +⏳ Permission Protocol: Approval required + Review & approve → https://app.permissionprotocol.com/pp/deploy-requests/{id} ``` -### 4. Open a PR - -Open any PR to the protected branch. Deploy Gate always creates/verifies a request and posts a PR comment with the receipt/review link. - ---- - -## ⚠️ Recommended: GitHub Ruleset Pattern - -To avoid "merge loops" where approvals go stale when `main` advances, we recommend a **two-ruleset pattern** if you use GitHub Repository Rulesets: - -1. **Ruleset 1 (Permission Protocol):** Require `Permission Protocol` status check with **Strict mode: OFF**. -2. **Ruleset 2 (Build Protection):** Require your build/test checks with **Strict mode: ON**. - -This ensures your code is up-to-date with `main`, but your human approvals stick once granted. [See full guide →](./INSTALL.md#%EF%B8%8F-critical-github-rulesets--strict-mode) +Approved: +``` +✅ Permission Protocol: Approved + View receipt → https://app.permissionprotocol.com/pp/deploy-requests/{id} +``` --- @@ -166,43 +135,31 @@ This ensures your code is up-to-date with `main`, but your human approvals stick |-------|-------------|---------| | `pp-api-key` | Your Permission Protocol API key | **Required** | | `pp-base-url` | PP API base URL | `https://app.permissionprotocol.com` | -| `pp-request-create-token` | Optional token to auto-create approval requests when receipts are missing | `''` | | `environment` | Environment bound to the receipt scope | `production` | | `capability` | Capability bound to the receipt scope | `deploy:production` | | `redeem` | Redeem receipt on verify (`false` for PR gate, `true` for deploy workflow) | `false` | -| `protected-paths` | Regex used for risk assessment metadata only (not gating) | `^(deploy/|\.github/workflows/)` | | `fail-on-missing` | Fail if no receipt | `true` | | `fail-open-timeout` | Seconds to wait before PP API fail-open | `30` | | `post-comment` | Post/update PR comment with receipt or approval link | `true` | -### Risk Metadata Paths - -```yaml -- uses: permission-protocol/deploy-gate@v1 - with: - pp-api-key: ${{ secrets.PP_API_KEY }} - protected-paths: '^(src/critical/|infra/|\.env)' -``` -Protected path matches are forwarded to PP as `protectedPathsChanged` + `changedFiles` metadata for risk scoring. +

+Advanced configuration -## Advanced Usage +| Input | Description | Default | +|-------|-------------|---------| +| `pp-request-create-token` | Optional token to auto-create approval requests | `''` | +| `protected-paths` | Regex for risk assessment metadata (not gating) | `^(deploy/\|\.github/workflows/)` | -Use this when you want custom scope values and auto-request creation in one workflow. +### Risk Metadata Paths ```yaml - uses: permission-protocol/deploy-gate@v1 with: pp-api-key: ${{ secrets.PP_API_KEY }} - pp-request-create-token: ${{ secrets.PP_REQUEST_CREATE_TOKEN }} - environment: production - capability: deploy:production - redeem: false - fail-on-missing: true + protected-paths: '^(src/critical/|infra/|\.env)' ``` ---- - -## Outputs +### Outputs | Output | Description | |--------|-------------| @@ -224,39 +181,36 @@ Use this when you want custom scope values and auto-request creation in one work if: failure() ``` -## PR Comment Example +### GitHub Ruleset Pattern -Auto-approved / verified: -```markdown -✅ **Permission Protocol:** Approved -[View receipt →](https://app.permissionprotocol.com/pp/deploy-requests/{requestId}) -``` +To avoid "merge loops" where approvals go stale when `main` advances, use a **two-ruleset pattern**: -Approval required: -```markdown -⏳ **Permission Protocol:** Approval required -[Review & approve →](https://app.permissionprotocol.com/pp/deploy-requests/{requestId}) -``` - ---- +1. **Ruleset 1 (Permission Protocol):** Require `Permission Protocol` status check with **Strict mode: OFF**. +2. **Ruleset 2 (Build Protection):** Require your build/test checks with **Strict mode: ON**. -## Why? +[See full guide →](./INSTALL.md#%EF%B8%8F-critical-github-rulesets--strict-mode) -Your AI agent just pushed to main. -It passed CI. -It deployed to production. +
-**Who approved it?** +--- -Not a human. Not a policy. Nobody. +## Live Demo -Deploy Gate closes that gap. +See it in action: [permission-protocol/pp-demo](https://github.com/permission-protocol/pp-demo) --- -## Live Demo +## Badge Usage + +

+ deploy gate blocked badge + deploy gate approved badge +

-See it in action in the demo repo: [permission-protocol/pp-demo](https://github.com/permission-protocol/pp-demo) +```markdown +![deploy gate blocked](./assets/badge-blocked.svg) +![deploy gate approved](./assets/badge-approved.svg) +``` ---