ContentAuthenticity 0.77.0
See the version list below for details.
dotnet add package ContentAuthenticity --version 0.77.0
NuGet\Install-Package ContentAuthenticity -Version 0.77.0
<PackageReference Include="ContentAuthenticity" Version="0.77.0" />
<PackageVersion Include="ContentAuthenticity" Version="0.77.0" />
<PackageReference Include="ContentAuthenticity" />
paket add ContentAuthenticity --version 0.77.0
#r "nuget: ContentAuthenticity, 0.77.0"
#:package ContentAuthenticity@0.77.0
#addin nuget:?package=ContentAuthenticity&version=0.77.0
#tool nuget:?package=ContentAuthenticity&version=0.77.0
c2pa.net
.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 thec2pa.hheader and emits platform-specific binding files underlib/Bindings/*. The dispatcher inlib/C2paBindings.csselects 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.
Read an asset and use the typed ManifestStore
using ContentAuthenticity;
using static ContentAUthenticty.Reader;
var assetPath = "./my-image.jpg";
using var reader = Reader.FromFile(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}");
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, you can 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;
using static ContentAuthenticity.Builder;
// 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 Builder.ClaimGeneratorInfo { Name = "c2pa.net" }
],
Assertions =
[
new ActionAssertion(
[
new ActionV1("c2pa.edited"),
]),
new CreativeWorkAssertions(
new CreativeWorkAsertionData
{
Type = "MyType",
Context = new {
"SomeName" = "SomeValue"
}
}
)
]
};
using var builder = Builder.Create(definition);
// Optional: add extra resources that the manifest may reference (thumbnails, etc.)
builder.AddResource("thumbnail", "./thumbnail.jpg");
builder.AddIngredient(...)
// Signing requires an `ISigner` implementation (see `example/` projects for working signers).
Signer signer = Signer.FromSettings();/* Signer.From(someISigner) */
var input = "./my-image.jpg";
var output = "./my-image.signed.jpg";
// Writes a signed asset to `output` and returns the embedded manifest bytes.
byte[] manifestBytes = builder.Sign(signer, input, output);
Prerequisites
- .NET 10.0 SDK or later
- Rust toolchain (for building the native c2pa-rs library)
- Git with submodule support
- ClangSharp
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:
- Updates the submodule to point to the new tag
- Creates a pull request with the update details
- 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
Option 1: Using .NET CLI (Recommended)
# 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
- Open
c2pa.net.slnin Visual Studio - Select the desired configuration (Debug/Release) and platform (x64)
- 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 testsexample/- Example CLI application demonstrating usagegenerator/- Code generator for creating .NET bindings from Rustc2pa-rs/- Git submodule containing the Rust c2pa library
Troubleshooting
Common Issues
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"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-gnuSubmodule not initialized: If you see build errors related to missing Rust code:
git submodule update --init --recursive
Contributing
- Fork the repository
- Create a feature branch
- Update the submodule to the appropriate c2pa-rs version if needed
- Make your changes
- Run tests to ensure everything works
- Submit a pull request
| Product | Versions 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. |
-
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.78.8 | 47 | 4/2/2026 |
| 0.78.7 | 88 | 3/30/2026 |
| 0.78.6 | 79 | 3/26/2026 |
| 0.78.5 | 85 | 3/24/2026 |
| 0.78.4 | 86 | 3/17/2026 |
| 0.78.3 | 104 | 3/17/2026 |
| 0.78.1 | 82 | 3/12/2026 |
| 0.78.0 | 88 | 3/11/2026 |
| 0.77.1 | 92 | 3/11/2026 |
| 0.77.0 | 94 | 3/10/2026 |
| 0.76.2 | 84 | 3/4/2026 |
| 0.76.1 | 93 | 3/2/2026 |
| 0.76.0 | 89 | 2/26/2026 |
| 0.75.21 | 104 | 2/13/2026 |
| 0.75.19 | 103 | 2/10/2026 |
| 0.75.15 | 106 | 2/7/2026 |
| 0.75.13 | 105 | 2/4/2026 |
| 0.75.7.1 | 104 | 1/28/2026 |
| 0.75.7 | 100 | 1/28/2026 |
| 0.75.6 | 105 | 1/26/2026 |