Metadata-Version: 2.4
Name: csoai-scitt-ts
Version: 0.1.0
Summary: Minimal SCITT Transparency Service for CSOAI measurement cards — registers cards as SCITT Signed Statements with RFC 9162 Merkle receipts.
Author: CSOAI LTD
License: MIT
Keywords: scitt,cose,transparency,csoai,measurement,merkle,rfc9943,rfc9162
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security :: Cryptography
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: cbor2>=5.5
Requires-Dist: cryptography>=42.0
Requires-Dist: scitt-cose>=0.3.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"

# csoai-scitt-ts

[![CI](https://github.com/CSOAI-ORG/csoai-scitt-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/CSOAI-ORG/csoai-scitt-ts/actions/workflows/ci.yml)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![PyPI](https://img.shields.io/pypi/v/csoai-scitt-ts.svg)](https://pypi.org/project/csoai-scitt-ts/)

Minimal **SCITT Transparency Service** for CSOAI measurement cards.

Registers CSOAI measurement cards as [SCITT](https://datatracker.ietf.org/wg/scitt/documents/) **Signed Statements** (RFC 9943) backed by an append-only RFC 9162 Merkle transparency log. Issues **COSE Receipts** (RFC 9052) with inclusion proofs that are verifiable offline.

## Architecture

```
┌─────────────────┐     JSON card     ┌──────────────────────┐
│  CSOAI Council  │ ─────────────────>│  card_to_signed_     │
│  (BFT signer)   │                   │  statement()         │
└─────────────────┘                   │  COSE_Sign1 (EdDSA)  │
                                      └──────────┬───────────┘
                                                  │ CBOR tag-18
                                                  v
                                      ┌──────────────────────┐
                                      │  TransparencyService │
                                      │  ┌────────────────┐  │
                                      │  │ SQLite (append- │  │
                                      │  │ only Merkle log)│  │
                                      │  └────────────────┘  │
                                      │                      │
                                      │  register() → receipt│
                                      └──────────┬───────────┘
                                                  │
                                    ┌─────────────┼─────────────┐
                                    v                           v
                           COSE Receipt                  Transparent
                           (inclusion proof)              Statement
                                    │                   (stmt + receipt)
                                    v
                           ┌──────────────────┐
                           │  verify_csoai_   │
                           │  receipt()       │
                           │  (offline, no TS │
                           │   needed)        │
                           └──────────────────┘
```

## Standards

| Standard | Role |
|----------|------|
| **RFC 9943** | SCITT Architecture — Signed Statements, Transparent Statements, Receipts |
| **RFC 9052/9053** | COSE_Sign1 — the wire format for statements and receipts |
| **RFC 9162** | Certificate Transparency v2 — SHA-256 Merkle tree, inclusion/consistency proofs |
| **RFC 8392** | CWT Claims — issuer (iss) and subject (sub) in the COSE protected header |
| **RFC 9597** | CWT Claims in COSE Headers (label 15) |

## Key Design Decisions

1. **Python (not Go)** — matches CSOAI's existing stack (SOV3, measurement engine).
2. **Ed25519** (COSE algorithm ID `-8`, `"EdDSA"`) — matches CSOAI's existing Ed25519 key infrastructure.
3. **SQLite** for Merkle log storage — simple, portable, no external database required. WAL mode for concurrency.
4. **`scitt-cose` substrate** — builds on the tested, cross-validated `scitt-cose` library for COSE_Sign1, Merkle primitives, and receipt generation/verification. This library implements RFC 9052 from scratch (no external COSE lib dependency) and is cross-verified against Go and pycose implementations.
5. **CWT Claims at label 15** (not 13) — per RFC 9597 §2. Label 13 is `kcwt` (RFC 9528), a different parameter that is sometimes mistakenly used.
6. **Offline verification** — receipts are self-contained COSE_Sign1 objects; verify with only the receipt bytes, the leaf entry, and the log's public key. No network required.
7. **Append-only** — entries are never deleted or reordered. New registrations extend the tree and change the Merkle root.

## Installation

```bash
pip install -e .
# or
pip install cbor2 cryptography scitt-cose
```

## Quick Start

```python
from cryptography.hazmat.primitives.asymmetric import ed25519
from cryptography.hazmat.primitives import serialization

from csoai_scitt_ts.statement import card_to_signed_statement
from csoai_scitt_ts.service import TransparencyService
from csoai_scitt_ts.verify import verify_csoai_receipt

# Generate keys
issuer_sk = ed25519.Ed25519PrivateKey.generate()
issuer_pem = issuer_sk.private_bytes(
    serialization.Encoding.PEM,
    serialization.PrivateFormat.PKCS8,
    serialization.NoEncryption(),
)
log_sk = ed25519.Ed25519PrivateKey.generate()
log_pem = log_sk.private_bytes(
    serialization.Encoding.PEM,
    serialization.PrivateFormat.PKCS8,
    serialization.NoEncryption(),
)
log_pub = log_sk.public_key().public_bytes(
    serialization.Encoding.PEM,
    serialization.PublicFormat.SubjectPublicKeyInfo,
)

# Create a measurement card
card = {
    "card_id": "CARD-2026-001",
    "subject": "https://meok.ai/product/quantum-shield",
    "axes": [
        {"name": "robustness", "score": 0.87},
        {"name": "explainability", "score": 0.74},
    ],
    "overall_score": 0.84,
}

# Sign as a SCITT Signed Statement
stmt = card_to_signed_statement(card, private_key_pem=issuer_pem)

# Register with the Transparency Service
ts = TransparencyService(":memory:", log_pem)
result = ts.register(stmt)
print(f"Entry {result.entry_id}, tree size {result.tree_size}")
print(f"Merkle root: {result.merkle_root_hex}")

# Verify the receipt (offline)
vr = verify_csoai_receipt(
    result.receipt,
    leaf_entry_hex=stmt.hex(),
    log_public_key_pem=log_pub,
)
assert vr.receipt_ok
print(f"Receipt verified! Root: {vr.merkle_root}")
```

## HTTP API

```bash
# Start the server
csoai-scitt-ts serve --port 8443 --db ./scitt.db --key ./log-key.pem
```

### Endpoints

| Method | Path | Description |
|--------|------|-------------|
| `POST` | `/register` | Register a measurement card (JSON body) |
| `GET` | `/entries/{id}` | Get entry metadata by id |
| `GET` | `/receipt/{id}` | Get the COSE Receipt for an entry |
| `GET` | `/tree` | Current tree size and Merkle root |
| `GET` | `/health` | Health check |

### Register a card

```bash
curl -X POST http://localhost:8443/register \
  -H "Content-Type: application/json" \
  -d '{"card_id":"CARD-001","score":0.95}'
```

Response:
```json
{
  "entry_id": 1,
  "leaf_hash": "...",
  "tree_size": 1,
  "merkle_root": "...",
  "receipt_b64": "...",
  "statement_b64": "..."
}
```

### Get a receipt

```bash
curl http://localhost:8443/receipt/1 --output receipt.cbor
```

The receipt is COSE-encoded CBOR (Content-Type: application/cbor).

## Package Structure

```
csoai-scitt-ts/
├── pyproject.toml              # Package metadata
├── README.md
├── csoai_scitt_ts/
│   ├── __init__.py             # Package init
│   ├── statement.py            # Card → COSE_Sign1 Signed Statement
│   ├── service.py              # Transparency Service (SQLite Merkle log)
│   ├── receipt.py              # Receipt generation & transparent statements
│   ├── verify.py               # Receipt verification (offline)
│   ├── api.py                  # HTTP API
│   └── cli.py                  # CLI entry point
└── tests/
    └── test_service.py         # Comprehensive test suite
```

## Testing

```bash
pip install -e ".[dev]"
pytest -v
```

## Compatibility Notes

- **COSE algorithm -8 (EdDSA)**: The SCITT spec uses -8 for EdDSA, which maps to Ed25519. This matches CSOAI's existing key infrastructure. The `scitt-cose` library handles the COSE_Sign1 construction from scratch over `cbor2` + `cryptography`.
- **CWT Claims at label 15**: Per RFC 9597, not label 13 (`kcwt`). This is important for interoperability — some libraries incorrectly use label 13.
- **Merkle tree**: RFC 9162 SHA-256 construction (same as CT v2). Domain-separated leaf hashes (`0x00` prefix) and interior node hashes (`0x01` prefix).
- **Receipt format**: Tracks `draft-ietf-cose-merkle-tree-proofs-18` — vds=1 (RFC9162_SHA256) at label 395, inclusion proofs at label 396.

## License

MIT
