signedshot-validator 0.1.7

Validator for SignedShot media authenticity proofs
Documentation
# SignedShot Validator

Verify SignedShot media authenticity proofs. Available as a Rust CLI and Python library.

[![PyPI](https://img.shields.io/pypi/v/signedshot)](https://pypi.org/project/signedshot/)
[![crates.io](https://img.shields.io/crates/v/signedshot-validator)](https://crates.io/crates/signedshot-validator)
[![CI](https://github.com/SignedShot/signedshot-validator/actions/workflows/ci.yml/badge.svg)](https://github.com/SignedShot/signedshot-validator/actions/workflows/ci.yml)

## Overview

SignedShot is an open protocol for proving photos and videos haven't been altered since capture. This validator verifies the cryptographic proofs (sidecars) generated by the SignedShot iOS SDK.

## Installation

### Python (PyPI)

```bash
pip install signedshot
```

### Rust (Cargo)

```bash
cargo install signedshot-validator
```

## Python Library

```python
import signedshot

# Validate from files
result = signedshot.validate_files("photo.sidecar.json", "photo.jpg")

print(result.valid)           # True/False
print(result.version)         # Sidecar format version
print(result.error)           # Error message if validation failed

# Capture trust (JWT verification)
trust = result.capture_trust
print(trust["signature_valid"])  # JWT signature verified
print(trust["issuer"])           # API that issued the token
print(trust["publisher_id"])     # Publisher ID
print(trust["device_id"])        # Device ID
print(trust["capture_id"])       # Capture session ID
print(trust["method"])           # Attestation: "sandbox", "app_check", or "app_attest"
print(trust["app_id"])           # App bundle ID (if attested)
print(trust["issued_at"])        # Unix timestamp

# Media integrity (content verification)
integrity = result.media_integrity
print(integrity["content_hash_valid"])  # SHA-256 hash matches
print(integrity["signature_valid"])     # ECDSA signature verified
print(integrity["capture_id_match"])    # Capture IDs match
print(integrity["content_hash"])        # SHA-256 of media
print(integrity["captured_at"])         # ISO8601 timestamp
```

### Validate from Bytes

```python
# Validate from in-memory data
with open("photo.sidecar.json") as f:
    sidecar_json = f.read()
with open("photo.jpg", "rb") as f:
    media_bytes = f.read()

result = signedshot.validate(sidecar_json, media_bytes)
```

### Validate with Pre-loaded JWKS

```python
# Avoid HTTP call by providing JWKS directly
import requests

jwks = requests.get("https://api.signedshot.io/.well-known/jwks.json").text
result = signedshot.validate_with_jwks(sidecar_json, media_bytes, jwks)
```

### Convert to Dict/JSON

```python
# Get result as dictionary
data = result.to_dict()

# Get result as JSON string
json_str = result.to_json()
```

## CLI Usage

### Validate Media

```bash
# Basic validation
signedshot validate photo.sidecar.json photo.jpg

# Output as JSON
signedshot validate photo.sidecar.json photo.jpg --json
```

### Parse Sidecar (without validation)

```bash
signedshot parse photo.sidecar.json
```

### Example Output

```
Validating sidecar: photo.sidecar.json
Media file: photo.jpg
[OK] Sidecar parsed
[OK] JWT decoded
  Issuer: https://api.signedshot.io
  Publisher: 9a5b1062-a8fe-4871-bdc1-fe54e96cbf1c
  Device: ea5c9bfe-6bbc-4ee2-b82d-0bcfcc185ef1
  Capture: ac85dbd2-d8a8-4d0b-9e39-2feef5f7b19f
  Method: app_check
  App ID: io.signedshot.capture
[OK] JWT signature verified
[OK] Content hash matches
[OK] Media signature verified
[OK] Capture IDs match

✓ VALID - Media authenticity verified
```

## What It Validates

### 1. Capture Trust (JWT)

- Fetches JWKS from issuer (or uses provided keys)
- Verifies ES256 (P-256 ECDSA) signature
- Extracts claims: publisher, device, capture ID, attestation method

### 2. Media Integrity

- Computes SHA-256 hash of media file
- Compares with `content_hash` in sidecar
- Verifies ECDSA signature over integrity data
- Confirms `capture_id` matches JWT

### 3. Cross-Validation

- Ensures capture_id in JWT matches capture_id in media_integrity
- Validates all timestamps and formats

## Building from Source

### Rust CLI

```bash
git clone https://github.com/SignedShot/signedshot-validator.git
cd signedshot-validator

cargo build --release
./target/release/signedshot --help
```

### Python Wheels

```bash
# Install maturin
pip install maturin

# Build wheel
cd python
maturin build --release

# Install locally
pip install ../target/wheels/signedshot-*.whl
```

## Development

```bash
# Format
cargo fmt

# Lint
cargo clippy -- -D warnings

# Test
cargo test

# Build
cargo build --release
```

## Related Repositories

- [signedshot-api]https://github.com/SignedShot/signedshot-api - Backend API
- [signedshot-ios]https://github.com/SignedShot/signedshot-ios - iOS SDK

## Links

- [PyPI Package]https://pypi.org/project/signedshot/
- [Website]https://signedshot.io
- [Documentation]https://signedshot.io/docs
- [Interactive Demo]https://signedshot.io/demo

## License

MIT License - see [LICENSE](LICENSE) for details.