← Blog

Disconnected operations

Signing software releases, explained

How a code signature works, what NIST's secure development framework asks of release integrity, how Sigstore and SLSA build levels fit in, and how a signature is checked on a machine with no network.

Oct 21, 20264 min read8 sources

Why it matters

A signature on software carried into a disconnected network can be checked only against keys and roots already on the verifying machine, and the cosign README marks its air-gapped section out of date.

The short version

  1. 1A code signature gives data integrity and source authentication, and the verifier manages the trust anchors used to check it.
  2. 2Sigstore's Fulcio issues certificates valid for 10 minutes, so a later offline check depends on a signed timestamp or log entry timestamp in the bundle.
  3. 3SLSA v1.2 defines Build levels 0 to 3. Level 2 adds signed provenance from a hosted build platform, and Level 3 adds a hardened build platform.

A code signature is a digital signature applied to software. A January 26, 2018 NIST cybersecurity white paper, written by the National Institute of Standards and Technology (NIST) with the National Security Agency (NSA), says signing code provides data integrity, proof that the code was not modified, and source authentication, which identifies who controlled the code when it was signed. NIST's Secure Software Development Framework (SSDF), SP 800-218 version 1.1, asks producers to give acquirers a way to verify release integrity. On a disconnected network, verification can draw only on keys, certificates, and roots of trust already on the machine.

Signer, verifier, and trust anchor

The white paper names three roles. The developer writes and builds the code. The signer manages the signing keys, generates the key pair on a protected device, and usually obtains a certificate from a certification authority (CA) that ties the signer to the public key. If no CA is used, the public key must be distributed by a trusted, out-of-band mechanism. The verifier validates the signature, and may be part of the operating system or a component from the same developer.

A time stamp authority (TSA) can record when code was signed. With a time stamp, a verifier can accept a signature made while the key was valid, even if the key expired later or was compromised after signing.

Verifiers also manage trust anchors. The paper defines them as data objects, generally public keys, installed and securely stored on the verifying platform. It adds that trust anchors should not be permanent, because a compromised anchor would otherwise leave the platform with no means to remediate.

What the SSDF asks of a release

SP 800-218, published February 2022, puts release integrity in the Protect the Software (PS) group.

  • PS.1.1 stores all forms of code by least privilege. The examples include commit signing, code signing to protect executables, and cryptographic hashes for file integrity.
  • PS.2.1 makes integrity verification information available to acquirers. The examples are posting cryptographic hashes on a well-secured website, using an established CA for code signing so operating systems and tools can confirm signatures, and periodically reviewing certificate renewal, rotation, revocation, and protection.
  • PS.3.1 archives each release with its integrity verification and provenance data, kept separate from the release files or signed.
  • PS.3.2 collects and shares provenance data for all components, for example in a software bill of materials (SBOM), and gives recipients a way to verify its integrity.

Sigstore and SLSA

Sigstore, backed by the Open Source Security Foundation (OpenSSF) under the Linux Foundation, moves signing from long-lived keys to identity. The client, Cosign, creates a key pair and sends a certificate request with an OpenID Connect (OIDC) identity token to Fulcio, the certificate authority. Fulcio issues X.509 certificates valid for 10 minutes. The private key is discarded after a single signing, and the artifact's digest, signature, and certificate go into Rekor, an append-only transparency log. Verification checks the signature, the identity in the certificate, the certificate chain to Sigstore's root of trust, and proof of inclusion in Rekor.

SLSA, a cross-industry specification published at slsa.dev, grades provenance, the record of how a package was built. The Build track in version 1.2 has four levels:

  • Build L0: no guarantees.
  • Build L1: provenance exists, but is trivial to bypass or forge.
  • Build L2: a hosted build platform generates and signs the provenance, and the consumer validates it. This prevents tampering after the build.
  • Build L3: a hardened platform keeps runs from influencing one another and keeps the provenance signing secret away from user-defined build steps.

Checking a signature with no network

The Sigstore bundle is everything required to verify a signature on an artifact. Because Fulcio certificates expire quickly, a bundle that may be verified after expiry must include at least one transparency log signed entry timestamp or a Request for Comments (RFC) 3161 timestamp, showing that signing happened while the certificate was valid.

The Cosign verification page calls the signed entry timestamp a signed inclusion promise. It can be checked with the log's public key to prove an entry is in the log without contacting the log. The page also describes local verification with an on-disk public key, and says the newer bundle format supports offline verification.

The cosign README gives an air-gapped procedure and marks it out of date. It says most verification workflows periodically request service keys from an online repository. For air-gapped use with the public instance, the verifier needs a copy of the trusted root file, whose contents change without notification, so the operator must build a way to keep that copy current. The image is saved with network access first, then verified locally with an offline flag and the trusted root. A signature made with a key pair verifies offline against a public key held on the machine.

What to check

  • What does the vendor sign: release files, container images, the SBOM, build provenance?
  • Which trust anchor does verification rely on: an established CA, a vendor public key delivered out of band, or the Sigstore trusted root, and how is it carried into the enclave and refreshed?
  • For keyless Sigstore signatures, does each bundle carry a signed entry timestamp or an RFC 3161 timestamp?
  • Which certificate identity and OIDC issuer should a valid signature show?
  • What SLSA Build level does the vendor claim, and who signed the provenance?
  • How does the vendor handle certificate renewal, rotation, and revocation, the review SP 800-218 lists under PS.2.1?

Azcuna's BABEL reads, translates, and searches foreign-language documents entirely on-device, with no cloud and no connection, and keeps every claim tied to the passage it came from.

Sources

  1. 1Security Considerations for Code Signing · NIST Cybersecurity White Paper, with the National Security Agency, January 26, 2018
  2. 2NIST SP 800-218, Secure Software Development Framework (SSDF) Version 1.1 · National Institute of Standards and Technology, February 2022
  3. 3Sigstore Overview · Sigstore documentation
  4. 4Fulcio Overview · Sigstore documentation
  5. 5Sigstore Bundle Format · Sigstore documentation
  6. 6Verifying Signatures · Sigstore documentation (Cosign)
  7. 7cosign README · Sigstore project, GitHub
  8. 8Build: Track Basics (SLSA v1.2) · SLSA, The Linux Foundation

Where this shows up in our work

More on disconnected operations