Skip to main content

Sign C2PA manifests using Azure Trusted Signing.

Project description

c2pa-azure-py

Sign files with C2PA content credentials using the Azure Trusted Signing service.

The project ships in two forms from a single codebase:

  • A Python library (c2pa_azure) you can import in your own apps.
  • A standalone CLI (c2pa-azure-sign) you can run from the shell or a container.

Installation

From source

git clone https://github.com/duggaraju/c2pa-azure-py.git
cd c2pa-azure-py
python -m venv .venv
source .venv/bin/activate            # Windows: .venv\Scripts\activate
pip install .                        # add -e for an editable/dev install

As a dependency in another project

pip install c2pa-azure                # once published to PyPI
# or directly from a Git ref:
pip install git+https://github.com/duggaraju/c2pa-azure-py.git

Authentication

Sign in to Azure before running. Any credential supported by DefaultAzureCredential will work (Azure CLI, Managed Identity, environment variables, etc.).

az login
# In WSL or headless environments:
az login --use-device-code

CLI usage

c2pa-azure-sign \
    -i path/to/input.jpg \
    -o path/to/output.jpg \
    -e https://<region>.codesigning.azure.net/ \
    -a <trusted-signing-account> \
    -c <certificate-profile>

Equivalent invocation without an entry-point script:

python -m c2pa_azure -i input.jpg -o output.jpg -e https://... -a acct -c profile

Optional flags:

Flag Description
-m, --manifest Path to a manifest JSON file, or an inline manifest string. Defaults to the bundled manifest.json.
-s, --settings Path to a C2PA settings TOML file.
-f, --force Overwrite the output file if it already exists (default: on).

Library usage

from azure.identity import DefaultAzureCredential
from c2pa_azure import AzureSigner, TrustedSigningSettings

credential = DefaultAzureCredential()

settings = TrustedSigningSettings(
    certificate_profile="my-cert-profile",
    service_account="my-trusted-signing-account",
    endpoint="https://eus.codesigning.azure.net/",
    # Optional: TOML-formatted C2PA settings string. None = library defaults.
    c2pa_settings=None,
)

manifest = """
{
  "claim_generator": "my_app/1.0.0",
  "title": "My Signed Image",
  "assertions": [
    { "label": "stds.schema-org.CreativeWork",
      "data": { "@context": "https://schema.org", "@type": "CreativeWork",
                "author": [{ "@type": "Person", "name": "Jane Doe" }] } }
  ]
}
"""

signer = AzureSigner(credential, settings, manifest)
signer.sign("input.jpg", "output.jpg")

Loading the bundled manifest

from importlib.resources import files
from c2pa_azure import AzureSigner, TrustedSigningSettings

manifest = files("c2pa_azure.data").joinpath("manifest.json").read_text()

Calling the low-level Trusted Signing client

from azure.identity import DefaultAzureCredential
from c2pa_azure import TrustedSigningClient, TrustedSigningSettings

settings = TrustedSigningSettings(
    "profile", "account", "https://eus.codesigning.azure.net/"
)
client = TrustedSigningClient(DefaultAzureCredential(), settings)

cert_chain_p7b = client.get_certificate_chain()
signature = client.sign(b"<sha384 digest bytes>")

Invoking the CLI from Python

from c2pa_azure.cli import main

exit_code = main([
    "-i", "input.jpg",
    "-o", "output.jpg",
    "-e", "https://eus.codesigning.azure.net/",
    "-a", "my-account",
    "-c", "my-cert-profile",
])

Docker

docker build -t c2pa-azure .
docker run --rm \
    -v "$PWD:/data" \
    -e AZURE_CLIENT_ID -e AZURE_TENANT_ID -e AZURE_CLIENT_SECRET \
    c2pa-azure \
    -i /data/input.jpg -o /data/output.jpg \
    -e https://<region>.codesigning.azure.net/ \
    -a <account> -c <certificate-profile>

Project layout

src/c2pa_azure/
├── __init__.py          # public API: AzureSigner, TrustedSigningClient, TrustedSigningSettings
├── __main__.py          # enables `python -m c2pa_azure`
├── cli.py               # argparse entry point (c2pa-azure-sign)
├── signer.py            # AzureSigner
├── trusted_signing.py   # TrustedSigningClient + TrustedSigningSettings
└── data/                # bundled manifest.json and settings.json

Development

pip install -e ".[dev]"
pytest
python -m build           # produces dist/*.whl and dist/*.tar.gz

License

This project is licensed under the MIT License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

c2pa_azure-0.32.6.0.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

c2pa_azure-0.32.6.0-py3-none-any.whl (14.8 kB view details)

Uploaded Python 3

File details

Details for the file c2pa_azure-0.32.6.0.tar.gz.

File metadata

  • Download URL: c2pa_azure-0.32.6.0.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for c2pa_azure-0.32.6.0.tar.gz
Algorithm Hash digest
SHA256 97d3c8c4ecf984404089f4a59803bd1f3cb3af471320dc0190c1e7e2dd0b621c
MD5 a31bab9d5c75b71971afb64f2a508282
BLAKE2b-256 be909d87dc250c1a4b6459e7ffc3a7b627f101b2f4c53b3eebe15d49b1a49856

See more details on using hashes here.

File details

Details for the file c2pa_azure-0.32.6.0-py3-none-any.whl.

File metadata

  • Download URL: c2pa_azure-0.32.6.0-py3-none-any.whl
  • Upload date:
  • Size: 14.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for c2pa_azure-0.32.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ba55f15f7eb11469550e87662e2ebb44d06d8c57b5b262de6b348ed4ce49a2b6
MD5 df85ed2139cd151d3183c7143188877b
BLAKE2b-256 e04faa4b4c61dfe8af49604b54dd0e79680482c1c107550c17708e6363becc7f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page