Chapter 15Lesson 04~175 minutes

Multi-Project Pipelines, Downstream Triggers, Cross-Project Dependencies, and Platform-Oriented Delivery: Diagnostics, Failure Modes, Security, and Performance

Cross-project failures often look like generic 404, 403, pending, or green-pipeline problems. This lesson diagnoses them by preserving both project/ref/SHA identities, trigger evidence, job-token authorization, forwarded data, downstream status, and artifact/API semantics before changing anything.

Multi-project pipelinesCI_JOB_TOKENDownstream triggersAuthorizationPlatform delivery

Learning objectives

  • Diagnose mutable-ref drift, job-token allowlist failures, excessive forwarding, status misunderstandings, and circular trigger chains.
  • Preserve upstream/downstream IDs, SHAs, trigger job evidence, HTTP status, and first downstream failure before retrying.
  • Separate a downstream-creation failure from downstream job execution, API authorization, artifact retrieval, and external deployment failures.
  • Repair the smallest causal edge without broad PATs, secret forwarding, policy bypass, or blind retries.
  • Measure trigger/queue/runtime and fan-out evidence before blaming runner capacity for orchestration latency.

1. Diagnose across both projects before changing either

Preserve the upstream pipeline ID/source/ref/SHA, trigger job ID/status, requested downstream project/ref/strategy, downstream pipeline ID/ref/SHA/source, first failing downstream job, and any sanitized HTTP authorization response. Without both identities, a retry can hide whether the failure was ref drift, creation permission, job-token policy, runtime execution, or artifact selection.

2. Evidence-first diagnostic sequence

  1. Preserve upstream pipeline/job IDs and first trigger/downstream failure.
  2. Confirm upstream source/ref/SHA and expanded trigger configuration.
  3. Confirm requested downstream project/ref, input values, forwarding policy, and strategy.
  4. Confirm whether a downstream pipeline ID was created.
  5. If created, confirm downstream source=pipeline, ref, exact SHA, job graph, queue, runner, and toolchain.
  6. For API access, confirm token type, source project, target project, allowlist/fine-grained permissions, triggering-user access, endpoint, and HTTP status.
  7. For artifact/report access, confirm tier, producer project/ref/SHA/job, retention, and selection semantics.
  8. Repair only the causal edge and rerun the smallest safe scope.

3. Failure: downstream runs a different commit from the one reviewed

Symptom: upstream requested main, but downstream SHA differs from the SHA recorded during review. The pipeline may be green and still be wrong.

Cause: a moving ref advanced between review and trigger, or the orchestrator never pinned/governed the ref.

Repair: use a governed release ref appropriate to the downstream project's policy and verify its actual SHA. Do not “fix” this by copying downstream code into the upstream repository.

4. Failure: job-token request returns 403/404

Do not print the token. Capture the HTTP status, source project ID, target project ID, endpoint, and current target allowlist state. Then check:

  • Is the token source project/group actually on the target allowlist?
  • Does the triggering user already have sufficient target-project access?
  • Is the endpoint supported for CI_JOB_TOKEN?
  • Did fine-grained permissions omit the needed read capability?
  • Is the target public/internal in a way that changes expected visibility behavior?

Adding a PAT is not the diagnostic fix. It changes the identity model and can mask the authorization design error.

5. Failure: a secret is forwarded as an ordinary variable

Masked-variable properties do not safely carry into another project when you forward YAML variables. A value can appear unmasked in downstream logs or be overridden at unexpected precedence.

Repair: stop forwarding the secret. Give the downstream job its own least-privilege identity or secret retrieval path, and pass only non-secret identifiers/inputs needed to select that identity.

6. Failure: upstream is green while downstream failed

Symptom: the trigger job passed because GitLab created the downstream pipeline, but downstream later failed.

Diagnosis: inspect the trigger strategy. Default creation semantics were mistaken for completion semantics.

Repair: if downstream success is part of upstream completion, use strategy: mirror. If not, keep loose coupling and monitor/correlate downstream independently rather than falsely mirroring.

7. Failure: circular trigger chain

Project A triggers B and a rule in B triggers A again. This can create runaway pipelines, cost, noisy status, and confusing authorization.

Preserve the first upstream/downstream IDs and CI_PIPELINE_SOURCE values. Then introduce explicit source guards, ownership rules, and bounded orchestration. Do not rely on manually canceling “latest” pipelines as a control mechanism.

# Downstream guard example
accept-from-platform:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "pipeline" && $UPSTREAM_ROLE == "orchestrator"'
    - when: never
  script:
    - echo "bounded orchestration path"

In production, prefer typed input identity over an unvalidated user-provided variable for such guards.

8. Failure: artifact access succeeds but retrieves stale bytes

