CLI reference
One binary, two subcommands:
gitlab-warden reconcile --config governance.yaml [flags]
gitlab-warden migrate <path> [flags]
reconcile is the governance loop this page documents; migrate translates
GitHub Actions workflows into GitLab CI YAML and has its own page
(MIGRATE.md, flags included). gitlab-warden --help (or no
arguments, or --help after a subcommand) prints usage;
gitlab-warden --version prints the version (inlined from package.json at
build time).
Reconcile flags
| Flag | Default | Meaning |
|---|---|---|
--config <path> |
required | governance config file (YAML, or JSON when the path ends in .json) |
--mode dry-run\|apply |
dry-run |
dry-run computes and prints the plan; apply mutates after guardrails pass |
--cycles <name[,name…]> |
all 20 | comma-separated cycle names to run (see CYCLES.md); an unknown name is an error listing the known ones |
--base-url <url> |
https://gitlab.com |
GitLab instance URL for self-managed, e.g. https://gitlab.example.com |
--base-url-env <VAR> |
— | read the base URL from an env var instead (--base-url wins if both are given) |
--token-env <VAR> |
GITLAB_TOKEN |
env var holding the API token; the run fails (exit 2) if it is unset or empty |
--allow-guardrail-override |
off | apply even when a guardrail trips |
--removal-cap-fraction <f> |
0.25 |
max deletable fraction of each resource type's live entries per apply; must be in (0, 1] or the parse fails with exit 2 |
The command accepts flags only; a positional argument is an error. Every flag
except --allow-guardrail-override takes a value.
Config loading
- The file is parsed as JSON if the path ends in
.json(case-insensitive), otherwise as YAML. - It must be an object with a
nodesmap (POLICY.md documents the schema). Anything else is rejected with exit 2.
Auth and token scopes
The token is sent as the PRIVATE-TOKEN header against <base-url>/api/v4
(REST) and <base-url>/api/graphql (the GraphQL cycles). Use a personal
access token or a group access token with:
apiscope (required; the reconcile both reads and writes).- Owner on declared group nodes and Maintainer or above on declared project nodes (member management, protected branches, tokens, and settings writes need those roles).
- Instance admin for
kind: instancenodes (/application/settings,/hooks, and/admin/ci/variablesare admin-only and absent on GitLab.com, where the instance-governance cycle simply manages nothing).
Never pass the token on the command line; export it and name the variable via
--token-env.
Modes, guardrails, budget
- dry-run (default): reads live state, prints a per-cycle plan
(
=== <cycle> @ <scope> ===), changes nothing. When a declared slice's read was tier-gated, the plan ends withNOTE: <slice>: read was tier-gated (403); planned entries may fail on apply. - apply: applies each planned entry, then prints
Applied: N, Failed: Mper cycle with oneFAILED [type] key: errorline per failure (e.g. a 403 from a tier-gated endpoint). - Guardrail: the per-collection removal cap bounds how much of any one
resource type's live entries a single apply may delete — the exact
promise lives with the delete semantics in POLICY.md. A
tripped guardrail prints
GUARDRAIL BLOCK: …, skips that cycle's apply, and exits 1;--allow-guardrail-overrideapplies anyway, and--removal-cap-fractionadjusts the threshold. - Request budget: a run has a shared budget of 1000 API requests. On
exhaustion the run stops cleanly and prints
DEFERRED (budget): <cycles>to stderr; run again (or narrow--cycles) to finish.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success: the plan printed (dry-run), or apply completed with no failures. |
| 1 | Guardrail block: apply mode, at least one guardrail tripped, and --allow-guardrail-override was not set. For migrate --strict: error-severity findings remain. |
| 2 | Argument or config error (unknown flag, unknown cycle, unreadable or invalid config, missing auth). |
| 3 | Runtime error (API failure, an errored cycle, or failed apply entries). |
In CI, that means: a dry-run job fails only on real errors, and an apply job fails loudly on a guardrail trip (1) or partial application (3). See CI.md.
Examples
# Plan everything against gitlab.com
gitlab-warden reconcile --config governance.yaml
# Apply only the flagship push-rule reconcile against self-managed
export GITLAB_TOKEN=glpat-…
gitlab-warden reconcile --config governance.yaml \
--mode apply --cycles push-rules \
--base-url https://gitlab.example.com
# Base URL and token both from the environment (CI-friendly)
gitlab-warden reconcile --config governance.yaml \
--base-url-env CI_SERVER_URL --token-env WARDEN_TOKEN