Add CEL auth role for project secrets pipeline JWT

What does this MR do?

Resolves #589520 (closed)

Phase 1 of migrating project secrets pipeline JWT from legacy bound_claims authentication to CEL-based authentication, matching the group secrets implementation.

  • Adds CEL-based pipeline auth role creation during project secrets provisioning (coexists with legacy role)
  • Introduces project_secrets_cel_pipeline_auth feature flag (disabled by default) to control which auth method is used at runtime
  • Updates ci_auth_path to include /cel/ in the login path when the flag is enabled

Why CEL-based authentication?

CEL (Common Expression Language) provides more flexible and secure authentication by:

  • Enabling complex validation logic directly in the auth role configuration
  • Reducing reliance on static bound_claims that can be limiting
  • Aligning project-level auth with the existing group-level implementation
  • Allowing dynamic policy assignment based on JWT claims

Production code

  • ProjectSecretsManagers::PipelineHelper: Added pipeline_auth_cel_program that validates project_id, subject, scope, audience, and user_id claims, dynamically generating token policies (global, environment, branch, combined). Added use_cel_pipeline_auth? method. Updated ci_auth_path to route through CEL login when the flag is on.
  • ProjectSecretsManagers::ProvisionService: Added configure_pipeline_auth_cel to create the CEL JWT role via update_jwt_cel_role, called alongside existing configure_pipeline_auth.
  • Feature flag: ee/config/feature_flags/wip/project_secrets_cel_pipeline_auth.yml

Tests

All specs test both legacy (flag off) and CEL (flag on) code paths:

  • provision_service_spec.rb — CEL role creation verification + full CEL authentication integration (success, project_id mismatch, missing/invalid subject, invalid scope, missing user_id)
  • project_secrets_manager_spec.rbci_auth_path, use_cel_pipeline_auth?, pipeline_auth_cel_program structure
  • deprovision_service_spec.rb — CEL pipeline role existence before/after deprovision
  • deprovision_project_secrets_manager_worker_spec.rb — CEL pipeline role cleanup
  • pipeline_secrets_access_spec.rb — Refactored with shared_examples and dual legacy/CEL contexts
  • authentication_boundaries_spec.rb — Added :cel_pipeline auth mount and test rows
  • runner_spec.rb — Legacy vs CEL auth path in runner API response
  • build_runner_presenter_spec.rb — Legacy vs CEL auth path in presenter output

Feature flag rollout

Name project_secrets_cel_pipeline_auth
Type wip
Default false
Rollout issue #590664

When disabled (default): Legacy bound_claims JWT authentication is used (no behavior change).

When enabled: Pipeline authentication uses the CEL-based JWT role (/cel/ in login path).

Migration strategy

This MR implements Phase 1 of a multi-phase migration:

  1. Phase 1 (this MR): Create CEL roles alongside legacy roles, feature flag controls which is used
  2. Phase 2 (future): Enable feature flag, monitor, and validate CEL auth in production
  3. Phase 3 (future): Remove legacy bound_claims auth and feature flag

Both authentication methods will coexist during rollout to ensure zero-downtime migration.

Database changes

None - this MR only modifies OpenBao configuration, not GitLab database schema.

Screenshots or screen recordings

N/A - Backend authentication change with no UI impact.

How to set up and validate locally

  1. Provision a project secrets manager
  2. Verify both legacy and CEL pipeline auth roles are created in OpenBao
  3. Toggle project_secrets_cel_pipeline_auth feature flag
  4. Run pipeline with secrets and verify authentication works in both modes
  5. Check that ci_auth_path includes /cel/ when flag is enabled

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Erick Bajao

Merge request reports

Loading