Chapter 04Lesson 01~115 minutes

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.

Runner architectureRunner managerScope & tagsAuthentication tokenLifecycle

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.
Runner trust rule. A self-managed runner is a remote-code-execution service for repository-controlled jobs. Scope, tags, protection, executor, credentials, host/network reachability, version, and cleanup are security state—not convenience settings.

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

Runner lifecycle — eligibility precedes execution
            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

Paused

GitLab-side policy says the runner should ignore new jobs. A manager may still be running and contacting GitLab.

Online

A manager has contacted GitLab recently enough to be considered available.

Offline

No recent manager contact. This can be intentional shutdown, network failure, service failure, or retirement.

Stale

Manager contact is old enough for GitLab to classify the manager as stale/offline state.

Never contacted

Runner configuration exists but no manager has successfully established the expected contact yet.

Idle / running

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.

Current reproducibility pin: this chapter was verified on 2026-09-11 against GitLab Runner 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?
Next lesson

Guided Hands-On Workflow and Core Operations

Create one isolated project runner, register a disposable manager, prove uniquely tagged routing, exercise pause/stop/resume states, and retire the manager safely.

Knowledge check

Why can one GitLab runner configuration show multiple managers?

A job is pending and requests tags [ch04-lab, gpu]. Your runner has only [ch04-lab]. Is the runner eligible?

Does pausing a runner necessarily stop the local GitLab Runner process?

Why is a runner authentication token more sensitive than ordinary runner metadata?

Why record a manager system ID in addition to the runner ID?

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, and unregister lifecycle commands.
  • Runner fleet planning — manager system_id identity 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 and compatibility note

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.