This document describes the artifacts produced by each SecAI_OS tagged release and how to verify them independently. All artifacts are generated by .github/workflows/release.yml.
Last updated: 2026-03-14
A release tag (e.g. v1.0.0) produces the following artifacts:
v1.0.0/
# Go service binaries (linux/amd64 + linux/arm64)
airlock-linux-amd64
airlock-linux-arm64
registry-linux-amd64
registry-linux-arm64
tool-firewall-linux-amd64
tool-firewall-linux-arm64
gpu-integrity-watch-linux-amd64
gpu-integrity-watch-linux-arm64
mcp-firewall-linux-amd64
mcp-firewall-linux-arm64
policy-engine-linux-amd64
policy-engine-linux-arm64
runtime-attestor-linux-amd64
runtime-attestor-linux-arm64
integrity-monitor-linux-amd64
integrity-monitor-linux-arm64
incident-recorder-linux-amd64
incident-recorder-linux-arm64
# Per-service CycloneDX SBOMs (JSON)
airlock-sbom.cdx.json
registry-sbom.cdx.json
tool-firewall-sbom.cdx.json
gpu-integrity-watch-sbom.cdx.json
mcp-firewall-sbom.cdx.json
policy-engine-sbom.cdx.json
runtime-attestor-sbom.cdx.json
integrity-monitor-sbom.cdx.json
incident-recorder-sbom.cdx.json
agent-sbom.cdx.json
ui-sbom.cdx.json
quarantine-sbom.cdx.json
common-sbom.cdx.json
diffusion-worker-sbom.cdx.json
search-mediator-sbom.cdx.json
# Checksums and signature
SHA256SUMS # sha256sum of every artifact above
SHA256SUMS.sig # cosign detached signature over SHA256SUMS
The container image is published to ghcr.io/secai-hub/secai_os and is identified by its SHA256 digest:
ghcr.io/secai-hub/secai_os@sha256:a1b2c3d4e5f6... (example)
The digest is immutable and can be used in place of a mutable tag for pinned deployments.
The SHA256SUMS file contains one line per artifact with its SHA256 hash:
e3b0c44298fc1c149afbf4c8996fb924... airlock-linux-amd64
7d865e959b2466918c9863afca942d0f... airlock-linux-arm64
...
SHA256SUMS.sig is a cosign detached signature over that file, created with:
cosign sign-blob --yes \
--key cosign.key \
--output-signature SHA256SUMS.sig \
SHA256SUMSEach service gets a CycloneDX JSON SBOM generated by Syft. These SBOMs list all direct and transitive dependencies for the service.
Go services (9): SBOMs are generated from the Go module graph. Python services (6): SBOMs are generated from directory scanning (requirements.txt, pyproject.toml, etc.).
Example SBOM structure (abbreviated):
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"serialNumber": "urn:uuid:...",
"version": 1,
"metadata": {
"component": {
"type": "application",
"name": "registry",
"version": "v1.0.0"
}
},
"components": [
{
"type": "library",
"name": "golang.org/x/crypto",
"version": "v0.25.0",
"purl": "pkg:golang/golang.org/x/crypto@v0.25.0"
}
]
}SBOMs are also attached as cosign attestations to the image:
cosign attest --yes --type cyclonedx \
--predicate registry-sbom.cdx.json \
--key cosign.key \
ghcr.io/secai-hub/secai_os:v1.0.0-registryBuild provenance follows the SLSA v1.0 in-toto format and is generated by actions/attest-build-provenance. The attestation binds the built artifacts to the specific source commit, build workflow, and builder identity.
Example provenance predicate (abbreviated):
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{
"name": "registry-linux-amd64",
"digest": {
"sha256": "a1b2c3d4e5f6..."
}
}
],
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {
"buildDefinition": {
"buildType": "https://actions.github.io/buildtypes/workflow/v1",
"externalParameters": {
"workflow": {
"ref": "refs/tags/v1.0.0",
"repository": "https://github.com/SecAI-Hub/SecAI_OS"
}
}
},
"runDetails": {
"builder": {
"id": "https://github.com/actions/runner"
}
}
}
}cosign verify \
--key cosign.pub \
ghcr.io/secai-hub/secai_os:v1.0.0cosign verify-attestation \
--type cyclonedx \
--key cosign.pub \
ghcr.io/secai-hub/secai_os:v1.0.0cosign verify-attestation \
--type slsaprovenance \
--key cosign.pub \
ghcr.io/secai-hub/secai_os:v1.0.0cosign verify-blob \
--key cosign.pub \
--signature SHA256SUMS.sig \
SHA256SUMSsha256sum -c SHA256SUMS# View SBOM contents
cat registry-sbom.cdx.json | jq '.components[] | .name + "@" + .version'
# Re-generate and compare SBOM from source
syft dir:services/registry -o cyclonedx-json | \
jq '.components | sort_by(.name)' > /tmp/fresh.json
jq '.components | sort_by(.name)' < registry-sbom.cdx.json > /tmp/released.json
diff /tmp/fresh.json /tmp/released.jsonFor a streamlined verification workflow, use files/scripts/verify-release.sh:
# Download release artifacts into a directory
mkdir release && cd release
gh release download v1.0.0 -R SecAI-Hub/SecAI_OS
# Place cosign.pub in the directory (or set COSIGN_PUB_KEY)
cp /path/to/cosign.pub .
# Run full verification
../files/scripts/verify-release.sh ghcr.io/secai-hub/secai_os:v1.0.0The script prints PASS/FAIL for each step and exits non-zero if any check fails. See --help for configuration options.
A successful verify-release.sh run produces output like:
=== SecAI_OS Release Verification ===
Image: ghcr.io/secai-hub/secai_os:v1.0.0
[1/4] Verifying image signature (cosign)...
Verification for ghcr.io/secai-hub/secai_os:v1.0.0 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[PASS] Image signature verified
[2/4] Verifying CycloneDX SBOM attestation...
Verification for ghcr.io/secai-hub/secai_os:v1.0.0 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[PASS] SBOM attestation verified
[3/4] Verifying SLSA3 provenance attestation...
Verification for ghcr.io/secai-hub/secai_os:v1.0.0 --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[PASS] Provenance attestation verified
[4/4] Verifying SHA256SUMS (local artifacts)...
airlock-linux-amd64: OK
airlock-linux-arm64: OK
registry-linux-amd64: OK
... (18 artifacts verified)
[PASS] All checksums match
=== Results ===
4/4 checks passed
Status: ALL VERIFIED
A failed run exits with code 1 and clearly identifies which step failed:
[1/4] Verifying image signature (cosign)...
Error: no matching signatures: crypto/rsa: verification error
[FAIL] Image signature verification FAILED
=== Results ===
0/4 checks passed
Status: VERIFICATION FAILED — do not trust this release