ContentAuthenticity 0.84.1

dotnet add package ContentAuthenticity --version 0.84.1
                    
NuGet\Install-Package ContentAuthenticity -Version 0.84.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ContentAuthenticity" Version="0.84.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ContentAuthenticity" Version="0.84.1" />
                    
Directory.Packages.props
<PackageReference Include="ContentAuthenticity" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ContentAuthenticity --version 0.84.1
                    
#r "nuget: ContentAuthenticity, 0.84.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ContentAuthenticity@0.84.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ContentAuthenticity&version=0.84.1
                    
Install as a Cake Addin
#tool nuget:?package=ContentAuthenticity&version=0.84.1
                    
Install as a Cake Tool

c2pa.net

License: MIT c2pa-rs NuGet Target Framework

.NET bindings for c2pa Rust library.

Description

This repository provides a .NET-friendly API surface over the native c2pa_c C ABI exposed by the upstream c2pa-rs project.

  • Interop bindings are generated automatically: the build runs the clangsharppinvokegenerator .NET tool (ClangSharp P/Invoke Generator) against the c2pa.h header and emits platform-specific binding files under lib/Bindings/*. The dispatcher in lib/C2paBindings.cs selects the correct platform/architecture implementation at runtime.
  • Typed models are generated from JSON Schema for safety: the generator/ project is a Roslyn incremental source generator that reads the C2PA JSON schemas (e.g., Builder/Reader/Settings) and emits strongly-typed C# models during compilation. This keeps the high-level API strongly typed (compile-time checks + IntelliSense) instead of relying on loosely-typed JSON strings.

Usage

The Reader and Builder classes have strongly-typed models generated from JSON Schema.

Reading and signing are now driven by an immutable Context, produced from a ContextBuilder. The context owns shared configuration (settings, signer, HTTP resolver, progress callback, etc.) and is then handed to a Reader or Builder. This keeps per-operation classes thin and lets you reuse one configured context across many reads/signs.

Read an asset and use the typed ManifestStore

using ContentAuthenticity;

var assetPath = "./my-image.jpg";

// Build a context. Settings/HTTP resolver are optional; defaults are fine for
// most reads.
using var contextBuilder = ContextBuilder.New();
// contextBuilder.SetHttpResolver(new HttpResolver()); // optional, for remote manifests
using var context = contextBuilder.Build();

// Attach the context to a Reader and feed it the asset.
using var reader = Reader.FromContext(context).WithFile(assetPath);

// Raw JSON (if you need it)
string json = reader.Json;

// Strongly-typed view of the manifest store
ManifestStore store = reader.Store;

Console.WriteLine($"Embedded: {reader.IsEmbedded}");
Console.WriteLine($"Active manifest: {store.ActiveManifest}");

if (store.Manifests.TryGetValue(store.ActiveManifest, out var manifest))
{
    Console.WriteLine($"Title: {manifest.Title}");
    Console.WriteLine($"Format: {manifest.Format}");

    // Example: if the manifest has a thumbnail resource reference, fetch it.
    if (manifest.Thumbnail is not null)
    {
        using var thumbOut = File.Create("./thumbnail.bin");
        reader.ResourceToStream(new Uri(manifest.Thumbnail.Identifier), thumbOut);
    }
}

// Round-trip back to JSON using the same schema-driven serializer options.
string roundTripped = store.ToJson();

Create a typed manifest definition and sign an asset

using ContentAuthenticity;

// Build a minimal typed manifest definition.
// The schema requires `NoEmbed` to be set.
var definition = new ManifestDefinition
{
    NoEmbed = false,
    Title = "my-image.jpg",
    Format = "image/jpeg",
    InstanceId = Builder.GenerateInstanceID(),
    ClaimGeneratorInfo =
    [
        new ClaimGeneratorInfo { Name = "c2pa.net" }
    ],
    Assertions =
    [
        new ActionAssertion(
        [
            new ActionV1("c2pa.edited"),
        ]),
    ],
};

// Provide an ISigner implementation (see `example/` projects for working signers,
// including local PEM/key signers and Azure Key Vault).
ISigner signer = /* new FileSigner(certPem, keyPem, tsaUrl) */ ...;

// Configure a context with the signer (and any other shared options).
using var contextBuilder = ContextBuilder.New();
contextBuilder.SetSigner(signer);
contextBuilder.SetHttpResolver(new HttpResolver()); // optional
using var context = contextBuilder.Build();