A successful needs:project retrieval does not prove it came from the pipeline you just triggered. Its current semantics use the latest successful job for the specified ref and do not wait for an in-progress pipeline on that ref.

Record producer project/ref/SHA/job/pipeline and verify a digest. If exact same-run coupling is required, redesign the exchange around immutable publication identity or explicit producer IDs rather than a moving ref.

9. Failure: trigger job remains pending

Trigger jobs do not use runners. First inspect downstream project/ref existence and the triggering user's downstream permission. Runner fleet state becomes relevant only after a downstream job exists and enters the queue.

10. Performance: measure orchestration latency separately from runtime

Metric What it reveals Do not confuse with
Trigger creation latency Permission/ref/config creation path Runner queue time
Downstream queue time Runner capacity/routing Cross-project trigger latency
Downstream critical path Job graph/tool runtime Allowlist latency
API callback latency/rate limits Cross-project metadata integration Pipeline compile time
Artifact transfer bytes/time Data coupling/storage/network cost Trigger correctness

11. Intentionally broken example: wrong allowlist direction

Suppose upstream triggers downstream successfully, then downstream calls upstream Commit API and receives 404. An operator adds upstream to the downstream allowlist. The retry still fails.

The error is conceptual: allowlists are configured on the project whose resource is being accessed. Downstream's job token originates in downstream; upstream owns the commit resource. Therefore upstream must allowlist downstream, and the triggering user must also have upstream permission.

Preserve the failed request status and project IDs, correct only the allowlist direction, then rerun only the downstream job/pipeline scope needed to verify access.

12. Security constraints for troubleshooting

  • Never print CI_JOB_TOKEN, PATs, trigger tokens, deploy tokens, or authorization headers.
  • Do not disable TLS or broaden project visibility to “make the API work.”
  • Do not forward protected variables into an untrusted downstream project.
  • Do not change both source/target allowlists, user roles, and refs at once; you would destroy causal evidence.
  • Do not use untrusted code on privileged runners simply because cross-project orchestration needs network access.

13. Recovery rule: smallest safe scope

If creation failed, retry only after fixing trigger/ref/permission state. If downstream configuration failed, validate that project without re-running upstream build work. If one downstream job failed, retry that job only when its scripts are idempotent and no side effect would duplicate. If an artifact identity was wrong, do not rebuild the intended release artifact as a shortcut; locate/verify the correct producer.

Knowledge check

A trigger job is pending and no downstream pipeline ID exists. Should you add runners?

A downstream API call is denied. What two authorization facts must both be true?

Why is forwarding a masked variable to another project unsafe?

Why can a green needs:project consumer still use the wrong artifact?

What is the least destructive fix for wrong allowlist direction?

Next lesson

Checkpoint lab

Build the two-project mirrored chain, verify exact downstream SHA, repair one intentional authorization failure, and produce the evidence packet.

Version and compatibility note

GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.

Official references and version notes

Documentation verification date: 2026-09-11. Multi-project trigger syntax, downstream inputs/forwarding, CI_JOB_TOKEN permissions, allowlist controls, artifact APIs, and needs:project are version-sensitive. Re-check the GitLab version deployed on Self-Managed or Dedicated instances before relying on newer behavior.

  • Downstream pipelines — multi-project triggers, downstream source values, trigger strategies, inputs, variable forwarding, and cross-project artifact patterns.
  • CI/CD job token — token lifetime, user-derived permissions, cross-project allowlists, security, and current allowlist controls.
  • Fine-grained job-token permissions — optional endpoint-level restrictions for allowlisted projects/groups.
  • Trigger pipelines with the API — trigger tokens, CI_JOB_TOKEN multi-project API triggers, source semantics, and revocation guidance.
  • CI/CD YAML syntax reference — trigger, trigger:strategy, trigger:forward, needs:project, and current tier constraints.
  • Job Artifacts API — artifact download by job/ref and the current tier requirement for cross-project job-token downloads.
Current behavior used by this chapter: Multi-project downstream pipelines are available across GitLab offerings. The user who starts the upstream pipeline must also be authorized to start a pipeline in the downstream project. Jobs in a multi-project downstream pipeline see CI_PIPELINE_SOURCE=pipeline. By default, a trigger job succeeds when GitLab successfully creates the downstream pipeline; strategy: mirror makes the trigger job track downstream status, while strategy: depend is not recommended for new designs. Downstream inputs are preferred over broad variables when defining a configuration contract. CI_JOB_TOKEN exists only while a job runs; target projects restrict cross-project token use with an allowlist, and allowlisting does not grant project membership. Current allowlists support up to 200 group entries and 200 project entries. needs:project and CI_JOB_TOKEN-authenticated Job Artifacts API downloads across projects are Premium/Ultimate features, so this chapter's mandatory path uses Free-tier allowlisted API metadata access and treats cross-project artifact transfer as optional/simulated.

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.