How to sign OpenAI / GPT outputs with cryptographic provenance
If your app calls the OpenAI API, you eventually face a question: "can you prove this came from your system, at this time, from this model?" This page walks through adding cryptographic provenance to any GPT-4o, GPT-4-Turbo, or GPT-3.5 call. One extra line, every output gets a verifiable receipt.
When this matters
Three triggers usually surface this need:
- A customer disputes the authenticity of AI-generated content you delivered. They claim it was edited, plagiarized, or generated by something other than what you said.
- Enterprise procurement asks for an audit trail of AI usage as part of vendor onboarding.
- EU AI Act Article 50 enforcement (August 2026) requires AI-generated content to be marked in machine-readable form. Cryptographic signatures are the strongest available implementation.
Your database timestamp is not proof. Database logs can be modified. Your own systems cannot independently attest to their own outputs. You need a third-party cryptographic record that anyone can verify without contacting you.
The setup
Get a CertNode API key at certnode.io/ai-provenance. First 100 signings every month are free, no card required.
Install the SDK:
npm install @certnode/sdk openaiSign every chat completion
import OpenAI from 'openai'
import { CertNode } from '@certnode/sdk'
const openai = new OpenAI()
const cert = new CertNode({ apiKey: process.env.CERTNODE_API_KEY! })
const completion = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'user', content: 'Summarize this article in 200 words' }
]
})
const text = completion.choices[0].message.content!
// One extra line. Every output gets a verifiable receipt.
const signed = await cert.signAIOutput({
output: text,
model: 'gpt-4o',
provider: 'openai',
})
console.log(signed.receiptId)
console.log(signed.verifyUrl)
// signed.verifyUrl is a public page anyone can visit to verifyThat is the entire integration. The receipt contains the SHA-256 hash of the output, the model identifier, the provider name, and three independent timestamps (CertNode internal + RFC 3161 + Bitcoin anchor).
Sign with prompt-hash for privacy
If your prompts contain sensitive information you do not want stored in the receipt, sign the prompt hash instead of the prompt itself. The receipt then proves "this output was generated from a prompt with this hash" without exposing the prompt content.
import { createHash } from 'crypto'
const prompt = 'Confidential prompt content here'
const promptHash = createHash('sha256').update(prompt).digest('hex')
const signed = await cert.signAIOutput({
output: text,
model: 'gpt-4o',
provider: 'openai',
promptHash,
})Later, if you need to prove the output came from a specific prompt, hash the prompt at verification time and compare against the stored hash. No prompt content leaks.
Sign streaming responses
For streaming completions, accumulate the output and sign once at the end:
const stream = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: 'Long response here' }],
stream: true,
})
let fullText = ''
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content || ''
fullText += delta
process.stdout.write(delta)
}
const signed = await cert.signAIOutput({
output: fullText,
model: 'gpt-4o',
provider: 'openai',
})The signature is computed over the complete output. Streaming doesn't change the cryptographic guarantee.
Verifying later
Anyone (not just you) can verify the receipt at the public verify page:
https://certnode.io/verify/provenance/<receiptId>Programmatic verification is also free and requires no API key:
const verification = await cert.verify({ receiptId: signed.receiptId })
console.log(verification.valid) // true
console.log(verification.signatureValid) // true
console.log(verification.receipt.model) // 'gpt-4o'
console.log(verification.receipt.signedAt) // ISO 8601 timestampIf you also want to confirm the content matches (defense against tampering), pass the original output:
const verification = await cert.verify({
receiptId: signed.receiptId,
content: storedOutput,
})
console.log(verification.contentMatches) // true if content is unmodifiedWhat gets stored, what doesn't
CertNode stores the SHA-256 hash of your output, not the output itself. The metadata (model, provider, timestamp, optional prompt hash) is stored. The full content is your problem to retain, we can prove a specific output existed at a specific time, but you need to keep the content if you want to prove what was said.
This is intentional. Storing customer AI outputs would create a privacy and liability surface we do not want, and would make CertNode less useful for regulated content (healthcare, legal, finance) where the customer must retain control.
Pricing for OpenAI workloads
CertNode is multi-model. The pricing is the same whether you sign GPT, Claude, Mistral, or Llama outputs:
| Monthly volume | Per signing |
|---|---|
| 0, 100 | Free |
| 100, 10K | $0.010 |
| 10K, 100K | $0.007 |
| 100K, 1M | $0.004 |
| 1M+ | $0.002 |
Volume discounts apply automatically. There is no tier migration. Verifications are always free.
Comparison to OpenAI native options
OpenAI does not currently offer native cryptographic provenance for chat completion outputs. Their image generation models (DALL-E 3) attach C2PA metadata. Their text models do not.
If OpenAI ships native text signing in the future, CertNode AI Provenance still has a defensible position: multi-model stacks. Most production AI applications call multiple model providers (OpenAI for one task, Claude for another, open-source for a third). A neutral third-party signer that works across all providers is more useful than provider-specific signing for any team running more than one model.
FRE 902 and EU AI Act framing
Receipts are designed to satisfy Federal Rule of Evidence 902(13) (records produced by a system that produces accurate results) and 902(14) (records that include a digital signature verified through a trusted certifying authority). The three-layer timestamp chain is intentionally over-built for this standard so receipts hold up under skeptical examination.
For EU AI Act Article 50 (enforces August 2026), CertNode signatures provide the machine-readable AI marking that providers of generative AI must attach to their outputs. The signature includes the model identifier, provider, and generation time, exactly the metadata the regulation requires.
Sign your first OpenAI output
100 signings/month free. No card required. Works with GPT-4o, GPT-4-Turbo, and any other OpenAI text model.