⁉️ Usage

🐳 Docker image

To get GitLab Guard, use the following Docker image:

harbor.confirm.ch/gitlab-guard/gitlab-guard

⚙️ CLI

GitLab Guard provides a CLI

usage: gitlab-guard [-h] [-C] [-f] [-n NAMESPACE] [-t TOKEN] [-r GROUP] [--token-expiry-days DAYS] [-u URL] [-v]

The guardian of GitLab projects.

options:
  -h, --help                            show this help message and exit
  -C, --colours                         display ANSI colours during logging
  -f, --fix                             fix violations automatically (alt. GLG_FIX environment variable)
  -n, --namespace NAMESPACE             GitLab namespace (alt. GLG_GITLAB_NAMESPACE environment variable)
  -t, --token TOKEN                     GitLab access token (alt. GLG_GITLAB_TOKEN environment variable)
  -r, --rotate-token-group GROUP        rotate group access token (alt. GLG_ROTATE_TOKEN_GROUP environment variable)
  --token-expiry-days DAYS              lifetime of the rotated token (alt. GLG_TOKEN_EXPIRY_DAYS environment variable)
  -u, --url URL                         GitLab URL (alt. GLG_GITLAB_URL environment variable)
  -v, --verbose                         enable verbose mode (alt. GLG_VERBOSE environment variable)

Note

For example values, check the examples in the 🌍 Environment variables below.

🌍 Environment variables

Instead of the ⚙️ CLI arguments, the following environment variables, resp. CI variables can be used:

Variable

Description

Example

GLG_FIX

Fix violations automatically (aka don’t dry run)

yes

GLG_GITLAB_NAMESPACE

The GitLab namespace path

example/namespace/path/

GLG_GITLAB_TOKEN

The GitLab access token

glpat-1234567890abcdefghji

GLG_GITLAB_URL

The GitLab base URL

https://gitlab.example.com

GLG_ROTATE_TOKEN_GROUP

Group (ID/path) whose access token is rotated

example/group

GLG_TOKEN_EXPIRY_DAYS

Lifetime (in days) of the rotated token

30

GLG_VERBOSE

Enable verbose mode (e.g. for debugging)

yes

Hint

Mark the GLG_GITLAB_TOKEN CI/CD variable as masked (and ideally protected) so the rotated token never appears in job logs.

🔁 Token rotation

Set GLG_ROTATE_TOKEN_GROUP to the ID (or path) of the group that owns the access token to enable rotation. When it is set, GitLab Guard rotates its own token at the end of every run; when it is unset, rotation is skipped:

  1. It calls the group’s access_tokens/self/rotate API endpoint to rotate the group access token it authenticated with.

  2. GitLab immediately revokes the old token and issues a new one.

  3. The new token is written back into the GLG_GITLAB_TOKEN CI/CD variable of the project GitLab Guard runs in (identified via the CI_PROJECT_ID CI variable), so the next run picks it up automatically.

Important

Token rotation only works when the following requirements are met:

  • GitLab Guard runs in a GitLab CI pipeline (CI_PROJECT_ID must be set).

  • The token is a group access token of the GLG_ROTATE_TOKEN_GROUP group, with the api scope and the Owner role.

  • GLG_GITLAB_TOKEN exists as a CI/CD variable on the project (so it can be updated).

Warning

The rotated token’s lifetime controls two things: whether GitLab Guard stays logged in, and how much expiry email you get.

If GLG_TOKEN_EXPIRY_DAYS is unset, GitLab applies its own default (one week when an expiry is required, otherwise the instance’s maximum allowable lifetime). The lifetime must be longer than your pipeline schedule, otherwise the token expires between runs and locks GitLab Guard out.

GitLab also sends expiry reminder emails 60, 30, and 7 days before a token expires (GitLab 17.6+; earlier versions only 7 days). To silence them, keep the token out of that window between rotations, by setting GLG_TOKEN_EXPIRY_DAYS greater than your pipeline interval (in days) plus 60. For example, with a weekly pipeline, 90 works well: every run mints a fresh ~90-day token and revokes the old one, so the live token never drops below ~83 days and never triggers a reminder.

Finally, keep the lifetime below any maximum token lifetime enforced by your group or instance, otherwise GitLab rejects the rotation.

🔌 GitLab integration

GitLab CI

Important

To run GitLab Guard, you must ensure the following requirements are met:

If the requirements are met, GitLab Guard can be configured to run in the CI/CD pipeline.

Create a .gitlab-ci.yml file with the following content:

Run GitLab Guard:
  stage: deploy
  image: harbor.confirm.ch/gitlab-guard/gitlab-guard:latest
  script:
    - gitlab-guard -C -n NAMESPACE -f
  rules:
    - if: $CI_PIPELINE_SOURCE == 'web'          # triggers when explicitly selecting «New pipeline» in the GitLab UI
    - if: $CI_PIPELINE_SOURCE == 'schedule'     # triggers when a scheduled pipeline is executed

Hint

Feel free to update the rules: according to your need, for example:

  • To run it on every push, remove the rules: completely.

  • To run it only on pushes to the main branch, use if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH

  • To run it only when a specific CI variable is set, use if: $TRIGGER_GITLAB_GUARD

Scheduling

If you want to run GitGuard scheduled, you can use scheduled pipelines.