Why does it matter which job and which identity runs cosign attest in your build pipeline?
answer
- the signature covers a claim
- worth equals the claimant's trustworthiness
- same job that built it
- workload identity versus a person's
- authentically signed hearsay
basics
~20 scosign attest signs a claim about an artifact, not the artifact itself, so the signature records only who asserted the claim. Run it later, or by hand, and you get a valid signature over an unverified statement.
solid answer
~50 s`cosign attest` takes a predicate document and a type, wraps them in an in-toto statement whose subject is the artifact's digest, and signs the whole envelope through the same identity chain `cosign sign` uses; verifiers use `cosign verify-attestation`, again pinned to an expected identity and issuer. Because the signed thing is a *claim*, its value equals the trustworthiness of whoever ran the command. In the nightly appliance build, running attest inside the same isolated job that produced the `.deb`, over the digest that job just computed, means the certificate carries the builder's workload identity and the claim is first-hand. Run it in a later stage over an artifact downloaded from a shared staging bucket, or by an engineer on a laptop under a human identity, and it verifies perfectly while asserting something the signer never observed. Authenticity is not accuracy.
go deeper
Recall that attest signs a statement about an artifact while sign signs the artifact's digest, and that both use the same identity chain.
Explain that the statement's subject is the artifact digest and that verification is a separate command pinned to an expected identity and issuer.
Demonstrate judgment about placement: attest in the job that produced the artifact, over a digest that job computed, under an identity nothing else can obtain.
Own the consequence for audit truth across teams: decide which components are allowed to make claims at all, and refuse convenience paths that let a person sign what a build system should.
## Signing bytes versus signing a statement about bytes `cosign sign` puts a signature over an artifact's digest: *I vouch for these bytes*. `cosign attest` does something structurally different. You give it a predicate — a document making some claim — and a type naming what kind of claim it is. cosign wraps them in an in-toto statement whose `subject` is the artifact's digest, and signs that statement inside a DSSE envelope. The signature therefore covers *the claim about the artifact*, not the artifact. Verification is the counterpart command, `cosign verify-attestation`, and like any keyless verification it is only meaningful when pinned to an expected certificate identity and issuer. That structural difference is the whole question. A signature over bytes is self-evidently about those bytes; anyone can recompute the digest. A signature over a claim inherits all its worth from the claimant. cosign will happily sign a statement that is completely false — that is not a flaw in cosign, it is what signing means. ### So the operative question is: who ran it, and what had they seen? Take a nightly appliance build producing a `.deb` that field engineers install. The attest step can sit in several places, and they are not equivalent: - **Inside the build job, over the digest that job just computed.** The certificate carries the build system's workload identity. The claim describes something the signer directly produced. This is first-hand testimony. - **In a later pipeline stage, over an artifact downloaded from a shared staging bucket.** The signer attests whatever digest it was handed. If anyone else can write that bucket, the statement may faithfully describe an artifact the builder never produced, and it will verify cleanly. This is testimony about something the witness did not see. - **By an engineer running the command locally after the fact.** The certificate carries a human identity from a human identity provider. Cryptographically flawless; evidentially, a person retyping what they believe happened. All three produce valid attestations. Only the first produces one worth anything, and the difference is visible to a verifier *only* because the identity in the certificate differs — a workload identity for a build job, an email for a person. That is why the verifying side pins the identity it expects rather than accepting any signed attestation. ### Failure modes to name in an interview - **Attesting a digest you were handed rather than one you computed.** Compute the digest in the same job that produced the file, and attest that value; never accept it as a pipeline input from a step you do not trust. - **A human fallback "for when the pipeline fails".** The moment a person can produce an attestation that the verifier accepts, the accepted-identity set includes a laptop, and every guarantee degrades to that laptop's security. - **Attesting an artifact that is then rebuilt.** If a later step recompiles or repackages, the digest changes and the attestation no longer applies to what ships — silently, because verification of the new artifact simply finds nothing rather than finding a conflict. - **Treating a verified attestation as a verified fact.** `verify-attestation` succeeding means the expected identity signed this claim about this digest. Whether the claim is *true* depends entirely on how it was produced. ### Why the audit value collapses if you get this wrong The asset at stake with attestations is usually audit truth: downstream consumers, auditors or field engineers want to know what the build recorded about an artifact. A compromised or merely careless attest step does not leak data or take a service down; it corrupts the record, and it does so in the most durable way possible, by making the corruption look verified. A weak build job that can be induced to attest arbitrary content is worth more to an attacker than one that can only produce a bad artifact, because the second is detectable and the first arrives pre-endorsed. The rule that falls out is short: attestations should be produced by the smallest, most isolated component that directly observed what it is claiming, under an identity only that component can obtain, over a digest it computed itself.
- How does a verifier tell a build job's attestation from an engineer's?By the certificate identity. A build job carries a workload identity issued to the pipeline by the platform's own provider; a person carries an email address from a human identity provider. The verifying step pins the one it expects, so an attestation signed by a laptop simply fails rather than quietly counting.
- The attest step downloads the artifact from a shared staging bucket first. What is wrong?It attests whatever digest it was handed. If anyone else can write that bucket, the signed statement can describe an artifact the builder never produced, and it will verify perfectly. Compute the digest in the job that produced the file and attest that value, so the claim and the evidence come from the same place.
- Does a successfully verified attestation mean its contents are true?No. It means the identity you expected signed this claim about this digest. Truth depends on how the claim was produced — whether the signer observed what it describes, whether it computed rather than accepted the inputs, and whether anything could have modified the artifact between production and signing.
- What happens to an attestation if a later stage repackages the artifact?The digest changes, so the attestation no longer applies to what ships. Worse, it fails silently: verifying the new artifact finds no attestation rather than finding a contradicting one. Either attest the final artifact, or make the absence of an attestation for the deployed digest a hard failure.
A notary confirms who signed a statement, not that the statement is true. An attestation signed after the fact by someone who was not present is exactly that: correctly notarised hearsay.
saying these in an interview costs you the question
- Says cosign attest signs the artifact itself
- Treats any valid attestation as equally trustworthy
- Attests a digest handed in from an untrusted earlier step
- Keeps a human fallback path that produces accepted attestations
- Reads a verified attestation as proof its contents are true