GitLab deploy tokens default to no expiry, and that expiry can only be set at creation time
This article was written with the assistance of AI.
If you created a GitLab deploy token six months ago and left the expiry field blank, that token is still valid today. It will be valid next year. It will remain valid until someone manually revokes it, because GitLab does not automatically deactivate tokens based on inactivity or age. There is no inactivity threshold, no automatic rotation, and no background job that will clean this up for you.
This is documented behavior. The GitLab documentation states: "By default, a deploy token does not expire. You can optionally set an expiry date when you create it. Expiry occurs at midnight UTC on that date."
The more significant constraint is what happens after creation: there is no documented mechanism to add or modify an expiry date on a token that already exists. If you created a token without an expiry date, your only options are to leave it in place or revoke it and create a replacement with an explicit date.
Why this compounds across projects
Deploy tokens can be created at the project level or the group level. A group deploy token applies to all projects in that group. The CI/CD variables CI_DEPLOY_USER and CI_DEPLOY_PASSWORD are automatically populated for a token named gitlab-deploy-token, but only for immediate child projects of the group, not for nested subgroups.
That scope behavior matters. A group-level token may reach more or fewer projects than the team that created it intended, depending on how the group hierarchy is structured. Without a cross-project view, there is no easy way to audit this.
GitLab surfaces deploy tokens at the project or group settings level under Settings > Repository > Deploy Tokens. There is no built-in cross-project or cross-group dashboard that lists all tokens across a tenant, shows which tokens have no expiry date, or flags tokens that have not been used recently. A team managing tokens across dozens of projects has no native tool to get a single consolidated view.
The rotation problem for gitlab-deploy-token
For the specific case where a token is named gitlab-deploy-token, the token is automatically exposed as CI_DEPLOY_USER and CI_DEPLOY_PASSWORD in pipeline variables. When you rotate such a token, you revoke the old one and create a new one. Any pipeline that has the old token value cached or hardcoded elsewhere will continue using it until the old token is revoked or those locations are updated.
The safe rotation sequence is: create the new token, update any explicit references, then revoke the old token. After revocation, run a test pipeline that exercises the credential and confirm it authenticates successfully. Then confirm the old token no longer appears in Settings > Repository > Deploy Tokens.
Operator checklist
- For each project and group, navigate to Settings > Repository > Deploy Tokens and list all active tokens.
- Note which tokens have no expiry date and assess whether each one is still required for active automation.
- Revoke any token that is no longer needed.
- For tokens that remain in use, add them to a centralized credential inventory with the creation date, scope, and intended lifespan recorded.
- If a token was created without an expiry date and cannot have one added retroactively, schedule a manual review date in your inventory.
- For group-level tokens, confirm which projects are immediate children of the group and verify that
CI_DEPLOY_USERandCI_DEPLOY_PASSWORDreach all intended pipelines. - After revoking and replacing a token, run a test pipeline that exercises the credential and confirm it completes without authentication errors.
A note on tooling
If you are tracking expiring credentials across multiple services, TokenTimer stores expiration metadata, ownership, and status for certificates, tokens, secrets, licenses, and other expiring assets without storing secret values or private key material. It supports configurable alerts through email, Slack, PagerDuty, and other channels. The self-hosted edition is available under GNU AGPL-3.0 and supports deployment with Docker Compose or Kubernetes using Helm.
That said, the checklist above is actionable without any additional tooling. The GitLab settings UI gives you everything you need to audit one project or group at a time. The gap is the absence of a tenant-wide view.
Originally published on TokenTimer.
Top comments (0)