MR Auto Approver
The MR Auto Approver is a RabbitMQ consumer that listens for GitLab
merge_request webhook events and automatically approves MRs that match
configurable rules. It is primarily used to auto-approve Renovate/Mintmaker
dependency update MRs.
How it works
- GitLab sends
merge_requestwebhooks to the CKI receiver Lambda - Events flow through SQS → amqp-bridge → RabbitMQ exchange
- The auto-approver consumes events from its queue
- For each MR event (action:
openorupdate):- Look up the project in config
- Evaluate ordered rules (first match wins)
- If a rule matches with action
approve: call GitLab’s approve API - If a rule matches with action
deny: log and skip
Security
- User identity is matched by
user_id(immutable integer), not by username. This prevents spoofing via GitLab username changes. - Per-project access tokens: each supported project has its own GitLab
project access token (Maintainer role,
apiscope). Tokens are resolved viacki_lib.gitlab’s longest-prefix matching onMR_APPROVER_GITLAB_TOKENS. - Fork MRs are always skipped (source_project_id != target_project_id).
Configuration
The config file is mounted from deployment-all as a ConfigMap at
/config/config.yaml (configurable via MR_APPROVER_CONFIG_PATH).
settings:
gitlab_tokens_env: MR_APPROVER_GITLAB_TOKENS
projects:
cki-project/kernel-ark:
rules:
- user_ids: [12345678] # renovate-bot's GitLab user ID
branch_regexes: ["renovate/.*", "mintmaker/.*"]
action: approve
Rule semantics
- First match wins: rules are evaluated in order; the first matching rule determines the action.
- AND across fields: both
user_idsandbranch_regexesmust match (if specified) for a rule to fire. - OR within a field: any user_id in the list OR any branch_regex matching is sufficient for that field.
- Empty field = no constraint: omitting
user_idsmeans any user matches for that dimension. action:approve(default) ordeny.
Finding a user’s GitLab ID
curl -s "https://gitlab.com/api/v4/users?username=renovate-bot" | jq '.[0].id'
Environment variables
| Variable | Required | Description |
|---|---|---|
MR_APPROVER_CONFIG_PATH |
no | Path to config YAML (default: /config/config.yaml) |
MR_APPROVER_GITLAB_TOKENS |
yes | JSON map: project URL prefix → token env var name |
GITLAB_APPROVAL_TOKEN_* |
yes | Per-project GitLab access tokens (referenced by the map) |
MR_AUTO_APPROVER_ROUTING_KEYS |
yes | Space-separated RabbitMQ routing keys |
MR_AUTO_APPROVER_QUEUE |
no | Queue name (default: auto-generated) |
WEBHOOK_RECEIVER_EXCHANGE |
no | Exchange name (default: cki.exchange.webhooks) |
RABBITMQ_USER |
yes | RabbitMQ credentials |
RABBITMQ_PASSWORD |
yes | RabbitMQ credentials |
RABBITMQ_HOST |
yes | RabbitMQ host |
RABBITMQ_PORT |
yes | RabbitMQ port |
RABBITMQ_VIRTUAL_HOST |
yes | RabbitMQ vhost |
SENTRY_DSN |
no | Sentry error reporting |
Metrics
Prometheus metrics are exposed on port 8765 at /metrics:
cki_mr_auto_approver_messages_total{result}: counter with labels:approved: MR was successfully approveddenied: rule matched with action=denyno_match: no rule matched for the projectapproval_failed: approve API call failedignored_not_gitlab: non-GitLab messageignored_not_mr: non-merge_request eventignored_action: MR action not in {open, update}ignored_fork: fork MR skippedignored_incomplete: incomplete webhook payloadignored_no_config: project not in config