Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AIMark Sidecar v2.4

A non-invasive, sidecar-friendly marking, detection, and provenance layer for EU AI Act Article 50(2) provider workflows.

AIMark is designed to bolt onto an existing model stack after generation:

model output (unchanged)
  ├─ signed AIMark provenance receipt        (Ed25519 + trusted JWKS)
  ├─ C2PA manifest/signing path              (c2patool for supported assets)
  ├─ fingerprint registry                    (exact/excerpt/light-edit matching)
  ├─ public detection endpoint               (/detect)
  └─ interoperability signpost               (/.well-known/ai-content-provenance)

Shipping posture

This is a minimal compliance candidate, not legal certification.

It is shipping-oriented only when you configure the operational pieces:

  1. Stable provider signing key in a KMS/HSM.
  2. Published public JWKS/trust-registry entry.
  3. Official c2patool installed and configured with production C2PA signing credentials or signer-path.
  4. Public/free detection endpoint where required.
  5. Calibrated thresholds and documented false-positive/false-negative behavior.
  6. Non-removal terms adopted into the provider/deployer terms.
  7. Written equivalence memo if you omit intrinsic text watermarking.

The design is intentionally honest: current common c2patool write support is still media-focused, even though the C2PA 2.3/2.4 specification added text and structured-text embedding. Raw .txt is therefore not claimed as embedded C2PA unless the provider supplies a text-capable C2PA signer. For raw text, AIMark exports a non-invasive fallback package:

output.txt
output.txt.aimark.json
output.txt.c2pa-manifest.json
C2PA_TEXT_FALLBACK_NOTES.txt

For true embedded C2PA, export to a supported asset/container and run aimark c2pa-sign.

Install

pip install -e .

Quickstart

# Generate AIMark receipt signing keys.
aimark keygen --out aimark-ed25519.pem --pub-out aimark.jwks.json --key-id acme-key-1

# Mark text without changing output.
aimark mark output.txt --private-key aimark-ed25519.pem --key-id acme-key-1 \
  --provider Acme --model-id acme-1 --out output.txt.aimark.json

# Verify with trusted JWKS. This is the production-trust path.
aimark verify output.txt --receipt output.txt.aimark.json \
  --trusted-jwks aimark.jwks.json --require-trusted

# Detect from raw content alone after metadata is stripped.
cat output.txt | aimark detect --registry aimark_registry.sqlite3

# Export raw-text fallback package.
aimark export-package output.txt --private-key aimark-ed25519.pem \
  --key-id acme-key-1 --provider Acme --model-id acme-1 --out-dir package

C2PA path

Create a C2PA manifest definition:

aimark c2pa-manifest --receipt output.txt.aimark.json --asset image.png --out c2pa-manifest.json

Check whether a file can be written with C2PA by current tooling:

aimark c2pa-supports image.png

Sign/embed using the official c2patool:

aimark c2pa-sign image.png \
  --receipt output.txt.aimark.json \
  --out signed-image.png \
  --manifest-out c2pa-manifest.json \
  --signer-path ./production-c2pa-signer

Verify the signed asset, enforcing trust against the provider's published JWKS (same trust root as the receipt layer). For production embedded C2PA verification, let c2patool inspect the asset; a separately supplied manifest definition is only a non-embedded fallback check.

aimark c2pa-verify signed-image.png \
  --trusted-jwks aimark.jwks.json --require-trusted

Verification returns aimark_signature_valid, aimark_signature_trusted, asset_binding_checked, binding_mode, and accepted_for_production. A self-signed or forged manifest is valid but not trusted, so it is not accepted. A standalone manifest-definition JSON may be accepted as a non-embedded fallback, but it is not accepted as production embedded C2PA until c2patool validates the asset binding.

c2pa-sign fails closed without a production signer (--signer-path, --remote, or --settings). For non-production testing only, pass --allow-dev-signer; the result is marked production: false. Never ship a dev-signed asset.

AIMark fails closed for formats not in the current common c2patool write set. That includes .txt, .json, and current read-only .pdf; .md remains fallback-only unless the provider deploys a C2PA 2.4 structured-text signer.

Python SDK

from aimark_sidecar import AIMarkSidecar, Signer, Registry

signer = Signer.from_pem(open("aimark-ed25519.pem", "rb").read(), key_id="acme-key-1")
sidecar = AIMarkSidecar(signer=signer, registry=Registry("registry.sqlite3"), provider_default="Acme")

result = sidecar.mark(text, model_id="acme-1")
assert result["text"] == text
receipt = result["ai_provenance"]

verification = sidecar.verify(text, receipt, require_trusted=True)
detection = sidecar.detect(text)

Gateway endpoints

GET  /health
GET  /pubkey
GET  /.well-known/ai-content-provenance
GET  /compliance
POST /mark              {text, provider, model_id}
POST /verify            {text, receipt}
POST /detect            {text}
POST /c2pa/manifest     {receipt, asset_filename}

Put auth in front of /mark. /detect is meant to be public where required.

Why this stays non-invasive

AIMark does not change generated text. The second layer is a registry/fingerprint and detection layer. That is a deliberate alternative route for text; if a customer or regulator requires strict intrinsic watermarking, add the optional watermark adapter rather than altering the default output path.

What this does not claim

  • It is not legal certification.
  • It is not embedded C2PA for raw text unless the provider supplies a text-capable C2PA 2.3/2.4 signer.
  • It does not use C2PA test certificates for production.
  • It does not prove authorship after heavy paraphrase.
  • It does not replace visible UI labelling duties for deployers.

Run as a gateway with Docker (set env, run)

The fastest way to adopt the sidecar with minimal effort: configure by environment, run the container.

cp .env.example .env          # fill in provider, key path, registry path, base URL
docker compose up --build     # gateway on :8765, data persisted in a volume

POST /mark after generation (auth in front of it), and expose POST /detect publicly and free of charge. All configuration is via environment variables (see .env.example and aimark_sidecar/config.py); no code edits required.

Compliance documentation

This package ships the documents a provider needs to adopt and defend the posture — not just the code:

  • EQUIVALENCE_JUSTIFICATION.md — the reasoned basis for the no-watermark text approach under Article 50(2)'s alternative-approach allowance. The artifact a gap analysis starts from. Complete it and have counsel review it.
  • INTEGRATION.md — how a provider bolts the sidecar on (inline or gateway), and the registration-coverage control that detection depends on.
  • COMPLIANCE_MAP.md — measure-by-measure mapping (also machine-readable via GET /compliance).
  • DATA_PROTECTION.md — registry/detection GDPR considerations and DPIA prompt.
  • TERMS_NONREMOVAL.md — the Measure 1.2 terms clause to adopt.
  • SHIPPING_CHECKLIST.md — the go-live gate. The package is a minimal- compliance candidate, not a certification: real signing credentials, registration coverage, and counsel sign-off sit outside the code.

About

A non-invasive, sidecar-friendly marking, detection, and provenance layer for EU AI Act Article 50(2) provider workflows

Resources

Contributing

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages