Automate file integrity with sha512sum in CI/CD
Use sha512sum --check --strict checksums.sha512 to compare files with an approved checksum
manifest before your pipeline uses them. The command returns a nonzero exit status when verification
fails, so a changed or missing artifact can stop the job. The useful part is deciding where the
expected checksums come from.
Choose a trusted baseline
A SHA-512 checksum describes file bytes. A matching checksum does not, by itself, tell you who created those bytes. If someone can replace both a file and its expected checksum, verification can still pass.
For your own fixed assets, generate a manifest from approved files and review changes to that manifest. For a download, obtain the expected checksum through an authenticated publisher channel; when signed checksums are available, follow the publisher’s signature verification instructions first. Debian’s image verification guide shows this distinction between checking downloaded bytes and authenticating their source.
The example below records two small files as a baseline, then reuses that baseline in CI. Generating new checksums from whatever CI receives would defeat the comparison.
File verification workflow
Use Bash and GNU coreutils. These examples were tested with Bash 5.1 and coreutils 8.32 on Ubuntu 22.04, and Bash 5.3 and coreutils 9.12 on macOS. Check the implementation before continuing:
sha512sum --version
The first line should identify GNU coreutils. A command with the same name may be a different
implementation. On macOS, Homebrew’s coreutils package
provides GNU tools; follow its gnubin PATH instructions to use their unprefixed names.
Run each Bash block below from the same parent directory. The parentheses keep directory changes
inside a subshell. This setup creates a new sha512-demo directory and refuses to reuse an existing
one, so rerunning it will not overwrite your files:
(
set -eC
mkdir sha512-demo
cd sha512-demo
mkdir assets
printf 'release 1\n' > assets/app.txt
printf '{"mode":"production"}\n' > assets/config.json
)
Here, set -e stops the subshell on failure, and -C makes output redirection refuse to overwrite
an existing regular file. If setup fails, resolve the error before moving to the next block; choose
a different parent directory if you need another demo.
Generating hashes
Create the manifest once, while both files contain the approved bytes:
(
set -eC
cd sha512-demo
sha512sum -- assets/app.txt assets/config.json > checksums.sha512
)
Each line contains a 128-digit hexadecimal SHA-512 digest, a mode marker, and a filename. The explicit file list makes a missing input an error and keeps the manifest from hashing itself. For your own files, replace that list and quote filenames containing spaces.
This command also refuses to overwrite an existing checksums.sha512. If generation fails, do not
use the newly created manifest: it may be empty or incomplete. Preserve the previous approved
manifest when preparing an intentional update, and review the replacement before adopting it.
Verifying files
Check from the directory used to create the relative filenames:
(
cd sha512-demo &&
sha512sum --check --strict checksums.sha512
)
With the original files, the output is:
assets/app.txt: OK
assets/config.json: OK
--check reads the manifest and compares each named file. --strict also makes malformed checksum
lines a failure, even when other entries match. An empty manifest fails too. Do not add
--ignore-missing when every listed artifact is required. These options are documented in the
GNU sha512sum manual packaged by Debian.
To try the failure path, edit sha512-demo/assets/app.txt and run the verification block again.
It reports assets/app.txt: FAILED and exits nonzero. Restore the original approved bytes before
using the successful CI examples below; leave the manifest unchanged.
Error handling and common issues
Permission issues
The verifier needs read access to the manifest and files, plus access through their parent directories. Inspect permissions and ask the owner for appropriate access if needed. Do not broadly change ownership or make sensitive files public to get a check to pass.
Hash mismatch troubleshooting
A mismatch means the bytes differ from the baseline. A truncated download, changed line endings, or an intentional edit can cause it. Retrieve a fresh trusted copy or investigate the change; regenerating the expected checksum would hide it.
A missing-file error can also mean you ran the command from the wrong directory. Relative paths inside the manifest resolve from the process’s working directory, not the manifest’s location. For malformed lines, retrieve the original manifest rather than copying a formatted checksum table from a webpage. Keep both standard output and standard error in CI logs so you can see the cause.
CI/CD integration
For this fixed-asset example, add sha512-demo/assets/ and the approved
sha512-demo/checksums.sha512 to your repository. Both workflows below verify those checked-out
files without regenerating the manifest. Review manifest changes: a pull request that changes both
the assets and their expected hashes can pass this check.
Place verification before the step that consumes the files, and make deployment depend on its success. If your artifacts arrive from another job, retrieve them before verification and keep the approved manifest separate from that job’s generated output.
GitHub Actions example
Add this as .github/workflows/integrity.yml, or merge the verification step into an existing
workflow. It uses actions/checkout to retrieve the
repository:
name: Verify file integrity
on: [push, pull_request]
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v7
- name: Verify approved assets
working-directory: sha512-demo
shell: bash
run: sha512sum --check --strict checksums.sha512
GitHub’s explicit bash shell propagates a failing command to the step; see its
workflow shell documentation.
Leave failure suppression disabled for this step.
GitLab CI example
For a GitLab runner with a Docker executor, merge this job into .gitlab-ci.yml:
verify_integrity:
image: ubuntu:22.04
script:
- cd sha512-demo
- sha512sum --check --strict checksums.sha512
The Ubuntu image provides GNU coreutils. GitLab
fails the job when a script command exits nonzero,
including a failed directory change. Keep the commands as separate script entries and do not enable
allow_failure for this gate.
Detect changes after a Docker build
To check artifacts copied out of an image, verify those exported files against the approved manifest before distributing them. A manifest generated inside the build can detect later byte changes only while that manifest remains trusted. It cannot establish the authenticity of the build inputs or protect against someone replacing both the files and the manifest.
Know what a passing check covers
Verification reads every listed file, so large artifacts require reading all their bytes again. It checks neither unlisted files nor file ownership, permissions, or timestamps. A passing result means the listed bytes match the baseline; it does not prove the directory contains only approved files or that the build is reproducible.
