Open-source media provenance.
DeltaSync is a set of SDKs and a small protocol, built on C2PA (opens in a new tab). A phone signs a photo with a key that stays on the device. Someone else can check that signature later.
Three packages: a Rust server (c2pa-rs), an iOS SDK (Swift, c2pa-swift, App Attest) and an Android SDK (Kotlin, c2pa-android, Play Integrity).
How it works
DeltaSync v1 shows that a photo was signed by a key in the phone’s secure hardware, and that the DeltaSync app asked for the certificate.
- 1
A key on the phone
The phone creates a P-256 key. iOS uses the Secure Enclave. Android prefers StrongBox, then a hardware-backed keystore, then a software keystore if the device has neither. The private key is not sent to the server. When the key is in secure hardware, it stays in the chip. - 2
Proof it is this app
The phone proves it holds the key by signing a certificate request. In live mode it also proves that the DeltaSync app asked for the certificate: App Attest on iOS, Play Integrity on Android. The proof is bound to a one-time server challenge. - 3
A short-lived certificate
The server checks that attestation in live mode, then signs a certificate for that exact public key. The certificate lasts 15 minutes by default and uses the profile C2PA expects of a signing certificate. - 4
The photo is signed locally
The phone signs a C2PA manifest for the JPEG on the device. c2pa-swift and c2pa-android wrap c2pa-rs: they hash the file and ask the key for an ES256 signature. - 5
A later check
A viewer sends the file to the server. c2pa-rs reads the manifest and trusts the DeltaSync certificate authority that issued the device certificate. A changed byte no longer validates.
Packages
The same protocol, in three trees. The phone apps capture a JPEG and embed the manifest. The server issues the certificate and checks the file.
Rust server
The signing authority and the check. It uses c2pa-rs to read the manifest. In live mode it checks App Attest or Play Integrity before it issues the certificate. The certificate authority key is created on the server. It is not in this repository.iOS SDK
Swift, using c2pa-swift and App Attest. The signing key is created in the Secure Enclave and is not exported. The Simulator cannot use the Secure Enclave or App Attest. A debug build can use an ordinary key and labels that path. That is not a hardware proof, and it only works against a stub server.Android SDK
Kotlin, using c2pa-android and Play Integrity. The app prefers StrongBox and records the backing it actually got: StrongBox, hardware keystore, or software keystore. Skipping Play Integrity is only for a stub server. The recognized Play verdict is for an install from Play, not a sideload.
What this does not do yet
The check is real for a manifest this certificate authority signed. A few pieces are still missing, and the software says so.
Photos, not video
The apps capture a JPEG. They do not capture video. The check also accepts PNG, WebP, and MP4.Stub mode skips attestation
A local server defaults to stub mode. It still requires proof the caller holds the key, and it does not check App Attest or Play Integrity. The response says the attestation was not verified.Apple’s receipt is not sent
Live App Attest checks the certificate chain and the nonce. The receipt is not sent to Apple yet.This authority, not the public list
Verification trusts the DeltaSync certificate authority for manifests it issued. It does not add the public C2PA trust list. A trusted timestamp and an OCSP response are not embedded yet.