# Census Derived Lists

Opaque third-party hash verification using HMAC-SHA256 derived lists.

## What It Solves

A third party needs to check if their suspect files match your attested
inventory — but you don't want to reveal your actual file hashes. Derived
lists solve this by creating HMAC-SHA256 digests of your hashes with a
shared secret key. The third party derives their suspect hashes with the
same key and submits them for comparison. The server compares derived
hashes — neither party's plaintext inventory is exposed.

## Usage

```bash
# Create a derived list from a manifest
census derived-list create --manifest ./manifest.db --label "Q1 2026 Audit"

# Create from a tag filter
census derived-list create --tag-filter '{"and":[{"key":"dept","value":"legal"}]}'

# List all derived lists
census derived-list list --json

# Get details
census derived-list info <list_id>

# Third party: match suspect hashes against the list
census derived-list match <list_id> --list-key <hex64> --hashes-file suspects.txt

# View access audit trail
census derived-list access-log <list_id>

# Revoke a list
census derived-list revoke <list_id>
```

## Workflow

1. **Owner** creates a derived list from manifest hashes or tag filter
2. Server generates HMAC-SHA256 of each hash using a random key
3. Owner receives `list_id` + `list_key` (shown only once)
4. Owner shares `list_id` + `list_key` with the third party
5. **Third party** computes `HMAC-SHA256(list_key, suspect_hash)` for each
   suspect file and submits the derived hashes
6. Server compares derived hashes and returns match count
7. **Owner** reviews the access log for audit trail

## Options

| Option | Description |
|--------|-------------|
| `--manifest` | Manifest to read hashes from |
| `--tag-filter` | JSON tag filter for server-side hash selection |
| `--label` | Human-readable label |
| `--expires` | Expiry in hours (max 2160 = 90 days) |
| `--list-key` | HMAC key (64 hex chars) for match operations |
| `--hashes-file` | File with one SHA-256 hash per line |
| `--limit` | Max access log entries (default: 50) |
| `--json` | Output as JSON |

## SDK Methods

- `client.create_derived_list(hashes, tag_filter, label, expires_in_hours)`
- `client.list_derived_lists()`
- `client.get_derived_list(list_id)`
- `client.match_derived_list(list_id, list_key, hashes)`
- `client.get_derived_list_signature(list_id)`
- `client.get_derived_list_access_log(list_id, limit)`
- `client.revoke_derived_list(list_id)`

Requires API key with `census` scope.

## Security Properties

- Server never sees plaintext hashes from either party
- HMAC key is shown only once at creation — lost keys cannot be recovered
- Lists have configurable expiry (max 90 days)
- Owner can revoke at any time
- All match attempts are logged with IP and timestamp
- List integrity is verifiable via ECDSA signature

## Audit Trail

Create, match, and revoke operations are logged to the tamper-evident audit log.
