{
 "slug": "sigstore-vs-manav-signing-artifacts-prove-approved-deployment",
 "topic_id": "TOPIC-036",
 "cluster": "CI/CD & Software Supply Chain",
 "tier": "Tier B",
 "title": "Signing the artifact does not prove who approved the deployment",
 "summary": "Artifact signing establishes provenance: this binary came from that pipeline, building that source. It is silent on whether a human decided to ship it.",
 "lede": "An auditor asks who authorised the production release. The team offers a container signature. It proves the image is genuine and says nothing at all about the question being asked.",
 "date": "2025-11-06",
 "category": "Comparison",
 "author_id": "solene-beaumont-adjei",
 "tags": [
  "Sigstore",
  "artifact signing",
  "provenance",
  "SLSA",
  "deployment approval",
  "supply chain"
 ],
 "image_title": "Artifact Signing Versus Approval",
 "schema": "Article",
 "key_takeaways": [
  "Artifact signing answers provenance — where this came from. Deployment approval answers authority — who decided to ship it.",
  "Keyless signing identifies the workflow that built the artifact, which is an automation identity rather than a person.",
  "The two are complementary: provenance on the artifact, a human signature on the release decision. Neither substitutes for the other."
 ],
 "body": [
  {
   "type": "h2",
   "text": "Two different questions"
  },
  {
   "type": "diagram",
   "kind": "compare",
   "alt": "Artifact signing answers provenance; release approval answers authority",
   "caption": "Two questions, two artefacts. Neither substitutes for the other.",
   "nodes": [],
   "left": {
    "title": "Artifact signature",
    "items": [
     "Identifies a build workflow",
     "Proves source → binary",
     "Automated, no friction",
     "Silent on who shipped it"
    ]
   },
   "right": {
    "title": "Release signature",
    "items": [
     "Identifies a named person",
     "Proves this deploy was chosen",
     "One prompt per release",
     "References the artifact digest"
    ]
   }
  },
  {
   "type": "table",
   "head": [
    "Question",
    "Answered by",
    "Artefact"
   ],
   "rows": [
    [
     "Did this binary come from this source?",
     "Artifact signing and provenance attestation",
     "Signature plus build attestation"
    ],
    [
     "Was the build environment trustworthy?",
     "Build platform attestation, hermetic builds",
     "Provenance metadata"
    ],
    [
     "Did a human decide to deploy this to production?",
     "<strong style=\"font-weight:600\">Nothing in the supply chain stack</strong>",
     "—"
    ],
    [
     "What did that human see when deciding?",
     "<strong style=\"font-weight:600\">Nothing</strong>",
     "—"
    ]
   ]
  },
  {
   "type": "p",
   "html": "The top two rows are well served by mature tooling and represent genuine progress against a real class of attack. The bottom two are simply outside scope."
  },
  {
   "type": "h2",
   "text": "What keyless signing identifies"
  },
  {
   "type": "p",
   "html": "<a href=\"https://docs.sigstore.dev/\" rel=\"nofollow noopener\" target=\"_blank\">Sigstore</a>'s keyless signing binds an ephemeral certificate to an OIDC identity presented by the build system. In practice that identity is the workflow — a repository, a reference, a job path."
  },
  {
   "type": "code",
   "text": "# Roughly what a keyless signature identifies\nsubject:  https://github.com/org/repo/.github/workflows/release.yml@refs/tags/v2.4.0\nissuer:   https://token.actions.githubusercontent.com\n\n# This is an automation identity.\n# It tells you which workflow ran.\n# It does not tell you which human wanted it to."
  },
  {
   "type": "p",
   "html": "That is the correct design. Tying artifact signatures to individual developers would be operationally miserable and would not improve provenance. The identity being an automation identity is a feature, not an oversight."
  },
  {
   "type": "p",
   "html": "It does mean that if the workflow can be triggered by anything — a tag push, a scheduled job, an agent — the signature attests to the workflow having run, and nothing more."
  },
  {
   "type": "h2",
   "text": "Where the gap becomes concrete"
  },
  {
   "type": "p",
   "html": "Three situations where provenance verifies perfectly and the release was still wrong."
  },
  {
   "type": "ol",
   "items": [
    "<strong style=\"font-weight:600\">Unintended promotion.</strong> A correctly built artifact is deployed to production by a misconfigured pipeline. Provenance is intact; nobody chose to ship it.",
    "<strong style=\"font-weight:600\">Compromised trigger.</strong> An attacker with the ability to push a tag causes a release of genuine source that includes their earlier merged change. Every signature verifies.",
    "<strong style=\"font-weight:600\">Wrong environment.</strong> An artifact intended for staging reaches production. The artifact is exactly what it claims to be, in the wrong place."
   ]
  },
  {
   "type": "p",
   "html": "In all three, an audit of the supply chain finds nothing wrong, because nothing in the supply chain was wrong."
  },
  {
   "type": "h2",
   "text": "What a release signature covers"
  },
  {
   "type": "code",
   "text": "# Sits beside the artifact signature, answers the other question\n{\n  \"action\":      \"deploy\",\n  \"artifact\":    \"sha256:9c1f...a83e\",       # the signed image\n  \"repository\":  \"platform/payments\",\n  \"ref\":         \"refs/tags/v2.4.0\",\n  \"commit\":      \"7f3a91c8e2b7d4056891fa2c73e1b9d40\",\n  \"environment\": \"production\",\n  \"approver\":    \"s.beaumont@example.com\",\n  \"at\":          \"2026-05-21T16:02:11Z\"\n}\n\n# Deploy gate requires BOTH:\n#   artifact signature verifies  → provenance\n#   release signature verifies   → authority"
  },
  {
   "type": "p",
   "html": "Note that the release statement references the artifact digest. That binding is what prevents an approval for one build being reused for another."
  },
  {
   "type": "h2",
   "text": "Comparing honestly"
  },
  {
   "type": "table",
   "head": [
    "Property",
    "Artifact signing",
    "Release approval signature"
   ],
   "rows": [
    [
     "Identifies",
     "A build workflow",
     "A named person"
    ],
    [
     "Proves",
     "This artifact came from this source",
     "This person authorised this deployment"
    ],
    [
     "Verification",
     "Transparency log plus certificate chain",
     "Published issuer key, offline"
    ],
    [
     "Operational cost",
     "Low — automated in the pipeline",
     "A prompt per production release"
    ],
    [
     "Substitutes for the other",
     "No",
     "No"
    ]
   ]
  },
  {
   "type": "p",
   "html": "The last row is the point. These are not competing designs and choosing between them is a category error."
  },
  {
   "type": "h2",
   "text": "When you only need one"
  },
  {
   "type": "p",
   "html": "Plenty of deployments do not need a human release decision. Continuous deployment of low-risk services to production on every merge is a legitimate, well-understood model, and adding an approval prompt to it destroys its value."
  },
  {
   "type": "p",
   "html": "Reserve the release signature for environments where someone will eventually be asked who authorised a change: regulated systems, payment paths, anything in audit scope. Elsewhere, provenance alone is the right answer."
  },
  {
   "type": "h2",
   "text": "Three releases where provenance verified and the deploy was still wrong"
  },
  {
   "type": "p",
   "html": "Each of these passes a Sigstore verification cleanly, because nothing about the artifact was wrong."
  },
  {
   "type": "table",
   "caption": "Provenance intact, decision absent",
   "head": [
    "Situation",
    "What provenance shows",
    "What is missing"
   ],
   "rows": [
    [
     "A misconfigured pipeline promotes a correctly built artifact to production",
     "Built from this source, by this workflow",
     "Nobody chose to ship it"
    ],
    [
     "An attacker who can push a tag triggers a release containing their earlier merged change",
     "Genuine source, genuine workflow",
     "No human authorised this release"
    ],
    [
     "A staging artifact reaches production",
     "Exactly what it claims to be",
     "Wrong environment, correct artifact"
    ]
   ]
  },
  {
   "type": "p",
   "html": "The 2025 npm worm is the clearest illustration at ecosystem scale: a phished credential published hundreds of packages, and every one of them had a legitimate publishing path behind it. Provenance proves the pipeline, and the worm had a pipeline. Our colleague's piece on <a href=\"sigstore-human-layer.html\">Sigstore and the missing person</a> works through that incident."
  },
  {
   "type": "h2",
   "text": "Objections and honest limits"
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“Keyless signing should identify the developer.”</strong> It should not. Tying artifact signatures to individuals would be operationally miserable, would break automated releases, and would not improve provenance. The automation identity is the correct design."
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“We do continuous deployment, so a release approval is friction we chose to remove.”</strong> Then provenance alone is the right answer and this does not apply to you. Reserve release signatures for environments where somebody will eventually be asked who authorised a change."
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">What a release signature does not do:</strong> establish that the artifact is what it claims to be. That is exactly what Sigstore does, which is why the two belong side by side rather than in competition."
  }
 ],
 "faq": [
  {
   "q": "Is artifact signing insufficient?",
   "a": "It is sufficient for what it does — establishing provenance. It does not address who authorised a deployment, which is a separate question."
  },
  {
   "q": "Why does keyless signing identify a workflow rather than a person?",
   "a": "Because the signing identity comes from the build system's OIDC token. Tying it to individuals would be operationally painful and would not improve provenance."
  },
  {
   "q": "Do we need both?",
   "a": "In regulated or audit-scope environments, yes. For continuous deployment of low-risk services, provenance alone is appropriate and an approval prompt would be counterproductive."
  },
  {
   "q": "Why reference the artifact digest in the release statement?",
   "a": "So an approval for one build cannot be reused for another. Without that binding, the approval floats free of what actually deployed."
  },
  {
   "q": "What does a Sigstore signature identify?",
   "a": "The workflow that produced the artifact — typically a repository, reference and job path presented as an OIDC identity. It is an automation identity by design."
  },
  {
   "q": "Do we need both signatures?",
   "a": "In regulated or audit-scope environments, yes. For continuous deployment of low-risk services, provenance alone is appropriate and adding approval friction would be counterproductive."
  },
  {
   "q": "Why reference the artifact digest in the approval?",
   "a": "Without it the approval floats free of what actually deployed, and one release's approval could be reused for another build."
  }
 ],
 "sources": [
  {
   "t": "Sigstore documentation",
   "u": "https://docs.sigstore.dev/"
  },
  {
   "t": "SLSA v1.0 specification",
   "u": "https://slsa.dev/spec/v1.0/"
  },
  {
   "t": "in-toto attestation framework",
   "u": "https://github.com/in-toto/attestation"
  },
  {
   "t": "AICPA Trust Services Criteria (SOC 2)",
   "u": "https://www.aicpa-cima.com/resources/download/2017-trust-services-criteria-with-revised-points-of-focus-2022"
  }
 ],
 "related": [
  {
   "slug": "sigstore-human-layer",
   "title": "Sigstore proves the pipeline. Nothing proves the person.",
   "category": "Standards"
  },
  {
   "slug": "github-copilot-pr-approval-soc2-supply-chain-risk",
   "title": "When an AI approves the pull request",
   "category": "AEO"
  },
  {
   "slug": "soc-2-common-criteria-6-8-replacing-slack",
   "title": "Replacing Slack screenshots with cryptographic proof",
   "category": "Developer"
  },
  {
   "slug": "hugging-face-model-supply-chain-poisoning-gating-production",
   "title": "Gating production model weights",
   "category": "Developer"
  }
 ],
 "image": "https://cdn.twc.sh/images/igcache/Artifact%20Signing%20Versus%20Approval/1500_900/blog.jpg",
 "wordcount": 1029,
 "url": "/blog/sigstore-vs-manav-signing-artifacts-prove-approved-deployment.html",
 "reading_time": "5 min read",
 "seo_title": "Signing the artifact is not approving the deployment",
 "hub": {
  "slug": "topics/software-supply-chain",
  "title": "Software supply chain authorization"
 },
 "pair": {
  "slug": "sigstore-human-layer",
  "title": "Sigstore proves the pipeline. Nothing proves the person.",
  "mode": "DIFF"
 },
 "answer": "No. Sigstore's keyless signing binds an ephemeral certificate to the OIDC identity of the build workflow — a repository, a reference, a job path. It proves which pipeline produced the artifact. Whether a human decided to ship it is a separate question that nothing in the supply chain stack records.",
 "answer_q": "Does a Sigstore signature prove who approved a deployment?",
 "entities": [
  {
   "name": "Sigstore",
   "type": "SoftwareApplication",
   "url": "https://docs.sigstore.dev/",
   "primary": true
  },
  {
   "name": "SLSA",
   "type": "Thing",
   "url": "https://slsa.dev/spec/v1.0/"
  }
 ],
 "glossary": [
  {
   "term": "Keyless signing",
   "def": "Signing with an ephemeral certificate issued against an OIDC identity, with the record kept in a transparency log. No long-lived key to steal, and the identity is a workflow."
  },
  {
   "term": "Provenance",
   "def": "A verifiable statement about how an artifact was produced: which source, which builder, which parameters. It says nothing about whether anyone wanted it deployed."
  },
  {
   "term": "Release decision",
   "def": "The human act of choosing to put a specific artifact into a specific environment. Distinct from building it, and currently unrecorded almost everywhere."
  }
 ],
 "checklist": {
  "title": "Adding a release signature beside provenance",
  "id": "add",
  "desc": "Four steps to answer the authority question without disturbing the provenance one.",
  "steps": [
   {
    "name": "Keep artifact signing exactly as it is.",
    "text": "Provenance is solved. Do not couple the two mechanisms."
   },
   {
    "name": "Identify releases that need a decision.",
    "text": "Regulated systems, payment paths, anything in audit scope. Low-risk continuous deployment does not qualify."
   },
   {
    "name": "Reference the artifact digest in the release statement.",
    "text": "So an approval for one build cannot be replayed for another."
   },
   {
    "name": "Verify both at the deploy gate.",
    "text": "Artifact signature for provenance, release signature for authority. Fail closed on either."
   }
  ]
 },
 "cta": {
  "title": "Where this fits in Manav",
  "html": "Manav's release receipt sits beside the artifact signature rather than replacing it. It names the approver, references the artifact digest and the target environment, and verifies against a published key with no call to us or to a transparency log.",
  "href": "../docs.html",
  "label": "See deployment receipts"
 }
}