MR Auto Approver

The MR Auto Approver is a RabbitMQ consumer that listens for GitLab pipeline webhook events and automatically approves MRs whose pipeline succeeded and that match configurable rules. It is primarily used to auto-approve Renovate/Mintmaker dependency update MRs.

How it works

  1. GitLab sends pipeline webhooks to the CKI receiver Lambda
  2. Events flow through SQS → amqp-bridge → RabbitMQ exchange
  3. The auto-approver consumes events from its queue
  4. For each successful pipeline on an MR:
    • Look up the project in config
    • Fetch the MR via parse_gitlab_url to get the author
    • 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

Approving only on pipeline success avoids race conditions with GitLab’s asynchronous removal of approvals on push.

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, api scope). Tokens are resolved via cki_lib.gitlab’s longest-prefix matching on GITLAB_TOKENS.
  • Fork MRs are always skipped (source_project_id != target_project_id).

Configuration

The config is loaded from MR_APPROVER_CONFIG (inline YAML) or MR_APPROVER_CONFIG_PATH (file path). In deployment, a ConfigMap is mounted at /config/config.yaml.

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_ids and branch_regexes must 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_ids means any user matches for that dimension.
  • action: approve (default) or deny.

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 no Inline YAML config string
MR_APPROVER_CONFIG_PATH no Path to config YAML file
GITLAB_TOKENS yes JSON map: URL prefix to token env var
MR_AUTO_APPROVER_ROUTING_KEYS yes Space-separated routing keys
MR_AUTO_APPROVER_QUEUE no Queue name (default: auto)
WEBHOOK_RECEIVER_EXCHANGE no Exchange (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 approved
    • denied: rule matched with action=deny
    • no_match: no rule matched for the project
    • ignored_not_gitlab: non-GitLab message
    • ignored_not_pipeline: non-pipeline event
    • ignored_not_success: pipeline did not succeed
    • ignored_no_mr: pipeline not associated with an MR
    • ignored_fork: fork MR skipped
    • ignored_no_config: project not in config