Suppose the bfstore catalog service is built three times:
DEVELOPMENT
build catalog from commit 8f31c2a
STAGING
build catalog from commit 8f31c2a again
PRODUCTION
build catalog from commit 8f31c2a again
All three builds begin with the same Git commit.
That does not guarantee they produce the same software.
The staging build may use a newer base image. A dependency repository may return a different package. The compiler, operating-system tools or build configuration may have changed. A generated file may contain another timestamp.
By the time the production build exists, the organisation has tested two relatives of the production artefact.
It has not necessarily tested the artefact it is about to deploy.
That is the problem behind a simple release-engineering principle:
Build once, then promote the same immutable artefact through every environment.
The stronger path is:
SOURCE REVISION
│
▼
APPROVED BUILD PROCESS
│
▼
CANDIDATE ARTEFACT
│
├──► TEST
├──► SCAN
└──► ANALYSE
│
▼
ELIGIBLE ARTEFACT
│
├────────┼────────┐
▼ ▼ ▼
development staging production
The artefact stays the same.
What changes is the evidence accumulated around it and the environments permitted to run it.
A source revision is not a release artefact
A Git commit identifies source files.
It does not identify the complete result of a build.
The output also depends on things such as:
- compiler and linker versions
- dependency versions
- container base images
- package repositories
- build flags
- generated code
- environment variables
- timestamps
- the build system itself
The relationship is closer to:
SOURCE
+
DEPENDENCIES
+
BUILD TOOLS
+
BUILD CONFIGURATION
=
ARTEFACT
Two builds from the same source commit can therefore produce different binaries or container images.
That difference may be intentional. Rebuilding after a base-image security update should create a new artefact.
But it is still a new artefact.
It needs its own identity and its own evidence.
The commit identifies what we intended to build. The artefact identifies what the build actually produced.
Reproducible builds complement this model.
If independently repeated builds produce the same output, that strengthens verification of the build process. It does not remove the value of promotion. A repeated build is still a new build event whose inputs, builder and evidence should be recorded before release.
Rebuilding and promotion are different operations
A rebuild creates new executable content.
Promotion changes where an existing artefact is approved to run.
REBUILD
source
│
▼
new artefact
PROMOTION
existing artefact
│
▼
new environment
Suppose CI publishes:
bfstore/catalog-service
digest: sha256:7b91...
Development deploys that digest and confirms that the service starts.
Staging deploys the same digest and exercises its database, gRPC and Kafka integrations.
Production should receive that digest too.
If production rebuilds the source, it creates another evidence boundary. The staging tests belong to the staging artefact, not automatically to the new production build.
Building once preserves the chain:
ARTEFACT
sha256:7b91...
│
▼
development evidence
│
▼
staging evidence
│
▼
production approval
Trust accumulates around one stable object.
Tags label; digests identify
A container image may be tagged:
bfstore/catalog-service:1.8.0
The tag is convenient for people.
Depending on registry policy, it may also be moved.
At 09:00:
catalog-service:1.8.0
│
▼
digest A
At 14:00:
catalog-service:1.8.0
│
▼
digest B
The visible tag has not changed. The content behind it has.
A digest identifies the image content itself:
bfstore/catalog-service@sha256:7b91...
Changing the image changes the digest.
That gives the delivery system a stable answer to:
Which exact artefact passed these tests and received this approval?
Tags and digests can serve different purposes:
| Reference | Useful meaning |
|---|---|
1.8.0 |
Human-facing release label |
candidate |
Movable pointer to the current release candidate |
production |
Movable pointer defined by the organisation’s release policy |
sha256:7b91... |
Exact immutable image content |
The meaning of a lifecycle tag should be explicit.
“Approved for production” and “currently running in production” are different states.
Where an image reference represents multiple platforms, the delivery system should also record the content resolved for each target platform. The digest remains the strong identity, but the level at which it is recorded should match what actually ran.
Immutable does not mean permanently approved
An immutable artefact cannot be altered while retaining the same identity.
It can still be:
- superseded
- quarantined
- denied further promotion
- removed under a retention policy
- replaced by a patched release
Immutability means:
ONE ARTEFACT IDENTITY
always refers to
ONE SET OF CONTENT
It does not mean every experimental build must occupy registry storage until the sun cools.
Retention is a separate policy.
Production and recent release artefacts may need longer retention because they support investigation and rollback. Temporary branch builds may have a much shorter lifecycle.
Eligibility can also change while the artefact does not.
An image may pass its vulnerability policy today. A serious vulnerability affecting one of its packages may be disclosed next week.
MONDAY
artefact eligible
FRIDAY
new vulnerability published
ARTEFACT
unchanged
PROMOTION STATUS
may change
The organisation’s knowledge has changed, not the bytes.
A release system may rescan stored images, block further promotion, identify running deployments by digest and revoke approval for severe findings.
Immutability does not freeze the security decision.
It makes it possible to identify exactly which stored and running artefacts are affected.
Configuration remains separate and traceable
Development, staging and production are not identical.
They may use different:
- database endpoints
- credentials
- replica counts
- resource limits
- log levels
- domain names
- feature settings
- network policies
That does not require separate application builds.
ONE IMAGE
catalog-service@sha256:7b91...
│
├── development configuration
├── staging configuration
└── production configuration
The image should contain the application and its runtime dependencies.
The environment should provide the configuration needed to operate it there.
This avoids producing:
catalog-dev
catalog-staging
catalog-production
as three supposedly equivalent images.
Environment-specific builds weaken the evidence chain and create more artefacts to understand, scan, retain and recover.
The same executable can still behave differently under different configuration and infrastructure. Building once does not remove that risk. It removes rebuilding as another source of unexplained difference.
The digest therefore identifies the executable content, not the complete deployed release.
A useful release record may contain:
application artefact:
sha256:7b91...
deployment declaration:
commit a42d6e1
environment configuration:
version prod-184
The complete release identity includes the artefact and the controlled declaration under which it runs.
Evidence and provenance need one stable subject
A release system can gather several forms of evidence:
- test results
- vulnerability scans
- software bills of materials
- provenance attestations
- signatures
- deployment approvals
- runtime observations
That evidence should refer to the exact artefact.
For example:
artefact:
sha256:7b91...
source:
commit 8f31c2a
unit tests:
passed
integration tests:
passed
container scan:
passed policy
SBOM:
attached
builder:
approved catalog release workflow
If the artefact is rebuilt and receives a new digest, the earlier evidence does not silently transfer.
The new object may be safe.
It simply requires evidence of its own.
Provenance adds the production history:
REVIEWED SOURCE
│
▼
APPROVED BUILDER
│
▼
RECORDED BUILD PROCESS
│
▼
IMMUTABLE DIGEST
Different evidence answers different questions:
| Evidence | Question answered |
|---|---|
| Digest | Which exact content is this? |
| Provenance | Where and how was it built? |
| Signature | Which trusted identity vouched for it? |
| Tests | Which behaviours were exercised? |
| Vulnerability scan | Which known problems were detected? |
| SBOM | Which software components are present? |
No one item carries the whole release decision.
The digest gives them one stable subject.
Exact identity improves recovery and investigation
Suppose catalog version 1.8.0 causes an unexpected increase in errors.
A useful release record contains:
current digest:
sha256:7b91...
previous digest:
sha256:24ac...
The system can redeploy the exact previous artefact.
That is different from checking out the old source revision and rebuilding it.
PROMOTION-BASED ROLLBACK
redeploy known previous artefact
REBUILD-BASED ROLLBACK
create a new artefact from old source
The first returns to executable content that already has evidence and production history.
The second creates another output that may differ from the original release.
Exact identity also improves incident investigation.
A running digest can be connected to:
- source
- build logs
- tests
- SBOM
- provenance
- security findings
- deployment history
- the declaration and configuration used in that environment
RUNNING WORKLOAD
│
▼
ARTEFACT DIGEST
│
├──► BUILD AND SECURITY EVIDENCE
│
└──► RELEASE DECLARATION
The investigator can study the exact software and release context involved rather than reconstructing an approximate sibling from source.
Artefact rollback still has limits.
The newer version may already have changed a database schema, written new data, published events, called external providers or altered shared configuration.
Immutable artefacts make executable rollback precise.
Application compatibility and recovery determine whether the wider system can safely move backwards.
A bfstore release path
Suppose commit 8f31c2a updates the catalog service.
Build
CI checks out the exact revision, runs the required tests and analysis, creates the container image, scans it, publishes it by digest and records provenance and an SBOM.
The result is:
source:
8f31c2a
image:
bfstore/catalog-service@sha256:7b91...
status:
eligible for development
Development
The development declaration is updated to that digest.
The environment verifies startup, health and basic service behaviour.
Staging
The same digest is promoted.
Staging exercises database, gRPC and Kafka integrations under production-shaped settings.
Production
A reviewed change promotes the same digest.
The delivery system verifies its provenance and approval before beginning a canary rollout.
No application rebuild occurs.
Recovery
The release record retains the previous production digest and the declarations associated with both releases.
If the rollout fails its acceptance criteria, the platform can restore the known previous artefact while the team evaluates any data or workflow consequences separately.
SOURCE
│
▼
ONE BUILD
│
▼
ONE DIGEST
│
├──► development
├──► staging
└──► production
The artefact identified in development is the same artefact promoted to staging, where it is exercised under staging conditions.
The artefact approved after staging is the artefact offered to production.
What immutable artefacts do not solve
Building once does not guarantee:
- correct source code
- secure dependencies
- valid production configuration
- compatible database changes
- sufficient capacity
- correct IAM
- healthy downstream services
- safe rollback
- successful business outcomes
It gives the delivery system something narrower and extremely valuable:
A stable executable object to which evidence, approval and runtime history can be attached.
That allows failures in other layers to be investigated without also wondering whether each environment received subtly different software.
Build once, promote many is not primarily a build-performance optimisation.
It protects the connection between evidence and execution.
Without that continuity, each environment receives a newly built relative carrying confidence earned by somebody else.
With it, the organisation can keep making one precise claim:
This is the exact artefact we built, tested, approved and deployed.
References and further reading
Kubernetes: Images Explains image names, tags, digests and image-pull behaviour.
Docker: Image digests Introduces content-addressed image identities and the distinction between tags and digests.
Continuous Delivery, Jez Humble and David Farley Explores deployment pipelines, release candidates and promotion through environments.
SLSA provenance Describes verifiable information connecting software artefacts to source and build systems.
Sigstore documentation Introduces signing and verification for software artefacts.
CycloneDX Defines a standard for software bills of materials.