// Attach the context to a Builder and apply the typed manifest definition.
using var builder = Builder.FromContext(context).WithDefinition(definition);

// Optional: add extra resources that the manifest may reference (thumbnails, etc.)
builder.AddResource("thumbnail", "./thumbnail.jpg");

var input = "./my-image.jpg";
var output = "./my-image.signed.jpg";

// Sign using the signer configured on the context.
builder.Sign(input, output);

Prerequisites

Development

1. Clone the Repository

git clone --recurse-submodules https://github.com/duggaraju/c2pa.net.git
cd c2pa.net

If you've already cloned the repository without submodules, initialize them:

git submodule update --init --recursive

2. Update Submodule to Specific Release Tag

The c2pa-rs submodule is automatically updated by a GitHub Actions workflow that monitors the upstream repository for new C FFI release tags matching the pattern c2pa-c-ffi-vx.x.x. When a new tag is detected, the workflow:

  1. Updates the submodule to point to the new tag
  2. Creates a pull request with the update details
  3. Includes the tag information and release notes link in the PR description

The workflow runs automatically every 6 hours, but can also be triggered manually:

# Go to Actions tab in GitHub UI
# Select "Update c2pa-rs Submodule" workflow
# Click "Run workflow"
# Optionally specify a specific tag (e.g., c2pa-c-ffi-v0.75.21)

Manual Update (if needed):

If you need to manually update the submodule to a specific release tag:

# Navigate to the submodule directory
cd c2pa-rs

# Fetch all tags from the remote repository
git fetch --tags

# List available c2pa-c-ffi tags
git tag -l 'c2pa-c-ffi-v*'

# Checkout to a specific release tag (replace with desired version)
git checkout c2pa-c-ffi-v0.75.21

# Return to the root directory
cd ..

# Commit the submodule update
git add c2pa-rs
git commit -m "Update c2pa-rs submodule to c2pa-c-ffi-v0.75.21"

3. Build the Project

# Build the entire solution
dotnet restore && dotnet tool restore
dotnet build

# Build
dotnet build
# or build in Release Mode.
dotnet build --configuration Release

Option 2: Using Visual Studio
  1. Open c2pa.net.sln in Visual Studio
  2. Select the desired configuration (Debug/Release) and platform (x64)
  3. Build → Build Solution (Ctrl+Shift+B)

4. Run Tests

# Run all tests
dotnet test

# Run tests with verbose output
dotnet test --verbosity normal

5. Run Example

# Navigate to the example CLI project
cd example/Cli

# Run the example
dotnet run

6. Package

Create a nuget package for publishing.

cd lib
dotnet pack

Project Structure

  • lib/ - Main .NET bindings library (ContentAuthenticity.Bindings)
  • tests/ - Unit and integration tests
  • example/ - Example CLI application demonstrating usage
  • generator/ - Code generator for creating .NET bindings from Rust
  • c2pa-rs/ - Git submodule containing the Rust c2pa library

Troubleshooting

Common Issues

  1. Missing c2pa_c.dll: Ensure the Rust library is built first:

    cd c2pa-rs
    cargo build --release -p c2pa-c-ffi --no-default-features --features "rust_native_crypto, file_io"
    
  2. Missing Rust Tooling: Ensure that you have cargo installed and right toolset present (e.g cross compiling for ARM64):

    rustup target add aarch64-unknown-linux-gnu
    
  3. Submodule not initialized: If you see build errors related to missing Rust code:

    git submodule update --init --recursive
    

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Update the submodule to the appropriate c2pa-rs version if needed
  4. Make your changes
  5. Run tests to ensure everything works
  6. Submit a pull request
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.84.1 89 5/13/2026
0.84.0 110 5/12/2026
0.83.0 111 5/11/2026
0.82.1.1 197 5/5/2026
0.82.1 82 5/5/2026
0.82.0 116 5/3/2026
0.80.3.3 94 4/30/2026
0.80.3.2 87 4/30/2026
0.80.3.1 87 4/30/2026
0.80.3 99 4/29/2026
0.80.2 101 4/29/2026
0.80.1 94 4/28/2026
0.80.0 93 4/21/2026
0.79.5 92 4/16/2026
0.79.4 89 4/16/2026
0.79.3 144 4/10/2026
0.79.2 97 4/10/2026
0.79.0 99 4/8/2026
0.78.8 104 4/2/2026
0.78.7 104 3/30/2026
Loading failed