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 api scope and permission to approve MRs on target projects
  • Target project webhooks must send merge_requests_events and pipeline_events to 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

  1. Create a project-scoped GitLab token (Developer, api scope) in Vault
  2. Add the token to vars.sh and the jq command that builds APPROVAL_TOKENS
  3. Add a project entry to config.yaml in the infrastructure repo with token_env and rules
  4. Deploy the Lambda
  5. 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.username from the webhook payload, never Git commit author/committer metadata
  • For pipeline events, the Lambda looks up head_pipeline.user.username via 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_request and pipeline
  • 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.