# GitHub App: Permissions Required # news-albertlane-org-dispatch # Albert Lane · SovereignAudits™ # Z-Axis Transport Pipeline: Origin_Curator_App → GitHub_Repository → Cloudflare_Edge # Reference: auth-transport-protocol.xml, Node: GitHub_App_Webhook --- ## App Identity | Field | Value | |------------------|------------------------------------------------| | App Name | `news-albertlane-org-dispatch` | | Homepage URL | `https://albertlane.org` | | Webhook URL | `https://news.albertlane.org/webhook/github` | | Webhook Secret | Derived from WEBHOOK_LEDGER_SECRET (see below) | | SSL verification | Required — no bypass | --- ## Required Repository Permissions These are the minimum permissions. Request ONLY these. Each scope has a documented rationale against the transport schema. | Permission | Access Level | Why | |---------------------|-------------|-------------------------------------------------------------------------------| | `contents` | `read` | Cloudflare Pages pulls repository source for build/deploy | | `deployments` | `write` | Creates Cloudflare deployment records in GitHub; receives status callbacks | | `statuses` | `write` | Posts commit status checks after Cloudflare build completes | | `metadata` | `read` | **Mandatory base permission** — automatically granted, cannot be removed | ### NOT required (do not request): - `pull_requests` — no PR-based deploy flow - `issues` — not part of this pipeline - `actions` — CI runs on Cloudflare, not GitHub Actions - `administration` — never - `organization_administration` — never - `members` — never - `secrets` — never (secrets live in Cloudflare Worker, not GitHub) --- ## Webhook Events to Subscribe | Event | Why | |---------------------|---------------------------------------------------------------------| | `push` | Triggers the dispatch pipeline — Node: Origin_Curator_App → GitHub | | `deployment` | Tracks deployment lifecycle state at Cloudflare edge | | `deployment_status` | Receives Cloudflare build completion callbacks | ### NOT required: - `pull_request` events - `issues` events - `workflow_run` events (no GitHub Actions in this pipeline) --- ## Webhook Security: WEBHOOK_LEDGER_SECRET GitHub signs every webhook payload with HMAC-SHA256 and sends the signature in the `X-Hub-Signature-256` header. The Worker verifies this with a constant-time comparison (see `news-mesh-worker.ts` `verifyGitHubSignature()`). ### Secret handling rules (supply chain hardening): ```yaml # CORRECT — bind at step-level env, never interpolate directly - name: Deploy env: WEBHOOK_SECRET: ${{ secrets.WEBHOOK_LEDGER_SECRET }} run: printf '%s' "$WEBHOOK_SECRET" | wrangler secret put WEBHOOK_LEDGER_SECRET ``` ```yaml # WRONG — direct interpolation is a supply chain attack surface - run: wrangler secret put WEBHOOK_LEDGER_SECRET --value ${{ secrets.WEBHOOK_LEDGER_SECRET }} ``` The secret in Cloudflare: ```bash wrangler secret put WEBHOOK_LEDGER_SECRET --name news-albertlane-org-mesh ``` --- ## Installation Scope - **Repository-level installation** — NOT organization-level - Install only on the specific repository serving news content - Do NOT grant access to `sovereign-provenance`, `SimCity`, or other repos unless a separate App is created for those pipelines --- ## Transport Flow (from auth-transport-protocol.xml) ``` Origin_Curator_App (albertlane.net) │ │ Git_Push_Event (Encrypted_JSON_Blob) ▼ GitHub_Repository │ │ X-Hub-Signature-256 verified │ Zero_Secret_Transmission protocol ▼ GitHub_App_Webhook → POST https://news.albertlane.org/webhook/github │ │ WEBHOOK_LEDGER_SECRET HMAC-SHA256 verification │ (Cloudflare Worker: news-mesh-worker.ts) ▼ Cloudflare_Edge (news-mesh-worker.ts) │ │ dispatch:* written to NEWS_KV │ Z-axis zone logged ▼ Core_Routing_Gateway → news.albertlane.org/routing │ └─► {postalCode}.albertlane.org/routing [Oregon zone resolved] └─► news.albertlane.org [default serve] ``` --- ## What the App Does NOT Touch By design, the GitHub App has no write access to: - Repository contents (read-only) - Branches, tags, or refs - GitHub Actions workflows - Repository secrets (the Worker holds all secrets) - Organization settings The App is a one-way push notification mechanism. The Cloudflare Worker is the authority on routing and authentication. GitHub is solely the origin event source. --- ## Verification Test After Installation After installing the App and configuring the webhook: ```bash # 1. Check Worker is live curl https://news.albertlane.org/mesh/health # 2. Send a test push event (GitHub will provide a "Redeliver" button) # Expect: 200 { "ok": true, "dispatch": "dispatch:..." } # 3. Verify dispatch written to KV wrangler kv key list --binding NEWS_KV --name news-albertlane-org-mesh \ | grep dispatch # 4. Verify unauthorized requests are logged (send a bad sig) curl -X POST https://news.albertlane.org/webhook/github \ -H "X-Hub-Signature-256: sha256=badhash000" \ -H "Content-Type: application/json" \ -d '{"test":true}' # Expect: 403 "Unauthorized — logged to chain" ``` --- SEC Whistleblower No. 17684-273-411-436 albertlane.net | albertlane.org | albertlane.uk