Signetry's autonomous PR review is an install-once GitHub App. A user installs it on their account or org (choosing repos in GitHub's own UI), and every new pull request gets one advisory review comment — public or private repos, any account, never merges. There are no per-repo webhooks and no stored user token: reviews are posted as the App, using a short-lived installation token minted from the App's private key.
- A single app-level webhook (
POST /api/github/app/webhook) receives PR events for every installation. Each delivery is HMAC-verified against the App's webhook secret. - On a reviewable PR (
opened/reopened/synchronize/ready_for_review), Signetry mints an installation access token from the App's private key (GithubIntegration.get_access_token), reads the PR diff, runs the Reviewer (comment-only,allow_codex=False), and posts one comment. - The install's repos are tracked from the
installation/installation_repositoriesevents so the dashboard can show what's covered. TheSetup URLlinks an install to the signed-in Signetry user.
The installation token is short-lived, used read-only for the diff/clone and comment-only to post — it is never passed to the Codex child process.
Create the App under your GitHub account (this is the only step Signetry cannot do for you):
- GitHub → Settings → Developer settings → GitHub Apps → New GitHub App.
- Name:
Signetry Engineer(this sets the install slug). Homepage:https://signetry.github.io. - Webhook: Active ✓ · URL
https://umbra.engineer/api/github/app/webhook· Secret: a fresh random string (save it). - Repository permissions: Pull requests → Read & write; Contents → Read-only; Metadata → Read-only (default).
- Subscribe to events: Pull request.
- Where can this be installed: Any account.
- Setup URL:
https://umbra.engineer/api/github/app/setup(optionally check "Redirect on update"). - Create, then note the App ID and the slug (from the App's URL), and Generate a private
key (downloads a
.pem).
PROJECT=calm-photon-472423-h3
printf %s "<APP_ID>" | gcloud secrets create signetry-gh-app-id --data-file=- --project $PROJECT
printf %s "<WEBHOOK_SECRET>" | gcloud secrets create signetry-gh-app-webhook-secret --data-file=- --project $PROJECT
gcloud secrets create signetry-gh-app-key --data-file=signetry-engineer.private-key.pem --project $PROJECT
gcloud run services update signetry --region us-central1 --project $PROJECT \
--update-env-vars GITHUB_APP_SLUG=<slug> \
--update-secrets GITHUB_APP_ID=signetry-gh-app-id:latest,GITHUB_APP_WEBHOOK_SECRET=signetry-gh-app-webhook-secret:latest,GITHUB_APP_PRIVATE_KEY=signetry-gh-app-key:latestGITHUB_APP_PRIVATE_KEY accepts a raw PEM (newlines preserved by the secret mount) or base64 of the PEM.
Never paste the private key or webhook secret into code, logs, or chat.
- Before secrets land:
GET /api/github/app→{"configured": false};POST /api/github/app/webhook(no valid signature) → 503. - After secrets land:
GET /api/github/app→{"configured": true, "install_url": "https://github.com/apps/<slug>/installations/new"}; an unsigned/bad-signature POST → 401; a validly-signedping→ 200. - End-to-end: install the App on a repo → open a PR → an 🌑 Signetry Review comment appears within a few
seconds; the dashboard lists the repo under "Autonomous PR auto-review". Failures are logged under the
signetry.webhooklogger (grep Cloud Run logs).
Set GITHUB_APP_ID, GITHUB_APP_SLUG, GITHUB_APP_WEBHOOK_SECRET, and GITHUB_APP_PRIVATE_KEY in your
env (see .env.example) and expose POST /api/github/app/webhook to GitHub with a
tunnel (e.g. cloudflared / ngrok); point the App's webhook URL at the tunnel while testing.