Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"metadata": {},
"outputs": [],
"source": [
"%pip install boto3 numpy pillow matplotlib --quiet"
"%pip install boto3 numpy pillow matplotlib c2pa-python --quiet"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"4. Background Removal\n",
"5. Image Variation\n",
"6. Image Conditioning\n",
"7. Color Conditioning\n"
"7. Color Conditioning\n",
"8. Content Provenance\n"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,345 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "83632d5f",
"metadata": {},
"source": [
"## Introduction to Content Provenance\n",
"\n",
"Content Credentials (C2PA) is a built-in feature of Amazon Nova Canvas that enables verification and tracking of AI-generated images. This capability adds cryptographically verifiable metadata to every generated image, documenting its origin, creation process, and any subsequent modifications. The metadata includes details such as generation timestamp, model information, and AWS's digital signature, enabling both automated and manual verification of authenticity.\n",
"\n",
"### Use Case\n",
"\n",
"OctankFashion wants to ensure transparency with their customers about their use of AI in their marketing materials. They need a reliable way to:\n",
"1. Prove the authenticity of their AI-generated product images\n",
"2. Track modifications made through their design workflow\n",
"3. Allow customers to verify the authenticity of marketing materials\n",
"4. Create a verification process for their creative team to ensure compliance\n",
"\n",
"To demonstrate these capabilities, we'll explore how Content Credentials are:\n",
"- Automatically embedded during image generation\n",
"- Preserved and updated through editing operations\n",
"- Verified using both programmatic tools and user-friendly interfaces\n"
]
},
{
"cell_type": "markdown",
"id": "7eac1c0f",
"metadata": {},
"source": [
"<div class=\"alert alert-block alert-warning\">\n",
"<b>Prerequisites:</b> Please run the prerequisites <b>00-prerequisites.ipynb</b> first before proceeding.\n",
"</div>\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "80af40c9",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"import json\n",
"import base64\n",
"import boto3\n",
"from botocore.config import Config\n",
"from PIL import Image\n",
"from utils import (\n",
" plot_images,\n",
" save_binary_image,\n",
" display_image_with_metadata,\n",
" verify_c2pa_metadata,\n",
" track_edit_provenance\n",
")\n",
"\n",
"bedrock_runtime_client = boto3.client(\n",
" \"bedrock-runtime\",\n",
" region_name=\"us-east-1\",\n",
" config=Config(\n",
" read_timeout=5 * 60\n",
" ),\n",
")\n",
"image_generation_model_id = \"amazon.nova-canvas-v1:0\"\n",
"output_dir = \"output\""
]
},
{
"cell_type": "markdown",
"id": "cb61977f",
"metadata": {
"tags": []
},
"source": [
"#### Example 1: Generating Images with Provenance\n",
"\n",
"Amazon Nova Canvas automatically embeds Content Credentials metadata in every generated image. This metadata provides a cryptographically verifiable record that includes:\n",
"\n",
"- **Manifest Identifier**: A unique UUID for the manifest\n",
"- **Generator Information**: Details about Nova Canvas and AWS Bedrock\n",
"- **Creation Time**: Precise timestamp of generation\n",
"- **Digital Signature**: AWS's cryptographic signature\n",
"- **AI Generation Markers**: Explicit indication of AI generation\n",
"\n",
"The C2PA manifest includes several key components:\n",
"- `claim_generator`: Identifies the software/system that created the image\n",
"- `claim_generator_info`: Detailed information about the generation process\n",
"- `assertions`: List of claims about the image, including creation time and AI attribution\n",
"- `signature_info`: Cryptographic signature details from AWS\n",
"\n",
"This metadata can be verified in two ways:\n",
"1. Through the [Content Credentials Verify](https://contentcredentials.org/verify) website\n",
"2. Programmatically using the [C2PA library](https://opensource.contentauthenticity.org/docs/c2pa-python/) as demonstrated below"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6e9e5747",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# Generate a simple product image\n",
"text = \"A white t-shirt with a modern geometric pattern, professional product photography\"\n",
"\n",
"body = json.dumps({\n",
" \"taskType\": \"TEXT_IMAGE\",\n",
" \"textToImageParams\": {\"text\": text},\n",
" \"imageGenerationConfig\": {\n",
" \"numberOfImages\": 1,\n",
" \"width\": 1024,\n",
" \"height\": 1024,\n",
" \"cfgScale\": 6.5,\n",
" \"seed\": 42,\n",
" \"quality\": \"premium\"\n",
" }\n",
"})\n",
"\n",
"print(\"Generating image...\")\n",
"response = bedrock_runtime_client.invoke_model(\n",
" body=body,\n",
" modelId=image_generation_model_id,\n",
" accept=\"application/json\",\n",
" contentType=\"application/json\"\n",
")\n",
"\n",
"response_body = json.loads(response.get(\"body\").read())\n",
"base64_image = response_body.get(\"images\")[0]\n",
"\n",
"# Save the image preserving C2PA metadata\n",
"image_path = f\"{output_dir}/08-provenance-original.png\"\n",
"save_binary_image(base64_image, image_path)\n",
"print(f\"\\nImage saved to: {image_path}\")\n",
"\n",
"# Display image and metadata using utils.plot_images\n",
"c2pa_info = display_image_with_metadata(image_path)"
]
},
{
"cell_type": "markdown",
"id": "19ecc82e",
"metadata": {
"tags": []
},
"source": [
"### Example 2: Verifying Image Provenance\n",
"\n",
"Verification of Content Credentials is crucial for establishing trust in AI-generated content. This example demonstrates how to programmatically verify an image's authenticity using the C2PA Python library. The verification process includes:\n",
"\n",
"**Verification Components:**\n",
"- **Digital Signature Validation**: Verifies AWS's cryptographic signature\n",
"- **Manifest Integrity**: Ensures the manifest hasn't been tampered with\n",
"- **Creation Information**: Validates timestamp and generator details\n",
"- **AI Attribution**: Confirms AI generation markers\n",
"\n",
"**Key Metadata Fields:**\n",
"- `signature_info`: Contains the AWS digital signature and certificate information\n",
"- `actions`: Documents creation time and AI generation markers\n",
"- `claim_generator_info`: Provides details about the generation software\n",
"\n",
"The verification can be integrated into automated workflows where programmatic verification is needed, while the Content Credentials Verify website provides a user-friendly interface for manual verification.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e2ea365c",
"metadata": {},
"outputs": [],
"source": [
"# Verify an image with C2PA metadata\n",
"print(\"Verifying image provenance...\")\n",
"verification_result = verify_c2pa_metadata(f\"{output_dir}/08-provenance-original.png\")\n",
"\n",
"if verification_result['verified']:\n",
" print(\"\\nVerification Status: ✓ Image verified\")\n",
" print(\"\\nSource Information:\")\n",
" print(f\"Generator: {verification_result['source']['generator']}\")\n",
" print(\"\\nGenerator Details:\")\n",
" for info in verification_result['source']['generator_info']:\n",
" print(f\"- {info['name']}\" + (f\" v{info['version']}\" if 'version' in info else \"\"))\n",
"\n",
" print(\"\\nCreation Information:\")\n",
" print(f\"Action: {verification_result['creation']['action']}\")\n",
" print(f\"Time: {verification_result['creation']['time']}\")\n",
" print(f\"AI Generated: {'Yes' if verification_result['creation']['ai_generated'] else 'No'}\")\n",
"\n",
" print(\"\\nSignature Information:\")\n",
" sig_info = verification_result['signature']\n",
" print(f\"Issuer: {sig_info['issuer']}\")\n",
" print(f\"Algorithm: {sig_info['alg']}\")\n",
" print(f\"Time: {sig_info['time']}\")\n",
" print(f\"Certificate SN: {sig_info['cert_serial_number']}\")\n",
"\n",
" # Display the verified image\n",
" img = Image.open(f\"{output_dir}/08-provenance-original.png\")\n",
" plot_images([img], processed_title=\"Verified Image with C2PA Metadata\")\n",
"else:\n",
" print(\"\\nVerification Status: ✗ Image not verified\")\n",
" print(f\"Reason: {verification_result['reason']}\")"
]
},
{
"cell_type": "markdown",
"id": "80c0589e",
"metadata": {
"tags": []
},
"source": [
"### Example 3: Maintaining Provenance Through Edits\n",
"\n",
"When editing images using Nova Canvas features like inpainting or outpainting, the Content Credentials are updated to reflect these modifications. Each edit operation generates a new manifest with updated metadata that documents the change while maintaining cryptographic verifiability.\n",
"\n",
"**Key Changes in Edit Manifests:**\n",
"- **New Manifest ID**: A unique UUID for the edited version\n",
"- **Updated Action**: Changes from `c2pa.created` to `c2pa.edited`\n",
"- **New Timestamp**: Records when the edit occurred\n",
"- **Preserved Generator Info**: Maintains the link to Nova Canvas as the editing tool\n",
"- **Updated Signature**: New cryptographic signature validating the edit\n",
"\n",
"**Key Fields for Edit Tracking:**\n",
"- `active_manifest`: Points to the most recent manifest\n",
"- `claim_generator`: Identifies Nova Canvas as the editing tool\n",
"- `actions`: Documents the edit operation with:\n",
" - Type: `c2pa.edited`\n",
" - Timestamp: When the edit occurred\n",
" - Software agent: Nova Canvas\n",
" - Digital source type: Confirms AI-based modification\n",
"\n",
"This example demonstrates how Nova Canvas maintains verifiable provenance through editing operations by creating new signed manifests that document each modification."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ad3dc304-cb45-4f11-bb81-0b7945608410",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"# First, let's read our original image\n",
"with open(f\"{output_dir}/08-provenance-original.png\", \"rb\") as image_file:\n",
" original_image = base64.b64encode(image_file.read()).decode('utf8')\n",
"\n",
"# Perform an inpainting operation to add a logo\n",
"body = json.dumps({\n",
" \"taskType\": \"INPAINTING\",\n",
" \"inPaintingParams\": {\n",
" \"text\": \"Add a small company logo to the t-shirt\",\n",
" \"image\": original_image,\n",
" \"maskPrompt\": \"center of the t-shirt\",\n",
" },\n",
" \"imageGenerationConfig\": {\n",
" \"numberOfImages\": 1,\n",
" \"cfgScale\": 6.5,\n",
" \"seed\": 42,\n",
" \"quality\": \"premium\"\n",
" }\n",
"})\n",
"\n",
"print(\"Performing inpainting...\")\n",
"response = bedrock_runtime_client.invoke_model(\n",
" body=body,\n",
" modelId=image_generation_model_id,\n",
" accept=\"application/json\",\n",
" contentType=\"application/json\"\n",
")\n",
"\n",
"response_body = json.loads(response.get(\"body\").read())\n",
"base64_image = response_body.get(\"images\")[0]\n",
"\n",
"# Save the edited image preserving C2PA metadata\n",
"edited_path = f\"{output_dir}/08-provenance-edited.png\"\n",
"save_binary_image(base64_image, edited_path)\n",
"print(f\"\\nEdited image saved to: {edited_path}\")\n",
"\n",
"# Compare provenance before and after editing\n",
"print(\"\\nComparing manifests before and after editing...\")\n",
"comparison = track_edit_provenance(\n",
" f\"{output_dir}/08-provenance-original.png\",\n",
" edited_path\n",
")\n",
"\n",
"# Display key changes summary\n",
"print(\"\\nKey Changes Summary:\")\n",
"print(\"-\" * 50)\n",
"if 'error' not in comparison:\n",
" original_time = comparison['original']['creation_time']\n",
" edited_time = comparison['edited']['creation_time']\n",
" print(f\"Original Manifest ID: {comparison['original']['manifest_id']}\")\n",
" print(f\"Created: {original_time}\")\n",
" print(f\"\\nEdited Manifest ID: {comparison['edited']['manifest_id']}\")\n",
" print(f\"Modified: {edited_time}\")\n",
"else:\n",
" print(f\"Error: {comparison['error']}\")"
]
},
{
"cell_type": "markdown",
"id": "01fc6841",
"metadata": {},
"source": [
"## Take Away\n",
"\n",
"Content provenance is a crucial feature of Amazon Nova Canvas that enables transparency and trust in AI-generated images. Through this notebook, we've explored how to:\n",
"\n",
"1. Generate images with built-in provenance metadata\n",
"2. Verify the authenticity of Nova Canvas-generated images\n",
"3. Maintain provenance through editing operations\n",
"\n",
"This capability is particularly valuable for businesses like OctankFashion that want to be transparent about their use of AI in marketing materials while maintaining trust with their customers.\n",
"\n",
"Key points to remember:\n",
"- All Nova Canvas-generated images include provenance metadata by default\n",
"- Provenance information persists through supported editing operations\n",
"- Verification can be automated and integrated into existing workflows\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "conda_python3",
"language": "python",
"name": "conda_python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading