Serverless GitHub App that auto-approves pull requests after CI passes, with optional AI code review via Amazon Bedrock. Five repositories: TypeScript/Probot app, AWS Terraform module (Lambda + API Gateway + Secrets Manager + SQS DLQ), GitHub Terraform module (webhooks), deployment infra, and test repo.
A serverless GitHub App that auto-approves pull requests when all CI checks pass. Optionally, before approving, it sends the diff to Amazon Bedrock for an AI code review that detects bugs, security vulnerabilities, and performance issues.
The project is split into five repositories with clear responsibilities:
| Repository | Version | Role |
|---|---|---|
| pr-auto-approver | v1.0.0 | TypeScript/Probot app — business logic (esbuild → ~1 MB) |
| terraform-aws-pr-auto-approver | v1.4.0 | Terraform AWS module — Lambda, API Gateway, Secrets Manager, SQS DLQ (Registry) |
| pr-auto-approver-infra | latest | Private deployment — consumes the modules, branch protected |
| pr-auto-approver-test | — | Test repo — PR history shows the bot in action |
| terraform-github-pr-auto-approver | v1.0.0 | Terraform GitHub module — per-repo webhooks (optional, the GitHub App configures them automatically) |

PR #21 shows the full AI review cycle. The first commit contained a hardcoded API key and a SQL injection vulnerability — the bot (jonmatumdev, using PAT) detected both issues, left inline comments, and requested changes. The author fixed the code, pushed a new commit, the bot automatically re-reviewed the updated diff, found no issues, and approved. The PR was merged — all in under two minutes.
The full flow from PR creation to approval:
Secrets management follows the principle of least privilege:
approval_token (PAT) is configured, the bot checks its validity on each cold start — logs CRITICAL if expired and WARNING if it expires within 14 dayssecretsmanager:GetSecretValue permissions only for the specific ARNsbedrock:InvokeModel) are added only when bedrock_enabled = trueThe terraform-aws-pr-auto-approver v1.4.0 module creates:
| Resource | Configuration |
|---|---|
| Lambda | Node.js 20, 128 MB / 30s (no Bedrock), 256 MB / 120s (with Bedrock) |
| API Gateway v2 | HTTP API with POST route |
| Secrets Manager | 2-3 secrets (private key + webhook secret + optional approval token) |
| SQS Dead Letter Queue | 14-day retention, alarm on messages (failed webhooks) |
| IAM Role | Least-privilege, conditional Bedrock |
| CloudWatch Logs | 14-day retention |
| CloudWatch Dashboard | Lambda, API GW, Bedrock metrics (optional) |
| CloudWatch Alarms | Errors, throttles, high duration, 5xx, DLQ |
| SNS Topic | Email alerts (optional) |
| AWS Budget | Monthly Bedrock budget (optional) |
The terraform-github-pr-auto-approver v1.0.0 module configures webhooks on each specified repository. This module is optional — when you install the GitHub App on a repository, webhooks are configured automatically. The module is only needed if you prefer to manage webhooks via IaC instead of the App's built-in webhook delivery.
module "approver_github" {
source = "jonmatum/pr-auto-approver/github"
version = "~> 1.0"
webhook_url = module.approver_infra.webhook_url
webhook_secret = var.webhook_secret
github_repositories = ["repo-one", "repo-two"]
}It subscribes each repository to pull_request and check_suite events, pointing to the API Gateway endpoint.

When bedrock_enabled = true, Lambda sends the PR diff to Claude 3.5 Haiku (configurable) before approving. In PR #21, the bot detected 2 issues in intentionally vulnerable code — a hardcoded API key and a SQL injection — and requested changes with inline comments instead of approving. The model reviews for:
The review prompt was tuned to reduce false positives — the model only reports concrete issues, not style suggestions. If Bedrock is disabled or fails, the bot falls back to auto-approve after CI passes — the AI review never blocks the flow.
When new commits are pushed to an open PR, the bot dismisses its previous review (clears the "changes requested" state) and automatically re-runs the review on the updated diff.
GitHub App approvals do not count as real user reviews in branch protection rulesets on the free plan. This means that even though the bot approves a PR, the "Require approvals" rule remains unsatisfied.
The implemented workaround is an optional approval_token — a Personal Access Token (PAT) stored in Secrets Manager. When configured, the bot submits the approval using that token instead of the GitHub App identity, which counts as a real user review and satisfies branch protection rules.
module "approver_infra" {
source = "jonmatum/pr-auto-approver/aws"
version = "~> 1.4"
# ... other variables ...
approval_token = var.approval_token # Optional PAT to satisfy branch protection
}This limitation is specific to the free plan — on GitHub Enterprise, GitHub App approvals do count toward branch protection.
pull_requests: write, checks: read, contents: read. Subscribe to pull_request and check_suite events. Generate a private key.npm ci && npm run zip. Produces lambda.zip (~1 MB).module "approver" {
source = "jonmatum/pr-auto-approver/aws"
version = "~> 1.4"
github_app_id = "123456"
github_app_private_key = file("private-key.pem")
github_webhook_secret = var.webhook_secret
allowed_authors = "bot-username,your-username"
lambda_zip_path = "./lambda.zip"
# Optional: AI code review
bedrock_enabled = true
# Optional: approvals that count toward branch protection
approval_token = var.approval_token
# Optional: monitoring
monitoring_enabled = true
alert_email = "you@example.com"
}webhook_url output and paste it in the GitHub App configuration.For PAT mode: create a classic PAT (repo scope) from a second GitHub account, add that account as a collaborator with write access.
In teams with AI agents that generate PRs automatically — like the content agent in this knowledge base — the bottleneck shifts from "writing code" to "reviewing and approving PRs." This bot eliminates the manual wait for PRs from trusted authors that already passed CI, while the optional Bedrock layer adds a code review safety net without human intervention.
GitHub's native CI/CD platform. Declarative YAML workflows that automate build, test, deploy, and any development lifecycle task — directly from the repository.
HashiCorp's Infrastructure as Code tool that enables defining, provisioning, and managing multi-cloud infrastructure through declarative HCL files.
AWS serverless compute service that runs code in response to events without provisioning or managing servers, automatically scaling from zero to thousands of concurrent executions.
AWS managed service for creating, publishing, and managing REST, HTTP, and WebSocket APIs that act as entry points to Lambda functions and other backend services.
Practices and tools for securely storing, distributing, and rotating credentials, API keys, and other sensitive data in applications and pipelines.
Cloud computing model where the provider manages infrastructure automatically, allowing code execution without provisioning or managing servers, paying only for actual usage.
Practice of defining and managing infrastructure through versioned configuration files instead of manual processes. Foundation of modern operations automation.
Continuous Integration and Continuous Delivery/Deployment — practices that automate code integration, testing, and delivery to production. Foundation of modern software engineering.