MR Auto-Approver
An AWS Lambda function that auto-approves GitLab merge requests based on configurable per-project rules. Replaces CI/CD-based approval jobs and moves approval tokens out of GitLab CI/CD variables.
Features
- Rules-Based Config: YAML config with per-project ordered rules matching on usernames, branch patterns, and Konflux pipeline status
- First-Match-Wins: Rules evaluated in order; first match determines action (approve or deny)
- Konflux Integration: Optional check that Konflux pipelines have posted commit statuses before approving
- Fork Rejection: Unconditionally rejects MRs from forked projects
- User Verification: Matches against the authenticated webhook event user, not forgeable Git commit metadata
- Stateless & Idempotent: No queues or stored state; re-approving is a no-op
Architecture
The Lambda subscribes to the existing SNS topic (from gitlab-event-forwarder)
with a filter for merge_request and pipeline events:
GitLab Webhook → gitlab-event-forwarder → SNS Topic → mr-auto-approver → GitLab API
Merge request events (open, update): evaluate rules using the
authenticated pusher from the webhook payload. If matched and no Konflux check
needed, approve immediately. If Konflux check needed, check statuses now and
approve only if present and not failed.
Pipeline events (success, failed): look up the MR from the pipeline
event via the GitLab API, evaluate rules, and approve if Konflux statuses are
ready. This handles the case where Konflux posts commit statuses after the
initial MR event.
Prerequisites
- AWS CLI configured with appropriate credentials (IAM permissions for Lambda, SNS, CloudFormation, CloudWatch Logs)
- Podman or Docker (for containerized SAM build/deploy)
- Python 3.11 or later (for development)
- GitLab API token(s) with
apiscope and permission to approve MRs on target projects - Target project webhooks must send
merge_requests_eventsandpipeline_eventsto the gitlab-event-forwarder endpoint
Deployment
Build and deploy using containerized AWS SAM CLI:
cd mr-auto-approver
make build # Build Lambda package
make deploy # First deployment (interactive/guided)
make redeploy # Subsequent deployments (non-interactive)
Parameters
| Parameter | Description | Default |
|---|---|---|
ResourcePrefix |
Prefix for resources | myapp-prod |
SnsTopicArn |
SNS topic ARN | (required) |
GitLabUrl |
GitLab instance URL | https://gitlab.com |
ConfigPath |
Path to YAML config (bundled with Lambda) | config.yaml |
ApprovalTokens |
JSON map of env var names to tokens | {} |
SentryDsn |
Optional Sentry DSN | `` |
Resource naming: Lambda follows {ResourcePrefix}-lambda-approver pattern.
Prerequisites: Requires an existing SNS topic. Deploy
hummingbird-events-topic first to create the topic, then use its
ARN for the SnsTopicArn parameter.
Configuration
The Lambda uses a YAML config file bundled at deploy time. The config defines per-project rules:
settings:
gitlab_url: https://gitlab.com
projects:
org/group/repo:
token_env: APPROVAL_GITLAB_TOKEN_REPO
rules:
- branch_regexes: ["renovate/skip/.*"]
action: deny
- user_regexes: ["bot-user"]
branch_regexes: ["renovate/.*"]
- user_regexes: ["chore-mr"]
check_konflux: true
Rule fields
| Field | Type | Default | Description |
|---|---|---|---|
user_regexes |
list[str] | [] |
Fullmatch regexes for username |
branch_regexes |
list[str] | [] |
Fullmatch regexes for source branch |
check_konflux |
bool | false |
Require Konflux statuses before approval |
action |
str | approve |
approve or deny |
Match logic: AND across field types, OR within a field. Empty fields match anything. First matching rule wins.
Adding a new project
- Create a project-scoped GitLab token (Developer,
apiscope) in Vault - Add the token to
vars.shand thejqcommand that buildsAPPROVAL_TOKENS - Add a project entry to
config.yamlin the infrastructure repo withtoken_envand rules - Deploy the Lambda
- Ensure the project’s GitLab webhook sends events to the gitlab-event-forwarder endpoint
Environment variables
| Variable | Description |
|---|---|
CONFIG_PATH |
Path to YAML config file |
GITLAB_URL |
GitLab instance URL |
APPROVAL_TOKENS |
JSON object mapping env var names to GitLab tokens |
SENTRY_DSN |
Optional Sentry DSN |
Security
- Fork MRs are unconditionally rejected before any rule evaluation
(
source_project_id != target_project_id) - User matching uses the authenticated
user.usernamefrom the webhook payload, never Git commit author/committer metadata - For pipeline events, the Lambda looks up
head_pipeline.user.usernamevia the GitLab API to verify the last pusher - Approval tokens stored as CloudFormation parameters with
NoEcho: true - SNS subscription filter policy limits events to
merge_requestandpipeline - CloudWatch logs capture all approval decisions (7-day retention)
Development
See the main README for development workflows.
make setup # Install dependencies
make check # Lint code (ruff)
make fmt # Format code
make test # Run unit tests
make coverage # Run tests with coverage
License
This project is licensed under the GNU General Public License v3.0 or later - see the LICENSE file for details.