Admission Controller scoping
Admission Controller Scoping - First Iteration
Goal
Define the scoping model for Runner Admission Controllers in the first iteration, establishing a flexible database structure that supports instance-level scoping while enabling future expansion to group and project levels.
Current State
Runner (Admission) Controllers are currently implemented at the instance level in Rails (see #578037 (closed) and #578797 (closed)).
Problem Statement
The current instance-level scoping is too broad for organizations that need fine-grained control. For example, a macOS runner team should be able to enforce admission controllers only on their specific runners without affecting other runners on the instance.
Proposed Solution
Database Schema: Postgres Inheritance Pattern
We will implement a parent-child table structure using Postgres inheritance to support multiple scoping types:
Parent Table: ci_runner_controller_scopings
Child Tables (via Postgres Inheritance):
-
ci_runner_controller_scopings_instance- Instance-level scoping-
runner_controller_id→ referencesci_runner_controllers -
type= 'instance' -
target_id= NULL (applies to entire instance)
-
-
ci_runner_controller_scopings_group- Group-level scoping (maybe future iteration)-
runner_controller_id→ referencesci_runner_controllers -
type= 'group' -
target_id→ referencesnamespaces(group)
-
-
ci_runner_controller_scopings_project- Project-level scoping (maybe future iteration)-
runner_controller_id→ referencesci_runner_controllers -
type= 'project' -
target_id→ referencesprojects
-
-
ci_runner_controller_scopings_runners- Runner-level scoping (future iteration)-
runner_controller_id→ referencesci_runner_controllers -
type= 'runner' -
target_id→ referencesrunners
-
Behavior Model
When a job is dequeued for execution on a runner:
-
Query all applicable admission controllers from
ci_runner_controller_scopings:- Instance-level controllers (always included)
- Group-level controllers (if job's project belongs to a scoped group)
- Project-level controllers (if job's project is scoped)
- Runner-specific controllers (if runner has scoped controllers)
- Return controller list to the Job Router/Runner with the job response
- All returned controllers MUST pass before the job can be executed
Cells Consideration
This design is compatible with GitLab's Cells architecture:
- Each cell maintains its own
ci_runner_controller_scopingstable - Instance-level scoping applies within a cell's scope
- Group, project and runner scoping are naturally cell-aware (groups/projects/runners belong to specific cells)
- No cross-cell coordination required for admission control decisions
First Iteration Scope
In this iteration, we will:
-
✅ Implement the parent table structure with instance-level scoping -
✅ Addenabledflag to Runner Controllers (prevents chicken-and-egg problem) (WIP: Implement `enabled` field in runner controller (!215485)) -
✅ Support querying applicable controllers during job dequeue -
✅ Establish the inheritance pattern for future scoping types
Related Work Items
- #578037 (closed) - Runner Controller implementation
- #578797 (closed) - Runner Controller integration
- #583132 - Enabled/disabled state for controllers