Image promotion (gate before tag)
Under an Enforce security policy, Loha holds a new image back until the
final security gate passes. Your build pushes the image to a temporary
loha-q-* tag in the same repository. When the gate passes, Loha moves the tag
you asked for (for example :main or :latest) onto exactly that image. When
the gate blocks the build, the tag you asked for stays on the previous image.
Anything that pulls your image by tag — a server running docker pull, a
cluster with imagePullPolicy: Always, a GitOps tool watching a tag — only
ever sees images that passed the gate.
Image promotion is behind a workspace feature flag. If the build's Security tab has no Image promotion section, it is not enabled for your workspace.
When it applies
All of these must be true for an image step (buildah-build or docker-build):
- The workspace's security policy is in Enforce mode. Observe and Off push exactly as before.
- The step pushes to a registry your operator supports for managed scans, and the workspace has its own credential for it under Settings → Registries. Loha moves the tag with that credential.
- The step's
IMAGEnames a tag (or none, which meanslatest), not a digest, and itsIMAGEcontains no${VARIABLE}that is only resolved while the step runs. - The step is one of the first 10 image steps in the pipeline. Image steps after the tenth are never promoted.
Under Enforce, a step that does not qualify pushes straight to the tag you asked
for, and the build shows a PROMOTION_UNAVAILABLE warning naming it. Under
Observe and Off, such steps get no warning.
What you see
The build's Security tab has an Image promotion section:
| Status | Meaning |
|---|---|
| Waiting for the gate | The image is under its loha-q-* tag; the gate has not decided yet. |
| Promoting | The gate passed; Loha is moving your tag. |
Promoted to :tag | Your tag now points at the gate-passed image. |
| Held | The tag was not moved, with the reason (for example, the gate blocked). |
| Promotion failed | Loha could not move the tag. A failed job is retried; a missing registry credential or an unsupported registry fails at once. Fix the credential, then press Retry. |
loha builds security <build-id> prints the same list.
If the build did not succeed, rows that are still waiting show Held about 10 minutes after the build ends.
A held image is never promoted: the gate did not pass it. Fix the finding and build again.
Things to know
- Later steps in the same pipeline. The tag moves after the whole build
passes the gate, so a later step that pulls
app:mainstill gets the previous image. Use the step'sIMAGE_URLresult ($(tasks.<step>.results.IMAGE_URL)) to refer to the image this build made. - Signatures. Image signatures and attestations bind to the image digest,
not the tag. Once the image is signed,
cosign verify <repository>:<tag>works on the moved tag. Signing can finish shortly after the tag moves. - Older builds never win a tag. An older build never moves a tag back over a newer promoted build: its promotion is held as Superseded, and Retry is refused.
- Delivery deploys by digest and is not affected.
loha-q-*tags stay in your registry. Loha does not delete them, because deletion works differently in every registry. Add a retention rule in your registry that removes tags matchingloha-q-*after a few days (for example 7). Never delete the tag your deployments use.- Failures are safe. If moving the tag fails, the tag stays on the previous image; it never points at an image the gate did not pass.