Build Security Concepts
Build Security Concepts
The following are the key concepts in build security. Some are related to desired properties of the build system (like isolation, hermeticity or reproducibility) that help with the idea of tamper-proof builds. They often need a complete redesign of the existing build system.
Other ideas target on captured evidence during the build that could be verified later. This leads to the concept of software attestations.
Software Attestation
A software attestation is an assertion made about a piece of software. A software attestation is an authenticated statement (metadata) about a software artifact or collection of software artifacts.
Software attestations are a generalization of raw artifact/code signing. The attestation is a signed document (in a given format, typically based on JSON) that associates metadata with an artifact. They represent evidence linking inputs (materials) and outputs (artifacts produced) at each build step.
Attestations provide a verifiable record of the steps done for building the final software artifacts, including input materials for each step and the build commands run.
The most popular attestation framework is in-toto, where attestations are signed statements with a subject (an artifact) and a predicate (a fact about the subject). Predicates may follow different standard types, see in-toto Attestation Predicates.
Attestations are signed with a keypair for linking the predicate (a claim) to the subject (e.g. a reference to the artifact) so the receiver can verify with the public key that the attestation was not tampered with (integrity), and that the signer created (or approved) the claim about the subject (authentication of origin / non repudiation).
The signed attestation is stored in an attestations registry and can be retrieved when the attestations is needed for verifying the software at a later moment.
The verifying part ("verifier") computes a digest on the software (the "subject") and checks the integrity of the attestation, matching the digest for the subject in the attestation with the one computed by the verifier. Cryptographic integrity (validity of the signature, public key, time when the signing was performed) and further "semantic validation" based on the contents of the attestation and an acceptance policy are performed by the verifier to accept or reject the software.
Provenance
Provenance is (verifiable) information, or metadata, about how, when and where a software artifact was created. This could include information about what source code, build system, and build steps were used, as well as who and why the build was initiated. Provenance can be used to determine the authenticity and trustworthiness of software artifacts that you use. Provenance is based on software attestations.
SLSA defines a provenance attestation format. A SLSA provenance is an attestation that a particular build platform produced a set of software artifacts through execution of a build definition:
Hermetic Build
When given the same input source code and product configuration, a hermetic build system always returns the same output by isolating the build from changes to the host system.
For build isolation, hermetic builds are insensitive to libraries and other software installed on host machines. They depend on specific versions of the build tools (compilers, linting and security tools) and dependencies (libraries, open-source & third-party packages, etc.). This makes the build process self-contained as it does not rely on services external to the build environment.
Hermeticity has two aspects:
Isolation - Hermetic build systems treat tools as source code. They download copies of tools and manage their storage and use inside managed file trees. This creates isolation between the host machine and local user, including installed versions of languages.
Source identity - Hermetic build systems try to ensure the sameness of inputs. Code repositories identify sets of code mutations with a unique identifier like a SHA code, which refers to an (immutable) source code snapshot. Hermetic build systems use this hash to identify changes to the build’s input.
In other words, the build process and resulting artifacts are unaffected by external influence. To execute a hermetic build, every build step, input (e.g. source code) and dependencies (build tools or external software packages) must be declared using a reference which identifies a unique, immutable artifact. This information must be provided as part of the build definition, and the build process should not accept unverifiable references or weak references which may lead to indeterministic resolution. Each referenced resource must be verified and retrieved from a secure, trusted location. The rest of the build process is executed without network access, ensuring that no external influence can be applied to the build process and resulting artifacts.
Reproducible build
One step further from isolated and hermetic builds. A build process is reproducible if, given the same build definition consisting of immutable and verifiable references to build steps, source code, and dependencies the build process produces an identical result.
Reproducible builds are achieved by first creating isolated and hermetic builds. Reproducible builds have many advantages beyond security including more accurate dependency tracking, build caching, and debugging.
Reproducible builds are difficult to attain in the real world, as a single, minimal non-determinism in the build process can break reproducibility (I do love this word!).
Build Integrity
To protect against certain attacks, appropriate evidence is captured and signed by the actor at each step in the pipeline.There are different integrity types: layout integrity (the pipeline is executed as specified, with no steps added, removed or reordered), artifact flow integrity (no artifacts are altered in-between steps) and step authentication (only authorized parties can actually perform the steps).Often the signature framework is based on public key cryptography, where intended actors (project owners, functionaries) are identified by their public keys.
Keyless signing
Cryptographic keys are essential to software supply chain security, but managing them can be complex and time-consuming.This is especially true for long-lived cryptographic keys.Proper key handling is hard and may lead to key compromises with are difficult to recover from.
An alternative approach is to use short-lived, ephemeral keys that are generated on-the-fly for each signature operation, making them more difficult for an attacker to compromise.However, verifying keyless signatures is more complex than traditional signatures, as the corresponding certificate used to validate the signature may no longer be valid when the signature needs to be verified.
It is critical to understand how ephemeral certificates already expired at the time when attestation’s signatures are verified could be trusted so that (1) the public key in the certificate is linked to the authenticated identify included in the certificate (e.g. an email address), and (2) that such link was valid at the time when the certificate was issued and (3) that the certificate was valid when the signature was created.
A keyless signature is a digital signature that allows for the secure authentication of a digital message without the need to manage long-lived private keys. The signer generates a key pair on-the-fly and sends the public key to a CA along with a identity token that allows the CA to link the public key with the signer’s identity.Salt uses OIDC-based identity token with the Sigstore Fulcio CA, that issues short-lived certificates.These certificates include a subject identity, such as an email address, extracted from the OIDC token, and special Sigstore-specific ASN.1 object identifiers.One of these objects is a signed certificate timestamp (SCT), which serves as proof of the time at which the certificate was issued.
Fulcio publishes all issued certificates to a certificate transparency log (CT) for verifiers to check if their identity has been compromised or mis-issued.However, clients verifying the attestation only check the validity of the SCT, which is embedded in the certificate.The client verifies that the SCT is valid, then it gets the inclusion time for the record created in a public transparency log (Rekor) corresponding to the artifact it signs, and uses it to verify the signature happened within the validity period of the certificate.
Fortunately, the verification is largely transparent when the software consumer uses the attestation verify
command.
Last updated