Metadata-Version: 2.4
Name: attesto-local-vault
Version: 0.2.0
Summary: Attesto Local Vault edge relay for proofstream source attestations
Author-email: Attesto <support@attesto.eu>
License-Expression: Apache-2.0
Project-URL: Homepage, https://attesto.eu
Project-URL: Documentation, https://docs.attesto.eu
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: cryptography>=43
Provides-Extra: dev
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: ruff>=0.7; extra == "dev"

# Attesto Local Vault

Attesto Local Vault is the customer-side edge relay for Attesto 2.0
proofstream source attestations. It stores queued attestations in an encrypted
SQLite spool, signs outbound relay envelopes with Ed25519, and sends them to a
registered Attesto Local Vault receiver endpoint.

It can also run as a customer-side proofstream witness: checkpoint progression
is stored locally, accepted checkpoints are signed, and conflicting history
produces fork evidence instead of advancing state.

Runtime keys are supplied by the local deployment secret manager. Private
signing keys, spool encryption keys, and connector credentials are never sent to
Attesto.

The runtime is intentionally idempotent on `(stream_id, source_ref)`, rejects
payload drift for a reused source reference, recovers stale in-flight queue
items after process crashes, and only relays to HTTPS endpoints.

Delivery acknowledgements are fail-closed. Local Vault only marks a queued item
as delivered when the Attesto receiver returns a 2xx JSON receipt with a
`localVaultAck` whose `envelopeHash` matches the signed outbound envelope and
whose stream and canonical `local-vault:{installation_id}:{source_ref}` event
id match the receipt payload. A proxy/misroute 2xx, malformed body, or
mismatched receipt is treated as a failed attempt and remains subject to
retry/dead-letter policy.

## Runtime

`attesto-local-vault drain-loop` is the production runner. It reads its
non-secret runtime coordinates from flags or environment variables and reads
key material only from the local deployment secret manager:

- `ATTESTO_LOCAL_VAULT_SPOOL_DB`
- `ATTESTO_LOCAL_VAULT_INSTALLATION_ID`
- `ATTESTO_LOCAL_VAULT_RELAY_URL`
- `ATTESTO_LOCAL_VAULT_KEY_ID`
- `ATTESTO_LOCAL_VAULT_ENCRYPTION_KEY`
- `ATTESTO_LOCAL_VAULT_SIGNING_KEY`

The packaged Docker image runs as a non-root user, stores the encrypted spool
under `/var/lib/attesto/local-vault.sqlite3`, and defaults to `drain-loop`.

## Witness

`attesto-local-vault witness-checkpoint` is the production operator command for
customer-side checkpoint witnessing. It signs only monotonic progression for a
single `(witness_id, tenant_id, stream_id)` and returns fork evidence for stale
or conflicting checkpoint heads.

```bash
attesto-local-vault --witness-db /var/lib/attesto/local-vault-witness.sqlite3 \
  witness-checkpoint \
  --tenant-id ten_... \
  --stream-id str_... \
  --checkpoint-id chk_... \
  --checkpoint-seq-no 42 \
  --checkpoint-hash "$CHECKPOINT_HASH" \
  --previous-checkpoint-hash "$PREVIOUS_CHECKPOINT_HASH"
```

Witness runtime values are read from flags or environment:

- `ATTESTO_LOCAL_VAULT_WITNESS_DB`
- `ATTESTO_LOCAL_VAULT_WITNESS_ID` set to the Attesto Local Vault installation ID
- `ATTESTO_LOCAL_VAULT_KEY_ID`
- `ATTESTO_LOCAL_VAULT_SIGNING_KEY`

The command output contains public key metadata, signature material, and the
receipt or fork evidence. Receipts and fork evidence are both signed. It never
prints the private signing key.

Submit the JSON output to the Attesto installation witness endpoint:

```text
/v2/local-vault/installations/{installationId}/witness/checkpoints
```

The SaaS endpoint verifies the Local Vault public key, domain-separated
signature, statement/fork hash, checkpoint binding, and monotonic witness state
before persisting anything.
