A Vault secrets engine for GitLab tokens
GitLab tokens live in CI variables for a year at a time, and nobody remembers which ones are still there.
GitLab access tokens have a maximum lifetime and no natural home to live in while they wait to be used.
So they end up pasted into a CI variable, or a Kubernetes secret, or somebody’s .netrc, and they sit there for a year until they expire and something breaks at an inconvenient time.
Vault already solves this shape of problem for databases and for AWS, where you ask for credentials, you get ones that exist for an hour, and Vault takes them away afterwards.
There was no such thing for GitLab, so I wrote one, and it works the same way the database engines do.
We configure it once with a GitLab token that is allowed to create tokens, then we define roles.
After that anything that can authenticate to Vault can ask for a GitLab token scoped the way the role says.
vault read gitlab/token/my-roleWhat comes back is a real GitLab token with a real expiry on it, and when the Vault lease ends the plugin goes and revokes it on the GitLab side.
The part that took the longest to get right is the token the plugin itself uses.
It’s a GitLab token like any other, which means it expires like any other.
A secrets engine that stops working after a year because its own credential died is not much of an improvement on what it replaced.
So the plugin rotates its own configuration token, before that token gets anywhere near its expiry.
vault write gitlab/config \ base_url=https://gitlab.com \ token=glpat-xxxxxxxx \ auto_rotate_token=true \ auto_rotate_before=48hWith that set, Vault rotates the token before it expires and stores the new one itself, and the token you pasted in at setup is not the token it’s still using six months later.
That behaviour caused more confusion than anything else in the plugin.
auto_rotate_before only fires when the token is already inside that window, so if we set it and read the config straight back, nothing appears to have happened.