GitLab Runner Architecture, Registration, Runner Managers, Job Execution, and Lifecycle: Concepts, Architecture, and Mental Model
GitLab Runner is not merely “the program that runs scripts.” It is privileged execution infrastructure with a persistent trust relationship to GitLab, one or more runner-manager processes, explicit scope and routing rules, an executor boundary, and a lifecycle that must be observable from registration through retirement. This lesson builds that model before any registration command is used.
Learning objectives
- Trace a queued GitLab job through runner eligibility, runner-manager polling, executor preparation, job execution, trace/artifact upload, cleanup, and renewed availability.
- Distinguish a GitLab runner configuration from a runner manager process and explain why one configuration can be represented by multiple manager system IDs.
-
Explain project, group, and instance runner scope together with
tags,
run_untagged, protected-runner access, pause state, and job routing. - Differentiate the modern runner authentication token from the deprecated registration-token workflow and explain why the authentication token is sensitive host infrastructure state.
- Identify the minimum evidence needed to operate a runner safely: runner ID, manager system ID, Runner version/revision, platform/architecture, executor, tags/protection, status, jobs, and cleanup state.
1. The problem: a queued job needs infrastructure, not just YAML
Chapter 03 made the job execution boundary visible. Chapter 04 moves one layer deeper: who is allowed to execute that job, where the execution process lives, how GitLab recognizes it, and what remains after the job ends. A pipeline can compile perfectly and still wait forever because no runner is eligible. Conversely, a broadly scoped runner can execute far more repository code than its operator intended.
The core operational habit is to describe a runner precisely. “We
have a runner” is incomplete. A useful statement is: “project runner
#123 is unpaused, restricted to tag ch04-lab, does not
run untagged jobs, has one Linux/amd64 manager system ID, is running
GitLab Runner 19.3.1 with the Shell executor in a disposable lab
container, and has no production credentials.”
2. The runner execution model
flowchart TD
A[Queued job requirements] --> B[Scope + tags + protection + pause state]
B --> C[Eligible runner configuration]
C --> D[Runner manager polls GitLab]
D --> E[Manager system_id + version + executor]
E --> F[Executor prepares job environment]
F --> G[Trusted job executes]
G --> H[Trace / artifacts / job status uploaded]
H --> I[Workspace cleanup]
I --> J[Manager returns to idle / available state]
The first half of the diagram is GitLab scheduling and runner eligibility; the second half is a particular manager and executor doing work. A job that cannot pass the eligibility boundary remains pending and never reaches the executor.
3. Runner configuration and runner manager are not the same object
| Object | Meaning | Evidence |
|---|---|---|
| Runner configuration |
The GitLab-side runner object: scope, tags, protected state,
run_untagged, pause state, timeout and
ownership.
|
Runner ID/type, tags, paused/protected fields, assigned projects/groups. |
| Runner authentication token |
Long-lived secret used by a registered manager to
authenticate the runner configuration to GitLab. Modern
tokens use the glrt- prefix.
|
Stored in local config.toml; never print or
archive the value.
|
| Runner manager | One running GitLab Runner process/host/container registered under a runner configuration. | Manager system ID, version, revision, platform, architecture, contacted time, status. |
| Executor | The mechanism the manager uses to create a job environment. | Shell, Docker, Kubernetes, Docker Autoscaler, Instance, and other executor-specific metadata. |
| Job token | Short-lived job identity delivered after the runner authenticates and accepts a job. | Job context; different purpose and lifetime from runner authentication token. |
The modern creation workflow intentionally separates the reusable GitLab-side runner configuration from individual managers. The same authentication token can register the configuration on multiple hosts, and GitLab distinguishes those managers with system IDs. This is why “unregister the manager” and “delete the runner” are different lifecycle operations.
4. Registration is now a two-step ownership workflow
The recommended workflow is: (1) create a project/group/instance runner in GitLab with its scope and routing policy, then (2) register a manager using the runner authentication token. Older registration tokens are legacy, disabled by default in newer GitLab configurations, and scheduled for removal in GitLab 20.0.
# Modern shape — token value is supplied securely and never echoed.
gitlab-runner register \
--non-interactive \
--url "https://gitlab.example.com/" \
--token "$RUNNER_AUTH_TOKEN" \
--executor "shell" \
--description "ch04-disposable-manager"
With the modern authentication-token workflow, runner properties
such as tags, protected access, run_untagged, and
similar routing controls are configured when the runner object is
created in GitLab or through the supported API. Do not rely on
legacy registration-command flags to define those policies.
5. Scope is the first blast-radius boundary
| Scope | Who can use it | Typical ownership question |
|---|---|---|
| Project runner | The owning project and any explicitly assigned projects subject to current rules. | Does only this project require the capability? |
| Group runner | Projects in the group hierarchy that are allowed to use it. | Is the same controlled capability intentionally shared by a team/platform group? |
| Instance runner | Potentially broad instance-wide project population according to administration/policy. GitLab-hosted runners are instance runners. | Is the workload sufficiently generic and isolated for broad multi-project use? |
Prefer the narrowest scope that serves the requirement. Broad scope is not “more flexible” when the runner can reach sensitive networks, caches, signing keys, deployment credentials, or host state.
6. Tags, untagged jobs, and protected runners are scheduling controls
Runner tags are not Git tags. They are capabilities/selectors used
during runner matching. A runner must satisfy
all tags requested by a job. If a runner has
[linux, docker, gpu], it can satisfy a job requesting
[linux, docker]; a runner with only
[linux, docker] cannot satisfy a job that also requests
gpu.
trusted_runner_probe:
tags:
- ch04-lab
script:
- printf 'runner_id=%s
' "$CI_RUNNER_ID"
- printf 'runner_description=%s
' "$CI_RUNNER_DESCRIPTION"
- printf 'runner_tags=%s
' "$CI_RUNNER_TAGS"
- printf 'runner_version=%s
' "$CI_RUNNER_VERSION"
- printf 'runner_arch=%s
' "$CI_RUNNER_EXECUTABLE_ARCH"
For a dedicated capability runner, disabling “run untagged jobs” prevents unrelated untagged jobs from drifting onto it. Protected runners add another trust boundary by limiting eligible refs according to GitLab protected-ref rules. Tags and protection complement one another; neither substitutes for executor/host isolation.
7. Paused, online, offline, stale, and never-contacted answer different questions
GitLab-side policy says the runner should ignore new jobs. A manager may still be running and contacting GitLab.
A manager has contacted GitLab recently enough to be considered available.
No recent manager contact. This can be intentional shutdown, network failure, service failure, or retirement.
Manager contact is old enough for GitLab to classify the manager as stale/offline state.
Runner configuration exists but no manager has successfully established the expected contact yet.
Manager job-execution state; do not confuse it with runner pause policy or network reachability.
8. Version and manager identity are part of evidence
GitLab recommends keeping GitLab Runner major.minor synchronized with the GitLab major.minor version. Older/newer combinations can work, but features can depend on matching versions. For GitLab.com, which changes continuously, self-managed runner operators should keep Runner current.
Record the manager system_id, Runner version/revision,
platform, and architecture when diagnosing routing or compatibility.
If one runner configuration has multiple managers, “runner #123”
alone does not identify which machine executed a job.
v19.3.1,
the latest stable tag visible at that point. Do not silently replace
it with latest in the lab.
9. The runner authentication token is infrastructure credential material
The runner authentication token lives on the runner manager host in
config.toml and lets a process authenticate as that
runner configuration. An attacker who steals it may be able to clone
the runner identity. It therefore belongs in host secret storage,
not repository variables, artifacts, job logs, screenshots, or
course evidence.
Job execution environments should receive the job token appropriate to the job, not the runner authentication token. If the authentication token is exposed, rotate/reset it and re-establish manager configuration according to current GitLab guidance; masking the old string in a log does not undo exposure.
10. Read-only inspection before touching a runner
- Which runner ID and scope own the capability?
-
What tags, protected state,
run_untagged, and pause policy are configured? - How many managers exist under that runner configuration?
- What are their system IDs, versions, platforms, architectures, contact times, and statuses?
- Which executor does the manager use, and what trust boundary does it create?
- Which jobs has the runner processed, and are there pending jobs that actually match it?
- What host/network/cache/credential residue can survive between jobs?
Knowledge check
Why can one GitLab runner configuration show multiple managers?
The modern authentication-token workflow lets the same runner configuration be registered on multiple hosts; GitLab distinguishes manager processes with unique system IDs.
A job is pending and requests tags
[ch04-lab, gpu]. Your runner has only
[ch04-lab]. Is the runner eligible?
No. The runner must contain all tags requested by the job.
Does pausing a runner necessarily stop the local GitLab Runner process?
No. Pause is GitLab-side scheduling policy; the manager can remain running/contacting GitLab while ignoring new jobs.
Why is a runner authentication token more sensitive than ordinary runner metadata?
It authenticates a manager as the runner configuration and can potentially be used to clone that runner identity if stolen.
Why record a manager system ID in addition to the runner ID?
A runner configuration can have multiple managers; the system ID identifies the specific manager host/process involved in execution or diagnostics.
Official references and version notes
- Runners — runner categories, job scheduling, GitLab-hosted versus self-managed runners, and execution flow.
- Manage runners — project/group/instance scope, creation workflow, ownership and pause/resume operations.
-
Configure runners
— tags,
run_untagged, protected runners, authentication-token rotation, and routing behavior. - Registering runners and new runner creation workflow — current runner authentication-token registration and deprecated legacy registration-token behavior.
-
GitLab Runner commands
—
register,list,verify,run,stop, andunregisterlifecycle commands. -
Runner fleet planning
— manager
system_ididentity and modern unregister/delete distinctions. - Runners API — runner details, managers, status, pause, job history, authentication-token reset, and deletion semantics.
- Security for self-managed runners — remote-code-execution trust, Shell executor risk, persistent-runner residue, isolation, and credential exposure.
- GitLab Runner documentation — current compatibility guidance recommends keeping Runner major.minor aligned with GitLab; GitLab.com users should keep self-managed runners current.
Version-sensitive statements were rechecked against current
primary GitLab documentation and the GitLab Runner release history
on 2026-09-11. The latest stable Runner tag
visible in the upstream release history at that verification point
is v19.3.1 (2026-08-24); GitLab 19.4 is scheduled
after this guide-authoring date, so executable examples pin
gitlab/gitlab-runner:v19.3.1 instead of a moving
latest tag. The legacy runner-registration-token
workflow is deprecated and scheduled for removal in GitLab 20.0;
this chapter uses runner authentication tokens and the modern
creation workflow.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.