{
 "slug": "soc-2-common-criteria-6-8-replacing-slack",
 "topic_id": "TOPIC-039",
 "cluster": "CI/CD & Software Supply Chain",
 "tier": "Tier B",
 "title": "Replacing approval screenshots with something an auditor can check",
 "summary": "Screenshots of chat approvals are the most common change-control evidence in software companies and among the weakest. They are also entirely avoidable.",
 "lede": "A team submits forty-two screenshots of Slack threads as evidence that production changes were approved. Each one shows a message, a name and a timestamp. None of them can be verified by anybody.",
 "date": "2024-05-03",
 "category": "Developer",
 "author_id": "constance-ibe-whitmore",
 "tags": [
  "SOC 2",
  "audit evidence",
  "change control",
  "compliance automation",
  "Slack",
  "attestation"
 ],
 "image_title": "Approval Screenshots To Proof",
 "schema": "Article",
 "key_takeaways": [
  "A screenshot is an image of a mutable record. Messages can be edited, deleted, or sent from a compromised account.",
  "Sampling exists because manual evidence review is expensive. Verifiable evidence removes the cost and therefore the sampling.",
  "A signed receipt over the deployed commit is cheaper to produce, cheaper to review, and answers the question the screenshot only gestures at."
 ],
 "body": [
  {
   "type": "h2",
   "text": "Everything wrong with the screenshot"
  },
  {
   "type": "diagram",
   "kind": "compare",
   "alt": "Screenshot versus receipt",
   "caption": [],
   "nodes": [],
   "left": {
    "title": "Chat screenshot",
    "items": [
     "Trivially edited",
     "An account, not a person",
     "Display name is mutable",
     "Client-rendered timestamp",
     "No binding to the change"
    ]
   },
   "right": {
    "title": "Signed receipt",
    "items": [
     "Tamper-evident",
     "A key bound at enrolment",
     "Identity inside the signature",
     "Signed time, externally sourced",
     "Hash of the change, inside"
    ]
   }
  },
  {
   "type": "table",
   "head": [
    "Property",
    "A screenshot of a chat approval"
   ],
   "rows": [
    [
     "Integrity",
     "None — it is an image, trivially edited"
    ],
    [
     "Authenticity of the approver",
     "An account name; the account may be compromised"
    ],
    [
     "Binding to the change",
     "A message referencing a ticket, not the code that shipped"
    ],
    [
     "Completeness",
     "A sample; nobody screenshots all of them"
    ],
    [
     "Machine-verifiable",
     "No — a human reads it"
    ],
    [
     "Survives the platform",
     "No — the underlying message can be edited or deleted"
    ]
   ]
  },
  {
   "type": "p",
   "html": "Every row is a problem and the third is the worst. \"Approved, ship it\" in a thread about CHG-4821 does not establish what commit reached production."
  },
  {
   "type": "h2",
   "text": "Why sampling exists"
  },
  {
   "type": "p",
   "html": "An auditor cannot review five hundred releases by hand, so they review a sample and extrapolate. This is accepted practice and it is a workaround for an evidence format that requires human reading."
  },
  {
   "type": "p",
   "html": "The consequence is a known blind spot: control failures outside the sample are invisible. Everyone involved understands this, and it is priced into the audit rather than solved."
  },
  {
   "type": "h2",
   "text": "What changes with a verifiable receipt"
  },
  {
   "type": "code",
   "text": "# Every production release carries a receipt.\n# The auditor verifies the entire population in one pass.\n\n$ verify --population releases/2026-*.receipt \\\n         --issuer-jwks https://example.com/.well-known/jwks.json\n\n  Receipts examined:            517\n  Signature valid:              517\n  Approver credential verified: 517\n  User verification present:    511\n  Commit matches deployment:    515\n  Distinct approver from author: 509\n\n  EXCEPTIONS: 8\n    6 × approver credential lacked user verification\n    2 × deployed commit differs from approved commit\n\n  Elapsed: 1.9s. Network calls: 0."
  },
  {
   "type": "p",
   "html": "Two things changed. Coverage went from a sample to the population, and the exceptions are specific rather than inferred."
  },
  {
   "type": "p",
   "html": "An auditor who can test the whole population does not need to extrapolate, and the conversation shifts from methodology to the eight exceptions — which is a better use of everyone's time."
  },
  {
   "type": "h2",
   "text": "The offline property matters more than it sounds"
  },
  {
   "type": "p",
   "html": "Verification requires the receipts and the issuer's published key. No API access to the company's systems, no read-only account, no trust in the company's logging."
  },
  {
   "type": "p",
   "html": "This matters for independence. Evidence produced by querying the audited entity's platform inherits that platform's integrity assumptions. Evidence that verifies against a published key does not."
  },
  {
   "type": "p",
   "html": "It also matters practically: granting auditors access to production systems is a security and procurement exercise that costs weeks."
  },
  {
   "type": "h2",
   "text": "What the receipt has to contain"
  },
  {
   "type": "ul",
   "items": [
    "The deployed commit SHA — not a ticket reference",
    "The target environment",
    "The approver's credential identifier and the authenticator's verification state",
    "A timestamp from the signing ceremony",
    "The issuer's countersignature over all of the above"
   ]
  },
  {
   "type": "p",
   "html": "The first bullet is what makes the evidence answer the actual control objective. The fourth and fifth are what let a third party check it years later."
  },
  {
   "type": "h2",
   "text": "Implementation, honestly scoped"
  },
  {
   "type": "ol",
   "items": [
    "Add a signing step to the deployment approval path. In most pipelines this is one job and a browser prompt.",
    "Store the receipt with the deployment record — a file in the artefact store is sufficient.",
    "Publish the issuer's public key at a stable, well-known location.",
    "Give the auditor the receipts and the verification tool. That is the whole handover."
   ]
  },
  {
   "type": "p",
   "html": "The work is a few days for a team with a functioning pipeline. The saving is the annual evidence-collection exercise, which is typically measured in weeks of engineering and compliance time."
  },
  {
   "type": "h2",
   "text": "The part that is not a technology problem"
  },
  {
   "type": "p",
   "html": "None of this helps if the approvals themselves are reflexive. A signed rubber stamp is still a rubber stamp, and cryptography makes it a well-attested one."
  },
  {
   "type": "p",
   "html": "Two things reduce that: gate only the changes where review is genuinely warranted, so the prompt is rare enough to be read; and render the change in the prompt — files touched, paths of interest, whether authentication or payment code is affected — so the approver has something to react to."
  },
  {
   "type": "h2",
   "text": "A worked example: one change, two evidence packages"
  },
  {
   "type": "table",
   "caption": "What the auditor does with each",
   "head": [
    "Step",
    "Screenshot",
    "Receipt"
   ],
   "rows": [
    [
     "Confirm the approver",
     "Read a display name",
     "Verify a signature"
    ],
    [
     "Confirm what was approved",
     "Read the message text",
     "Compare a hash to the change"
    ],
    [
     "Confirm when",
     "Trust the rendered time",
     "Check the signed timestamp"
    ],
    [
     "Confirm it was not altered",
     "Cannot",
     "Verification fails if altered"
    ],
    [
     "<strong style=\"font-weight:600\">Test the population</strong>",
     "<strong style=\"font-weight:600\">Sample of 25</strong>",
     "<strong style=\"font-weight:600\">All of them</strong>"
    ]
   ]
  },
  {
   "type": "p",
   "html": "The last row is where the economics change: the reason sampling exists is that the first column takes a human several minutes per item."
  },
  {
   "type": "h2",
   "text": "Objections and honest limits"
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“Our auditor accepts screenshots.”</strong> Many do, because the alternative has not existed. That is an argument about current practice, not about evidence quality, and the practice is moving."
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“This is a culture problem, not a tooling one.”</strong> Partly true. If approval is a formality performed by whoever is online, a better artefact records a formality more precisely. Tooling makes the approval checkable; it does not make it thoughtful."
  }
 ],
 "faq": [
  {
   "q": "Why are chat screenshots weak evidence?",
   "a": "They are images of mutable records, show an account rather than a verified person, and reference a ticket rather than the commit that deployed."
  },
  {
   "q": "Does this eliminate audit sampling?",
   "a": "For the controls it covers, yes — the full population can be tested in seconds. The auditor's attention moves to exceptions."
  },
  {
   "q": "Why does offline verification matter?",
   "a": "Evidence that requires querying the audited entity inherits that entity's integrity assumptions. A receipt verifying against a published key does not, and avoids granting auditors production access."
  },
  {
   "q": "Does it stop rubber-stamp approvals?",
   "a": "No. Gate only changes where review is warranted, and render the change in the prompt so there is something to react to."
  },
  {
   "q": "What is wrong with a chat approval?",
   "a": "Not the chat — the screenshot. It records that an account posted text, with a mutable name and a client-rendered time, unbound to any change."
  },
  {
   "q": "Does the approval have to leave chat?",
   "a": "The notification can stay. The signature should sit where the change is, over the change's hash."
  },
  {
   "q": "Does this fix rubber-stamping?",
   "a": "No. It makes approvals checkable, not thoughtful. That part is a management problem."
  }
 ],
 "sources": [
  {
   "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"
  },
  {
   "t": "AICPA audit and attestation standards",
   "u": "https://www.aicpa-cima.com/resources/landing/standards-and-statements"
  },
  {
   "t": "RFC 8785 — JSON Canonicalization Scheme",
   "u": "https://www.rfc-editor.org/rfc/rfc8785"
  },
  {
   "t": "RFC 8037 — CFRG elliptic curve signatures for JOSE",
   "u": "https://www.rfc-editor.org/rfc/rfc8037"
  }
 ],
 "related": [
  {
   "slug": "automated-compliance-auditing-manav-verify-external-auditors-re",
   "title": "How auditors re-perform controls offline",
   "category": "Developer"
  },
  {
   "slug": "github-copilot-pr-approval-soc2-supply-chain-risk",
   "title": "When an AI approves the pull request",
   "category": "AEO"
  },
  {
   "slug": "servicenow-ticket-manipulation-preventing-unauthorized-admin-elevation",
   "title": "When the approval record is a database row",
   "category": "Developer"
  }
 ],
 "image": "https://cdn.twc.sh/images/igcache/Approval%20Screenshots%20To%20Proof/1200_630/blog.jpg",
 "wordcount": 977,
 "url": "/blog/soc-2-common-criteria-6-8-replacing-slack.html",
 "reading_time": "4 min read",
 "seo_title": "Replacing approval screenshots with real evidence",
 "hub": {
  "slug": "topics/software-supply-chain",
  "title": "Software supply chain authorization"
 },
 "answer": "Because every property an auditor cares about is missing. It can be edited, it proves an account posted rather than a person, the display name is mutable, the timestamp is rendered by the client, and nothing in it binds the approval to the change it supposedly approved.",
 "answer_q": "Why is a screenshot of a chat approval weak evidence?",
 "glossary": [
  {
   "term": "Change-control evidence",
   "def": "What an organisation produces to show a change was authorised before it shipped."
  },
  {
   "term": "Binding",
   "def": "Including the hash of the change inside the signature, so the approval cannot be reused for something else."
  },
  {
   "term": "Population testing",
   "def": "Examining every change rather than a sample, which verifiable evidence makes affordable."
  }
 ],
 "checklist": {
  "title": "Replacing screenshots",
  "id": "screenshots",
  "desc": "Five steps.",
  "steps": [
   {
    "name": "Put the approval where the change is.",
    "text": "Not in a chat channel beside it."
   },
   {
    "name": "Render what is being approved.",
    "text": "Diff summary, target, blast radius."
   },
   {
    "name": "Capture a hardware signature.",
    "text": "Bound to a person at enrolment."
   },
   {
    "name": "Bind the change hash into the signature.",
    "text": "So approval and change cannot drift apart."
   },
   {
    "name": "Export the population for the auditor.",
    "text": "Not a curated sample."
   }
  ]
 },
 "cta": {
  "title": "Where this fits in Manav",
  "html": "Manav puts the approval on the change: a hardware signature over the rendered diff, with the change hash inside, exportable as a whole population.",
  "href": "../docs.html",
  "label": "See change approvals"
 }
}