Skip to content

contentauth/wp-plugin

Repository files navigation

ContentAuth WordPress Plugin

A WordPress plugin that reads and signs C2PA content credentials, enabling conformant product signatures and CAWG organisational identity signatures.

License: Apache-2.0 OR MIT — pick whichever suits you.


Architecture

WordPress (PHP plugin)          Signing Service (Node.js)
┌────────────────────┐          ┌─────────────────────────┐
│                    │  HTTPS   │                         │
│  Media Library  ──►│─────────►│  POST /v1/sign          │
│  REST API       ──►│          │  POST /v1/read          │
│  Settings page     │◄─────────│  GET  /health           │
│                    │  signed  │                         │
└────────────────────┘  binary  │  Key Provider           │
                                │  ├── local PEM  (dev)   │
                                │  └── AWS KMS   (prod)   │
                                └─────────────────────────┘

The WordPress server never holds a private key. All cryptographic operations happen inside the signing service, which you deploy in a separate, hardened environment.

Signature types

Type What it proves Assertion label
product Content passed through a specific software product (standard C2PA claim)
cawg_org Content is associated with a named organisation cawg.identity
both Both of the above in a single manifest both

Requirements

WordPress plugin

  • PHP 8.1 or later
  • WordPress 6.3 or later

Signing service

  • Node.js 20 or later (or Docker)
  • A code-signing certificate and private key issued by a C2PA-trusted CA

Quick start

1 — Deploy the signing service

cd signing-service

# Copy and fill in the configuration
cp .env.example .env
# Set CONTENTAUTH_API_KEY, SIGNING_CERT_PATH, SIGNING_KEY_PATH

# Create the secrets directory (never commit this)
mkdir -p secrets
cp /path/to/your/signing.crt secrets/
cp /path/to/your/signing.key secrets/
chmod 400 secrets/signing.key

# Start with Docker Compose
docker compose up -d

# Verify it is healthy
curl http://localhost:3000/health

The signing service listens on port 3000 by default. Put it behind a TLS-terminating reverse proxy (nginx, Caddy, AWS ALB) before exposing it to your WP server.

2 — Install the WordPress plugin

# From the plugin directory:
composer install --no-dev

Then upload the plugin directory (or zip it) and activate it through Plugins → Installed Plugins.

3 — Configure the plugin

Go to Settings → Content Authenticity and enter:

  • Service URL — the base URL of your signing service (e.g. https://sign.example.com)
  • API Key — must match CONTENTAUTH_API_KEY in the signing service

For production, define the API key as a constant in wp-config.php instead of saving it to the database:

define( 'CONTENTAUTH_API_KEY', 'your-secret-key-here' );

Click Test signing service connection to verify connectivity.


Key management

Local PEM files (development / air-gapped)

Set KEY_PROVIDER=local and point SIGNING_CERT_PATH / SIGNING_KEY_PATH to your PEM files. The key file is cached in memory after the first read; it is never written anywhere by the service.

AWS KMS (production recommended)

Set KEY_PROVIDER=aws-kms. See signing-service/src/key-providers/aws-kms.js for the current status and integration notes.

Full KMS support (where the raw private key never exists in memory) requires an "external signer" API in c2pa-node, which is not yet available. Until then, the recommended approach for AWS users is:

  1. Store the private key as an encrypted secret in AWS Secrets Manager.
  2. Fetch and decrypt it at signing-service startup using the instance's IAM role.
  3. Hold the decrypted key in memory only (never write to disk).
  4. Rotate the key by redeploying the service.

Obtaining a code-signing certificate

Your certificate must chain to a CA recognised in the C2PA Trust List. Current options include certificates from DigiCert and other C2PA-participating CAs.

For CAWG organisational signatures, the certificate's Subject should identify your organisation.


CAWG Organisational Signatures

When signature_type is cawg_org or both, the plugin adds a cawg.identity assertion to the manifest containing:

  • Your organisation name and canonical URL (set in plugin settings)
  • An optional W3C Verifiable Credential — if your organisation has been issued one by a CAWG-recognised credential issuer, this allows validators to cryptographically verify the organisational claim

The CAWG identity assertion follows the CAWG Identity Assertion specification.


REST API

The plugin registers a REST namespace at contentauth/v1.

GET /contentauth/v1/credentials/{attachment_id}

Returns the C2PA manifest for an attachment. Append ?force=true to bypass the cache and re-read from the file.

Auth: Public for published attachments; edit_post capability for unpublished.

POST /contentauth/v1/credentials/{attachment_id}/sign

Signs an attachment. Optionally accepts signature_type in the JSON body to override the site-wide setting.

Auth: edit_post capability for the attachment.

GET /contentauth/v1/status

Returns signing service health status.

Auth: manage_options capability (administrators).


Development

PHP

composer install
composer lint         # PHP_CodeSniffer with WordPress standards
composer test         # PHPUnit

Signing service

cd signing-service
npm install
npm run dev           # auto-restarts on file changes
npm test

Security considerations

  • Never expose the signing service directly to the internet. Place it behind a private network or VPN and only allow ingress from your WordPress server.
  • Rotate the API key if it is ever compromised. Update it in both wp-config.php and the signing service environment.
  • Restrict file permissions on the signing service key file: chmod 400 signing.key.
  • Monitor the signing service logs for unexpected signing requests.
  • Rate limiting is enabled by default (60 req/min). Adjust RATE_LIMIT_PER_MINUTE for your environment.

Contributing

See CONTRIBUTING.md.

License

Licensed under either of:

at your option.

About

WordPress plugin for reading and signing C2PA content credentials (product and CAWG organisational signatures)

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors