Skip to content
← DevOps foundations

Learning bite

Credentials and artifact publication

Separate testing untrusted code from publishing with scoped authority.

Documentation reviewed2026-10-01 · 3 min read
On this page

Give a job only the access its work needs

Testing a pull request usually needs source access. Publishing an image or deploying infrastructure needs additional authority. Separate those operations so untrusted proposed code does not automatically receive release credentials. A short-lived token still permits all of its allowed actions during its lifetime.

GitHub's GITHUB_TOKEN has configurable permissions for its workflow context. For cloud access, OIDC can let a workflow exchange a verifiable identity for temporary credentials. The cloud's trust policy must restrict the intended repository, branch or environment, and audience. id-token: write allows the job to request an OIDC token; it does not independently grant AWS permissions or choose a safe trust policy.

Name the output that crosses jobs

A cache reuses inputs or intermediate work to save time, such as downloaded dependencies. An artifact preserves an output, such as a test report, package, or image archive. A release image in a registry is also a build artifact, identified using the image concepts from the Docker module. A cache hit does not prove release content is trusted or complete.

Source and checks lead to one identified build artifact; approved environments select that same identity with their own configuration, while dependency caches remain outside the release path.

Read the diagram in order: (1) checks belong to a source revision; (2) the build yields an identified artifact; (3) deployment selects it with target configuration; (4) behavior checks decide whether to continue. The cache supports the build but is not promoted as the release. Open the diagram.

Rehearse an artifact check locally

In a new artifact-practice directory, save release.txt containing the single line fixture release. Run this standard-library example as verify_artifact.py:

python
import hashlib
from pathlib import Path

path = Path("release.txt")
expected = hashlib.sha256(path.read_bytes()).hexdigest()
Path("release.sha256").write_text(expected + "\n", encoding="utf-8")
received = hashlib.sha256(path.read_bytes()).hexdigest()
assert received == Path("release.sha256").read_text().strip()
print("artifact bytes match the recorded checksum")

Expect the message. Now add a second line to release.txt and compare its newly computed hash with the previously saved checksum in a separate check; do not rerun the script's checksum-writing step first. The comparison should differ. Save this separate check_artifact.py and run it after changing the file:

python
import hashlib
from pathlib import Path

actual = hashlib.sha256(Path("release.txt").read_bytes()).hexdigest()
expected = Path("release.sha256").read_text().strip()
if actual != expected:
    raise SystemExit("artifact changed after the checksum was recorded")
print("artifact matches")

Expect a nonzero exit and the change message. Restore the original single line, including its newline, and expect artifact matches. This demonstrates byte identity. Because the same person can replace both files, a checksum alone does not prove trusted authorship or provenance.

For a real workflow, record source revision, build inputs, test result, artifact identity, and platform at publication. The consumer verifies the intended record rather than rebuilding an unrelated output under the same name. An ARM Mac and an AMD64 hosted runner also require an explicit platform plan.

Protect the producer and consumer

Do not combine privileged pull_request_target execution with checkout and execution of untrusted PR code. Do not interpolate untrusted event text directly into shell source. A less-privileged job's downloadable file is still untrusted input to a privileged consumer unless its origin and contents are checked appropriately.

Review and pin external actions. Avoid secrets in logs, archives, or build contexts. Set retention and visibility deliberately; an uploaded environment dump can expose far more than the failure being investigated. Choose an owned registry and scoped publishing identity before implementing a push, not an example namespace.

Checkpoint: if the dependency lockfile changes, why revisit a cache key? The reusable inputs may have changed. If application source changes but dependencies do not, can the old release artifact be reused as the new release? No; the build output needs a new identity and appropriate checks. Next, make the deployment and recovery decision explicit.

References: OIDC↗, token permissions↗, workflow artifacts↗, and workflow security↗.

Your notes and evidence

Record observations, questions, or links to your work. Keep credentials out of your notes.

Loading saved progress…

Back up or restore this path

Progress and notes stay in this browser. A backup contains only this learning path.