A cryptographically secure, append-only storage system for manifests with verifiable transparency log capabilities. Originally designed for Content Authenticity Initiative (C2PA) manifests but supports any structured content requiring tamper-evident storage.
- Verifiable Transparency Log: Merkle tree-based proof system for manifest inclusion
- Cryptographic Security: Ed25519 signatures and SHA384 hashing via atlas-common
- Multiple Content Formats: Support for JSON, CBOR, and binary manifests
- Append-Only Guarantee: Immutable storage with sequence numbers
- Proof Generation: Inclusion and consistency proofs for third-party verification
- RESTful API: Easy integration with existing systems
- Architecture Documentation - Detailed system design and implementation details
- API Reference - Complete API endpoint documentation
- Rust 1.70+
- MongoDB 4.0+
- OpenSSL development libraries
- Docker and Docker Compose (optional)
- Clone the repository:
git clone https://github.com/IntelLabs/atlas-transparency-log.git
cd atlas-transparency-log
- Build the project:
cargo build --release
- Set up environment variables:
export MONGODB_URI="mongodb://localhost:27017"
export DB_NAME="atlas_manifests"
export SERVER_HOST="0.0.0.0"
export SERVER_PORT="8080"
export KEY_PATH="transparency_log_key.pem"
- Run the service:
cargo run --release
- Clone the repository:
git clone https://github.com/IntelLabs/atlas-transparency-log.git
cd atlas-transparency-log
- Build and run with Docker Compose:
docker-compose up -d
- Check service health:
curl http://localhost:8080/merkle/root
The service will start at http://localhost:8080
.
# JSON manifest
curl -X POST http://localhost:8080/manifests/my-manifest-123 \
-H "Content-Type: application/json" \
-d '{
"manifest_type": "image",
"data": "example content"
}'
# CBOR manifest
curl -X POST http://localhost:8080/manifests/my-manifest-456 \
-H "Content-Type: application/cbor" \
--data-binary @manifest.cbor
# Binary manifest with type parameter
curl -X POST http://localhost:8080/manifests/my-manifest-789?manifest_type=video \
-H "Content-Type: application/octet-stream" \
--data-binary @manifest.bin
# C2PA URN format
curl -X POST http://localhost:8080/manifests/urn:c2pa:123e4567-e89b-12d3-a456-426614174000 \
-H "Content-Type: application/json" \
-d '{"manifest_type": "model", "data": "ML model manifest"}'
curl http://localhost:8080/manifests/my-manifest-123/proof
Response:
{
"manifest_id": "my-manifest-123",
"leaf_index": 42,
"leaf_hash": "base64_hash...",
"merkle_path": ["hash1", "hash2", "hash3"],
"root_hash": "base64_root_hash...",
"tree_size": 100
}
curl -X POST http://localhost:8080/merkle/verify \
-H "Content-Type: application/json" \
-d '{
"manifest_id": "my-manifest-123",
"leaf_index": 42,
"leaf_hash": "base64_hash...",
"merkle_path": ["hash1", "hash2", "hash3"],
"root_hash": "base64_root_hash...",
"tree_size": 100
}'
Method | Endpoint | Description |
---|---|---|
POST | /manifests/{id} |
Store a new manifest |
GET | /manifests/{id} |
Retrieve a manifest by ID |
GET | /manifests |
List manifests with pagination |
GET | /types/{type}/manifests |
List manifests by type |
Method | Endpoint | Description |
---|---|---|
GET | /manifests/{id}/proof |
Get inclusion proof for a manifest |
GET | /merkle/root |
Get current Merkle root |
POST | /merkle/verify |
Verify an inclusion proof |
GET | /merkle/stats |
Get tree statistics |
GET | /merkle/consistency |
Get consistency proof between sizes |
POST | /merkle/consistency/verify |
Verify consistency proof |
GET | /merkle/root/{size} |
Get historical root for specific size |
limit
- Maximum number of results (default: 100)skip
- Number of results to skip (default: 0)manifest_type
- Filter by manifest typeformat
- Filter by content format (json/cbor/binary)
old_size
- Old tree sizenew_size
- New tree size
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run specific test
cargo test test_merkle_tree_multiple_leaves
# Test atlas-common integration
cargo test test_atlas_common_integration
atlas-transparency-log/
├── Cargo.toml # Dependencies including atlas-common
├── README.md
├── ARCHITECTURE.md
├── Dockerfile # Docker container configuration
├── compose.yml # Multi-service deployment
└── src/
├── main.rs # HTTP server and API endpoints
├── tests.rs # Integration tests
└── merkle_tree/ # Merkle tree implementation
├── mod.rs
├── hasher.rs # Wrapper for atlas-common
├── proof.rs # Proof structures and traits
└── tree.rs # Core tree implementation
- atlas-common: Provides standardized hashing (SHA256/384/512) and validation utilities
- actix-web: Web framework for HTTP API
- mongodb: Database driver
- ring: Cryptographic primitives for Ed25519 signatures
- serde: Serialization/deserialization
-
Private Key Protection: The Ed25519 private key is stored in a file. Ensure proper file permissions and consider using a HSM in production.
-
Input Validation: Manifest IDs are validated using atlas-common's validation functions:
- C2PA URN format:
urn:c2pa:UUID[:claim_generator[:version_reason]]
- Plain UUIDs:
123e4567-e89b-12d3-a456-426614174000
- Alphanumeric strings with hyphens, underscores, and dots (max 256 chars)
- C2PA URN format:
-
Cryptographic Security:
- SHA384 hashing (default) via atlas-common
- Constant-time hash comparison to prevent timing attacks
- Ed25519 signatures for content authenticity
-
Size Limits: Maximum manifest size is 10MB to prevent DoS attacks.
-
Append-Only: No deletion or modification operations are supported to maintain log integrity.
- Proof Generation: O(log n) time complexity
- Storage: Linear growth with number of manifests
- Verification: Constant time for individual proofs
- Tree Reconstruction: O(n) on startup if needed
- Hashing: Optimized SHA384 implementation via atlas-common
# Check container logs
docker-compose logs atlas_service
# Rebuild containers
docker-compose build --no-cache
# Check container health
docker-compose ps
# Check MongoDB is running
docker-compose logs mongodb
# Verify connection string
docker exec -it atlas_mongodb mongosh
# Check write permissions
ls -la transparency_log_key.pem
# Generate key manually
openssl genpkey -algorithm Ed25519 -out transparency_log_key.pem
# Test hash validation
curl -X POST http://localhost:8080/manifests/test \
-H "Content-Type: application/json" \
-d '{"test": "data"}'
# Check logs for validation details
docker-compose logs atlas_service
- Default limit is 10MB
- Adjust
MAX_MANIFEST_SIZE
inmain.rs
if needed
Variable | Description | Default |
---|---|---|
MONGODB_URI |
MongoDB connection string | mongodb://localhost:27017 |
DB_NAME |
Database name | atlas_manifests |
SERVER_HOST |
Server bind address | 0.0.0.0 |
SERVER_PORT |
Server port | 8080 |
KEY_PATH |
Ed25519 private key file path | transparency_log_key.pem |
RUST_LOG |
Logging level | info |