Free2PA How it works

Free2PA checks the file before the agent can read it.

Agent control files are executable context. Free2PA puts a signed receipt beside each protected file, verifies the receipt at the load boundary, and returns a simple decision: LOAD, REJECT, or restore the signed original before the model sees anything.

1 Sign reviewed text

A trusted publisher signs the approved control file and creates a neighboring receipt.

2 Verify before load

The host checks the receipt exactly where it would normally read prompts, skills, tools, or policy.

3 Return a decision

Unchanged and trusted files get LOAD. Failed proof gets REJECT.

4 Restore if allowed

If the file was edited, Free2PA can recover the signed original and report the rejected change.

1. The receipt sits beside the file

The control file stays readable Markdown. The proof lives in a sidecar, so existing apps can adopt Free2PA without inventing a new prompt format.

SOUL.md
# Hello World Agent

Respond with:
Hello, <positive> world!
SOUL.md.c2pa.json
{
  "asset": {
    "hash": "sha256...",
    "content": "base64..."
  },
  "signature": "ES256..."
}

2. The verifier checks separate facts

Receipt signatureWas this receipt signed by the certificate inside it?
PASS
File hashDoes the current file still match the signed hash?
PASS
Certificate currentIs the publisher certificate inside its validity window?
PASS
Publisher trustedIs that certificate in this app's local trust group?
PASS

3. The app gets a small answer

Free2PA does not need to become the agent framework. It returns a load decision the host can enforce before model context is built.

LOAD

The file is signed, unchanged, current, and locally trusted. The verified text can enter model context.

REJECT

The receipt is invalid, the file changed, the certificate is stale, or the publisher is outside the group.

RESTORE + RUN + REPORT

The edited file is rejected, the signed original is recovered, and the event is reported.

STOP + REPORT

Repair is refused if the receipt, certificate, or publisher trust does not verify.

4. Add it at the read path

The integration point is the moment your app reads a control file.

import { loadVerifiedFile } from 'free2pa/load-gate';

const instructions = await loadVerifiedFile({
  assetPath: 'SOUL.md',
  trustStore: 'trusted-publishers',
});

// Only verified text reaches model context.
await model.responses.create({
  instructions,
  input: userMessage,
});

5. Restore is deliberately narrow

Repair is not a way to bless changed instructions. It only uses the original content embedded in a valid, current, locally trusted receipt.

Changed file detected

The current file hash does not match the signed hash, so the changed text is not loaded.

Trusted receipt verified

The receipt signature, certificate, and publisher trust still pass.

Signed original recovered

The embedded original is decoded, re-hashed, and used only if it matches the signed hash.

6. GPT-5.6 is the behavioral audit layer, not the trust gate

Free2PA meaningfully uses GPT-5.6 after provenance verification. The deterministic gate answers whether a control file may load. GPT-5.6 can then review the verified text for behavioral risks the signature cannot explain, such as prompt injection, secret access, destructive actions, exfiltration, unsafe downloads, or excessive permissions.

Free2PA gate

Signature, file hash, certificate validity, and verifier-local publisher trust decide LOAD, REJECT, or guarded restore.

GPT-5.6 audit

The CLI, HTTP API, and MCP audit_skill tool call GPT-5.6 through the Responses API or Azure OpenAI and require a structured JSON risk report.

No override

GPT-5.6 can explain risk in already verified instructions, but it cannot convert failed provenance into LOAD.