Metadata-Version: 2.4
Name: attesto-local-vault
Version: 2.0.1
Summary: Attesto Local Vault: the trust boundary that holds C0/C1 evidence, builds provenance capsules through the pinned edge core, and relays only commitments
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: zk
Requires-Dist: pysodium>=0.7.17; extra == "zk"
Provides-Extra: pkcs11
Requires-Dist: python-pkcs11>=0.7; extra == "pkcs11"
Provides-Extra: dev
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: Pillow==12.1.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.

## Attesto 3 Runtime Shell

Local Vault 2.x introduces three explicit operating modes:

- `legacy-relay` is the default and preserves the Attesto 2.0 relay contract.
- `provenance` is fail-closed and requires a pinned release build of
  `attesto-edge` before it can start provenance work.
- `shadow` prepares the same local runtime alongside a legacy authority lane;
  it does not reinterpret existing legacy evidence.

Check or set the configured mode with:

```bash
attesto-local-vault mode
attesto-local-vault mode --set shadow
```

Provenance/shadow mode requires these local-only runtime settings. They are
binary-integrity coordinates, not secrets:

- `ATTESTO_LOCAL_VAULT_EDGE_CORE_PATH`
- `ATTESTO_LOCAL_VAULT_EDGE_CORE_SHA256`

The signing key may be held in a PKCS#11 token (`L1`) with a TPM 2.0 quote
binding each start to a measurement of the vault (`L2`):
`ATTESTO_LOCAL_VAULT_SIGNING_PROVIDER=software|pkcs11|pkcs11+tpm2`, the
`ATTESTO_LOCAL_VAULT_PKCS11_*` variables and `TPM2TOOLS_TCTI`; install the
`pkcs11` extra. See `docs/LOCAL_VAULT_HARDWARE_CUSTODY.md`. `--vault-assurance`
remains the required minimum, and `attestation self-test|show|register` drive
the record the platform verifies.

The client verifies the binary SHA-256, performs a protocol handshake, and
refuses any edge build that accepts caller-supplied commitment randomizers.
Run a content-free self-test before enabling a provenance policy:

```bash
attesto-local-vault provenance self-test
```

Provider manifests are validated before use. Class S has a closed
`network_policy=deny`; Class D can only use an explicit `upstream_allowlist`.
The execution sandbox itself is introduced with the provider runtime in Sprint
5, so Sprint 2 does not claim that configured manifests are executable yet.

```bash
attesto-local-vault providers list
attesto-local-vault providers doctor
```

The new finalized-evidence queue is deliberately distinct from the legacy raw
relay spool. It stores only finalized C2/C3 envelopes for a transport retry;
no raw source input is required after finalization. Its current SQLite
reference implementation uses WAL plus FULL synchronous transactions. Inspect
only aggregate delivery state with:

```bash
attesto-local-vault queue status
```

Failures use the stable classes below, without putting source content in error
output:

- `F1`: local derivation, attestation, edge-core, or provider preparation
  failure.
- `F2`: delivery of already-finalized evidence failed; retry is safe.
- `F3`: evidence could not be made durable; assured operations must fail.

## Local Provenance Capsules

In `provenance` mode Local Vault can now create an offline-first provenance
capsule. A capsule is a local C1 container, not an API payload and not a
replacement for the Attesto 2.0 relay. Its public-facing material is limited to
the randomized C2 commitments and C3 protocol metadata derived by the pinned
release `attesto-edge` binary.

The long-lived capsule store is separate from the legacy Fernet relay spool:

- every capsule receives a new 256-bit DEK;
- the capsule body uses AES-256-GCM with AAD bound to its capsule ID, schema
  version, and encryption-record version;
- the DEK is separately authenticated and wrapped by
  `ATTESTO_LOCAL_VAULT_CAPSULE_MASTER_KEY`;
- master-key rotation re-wraps DEKs without re-encrypting each capsule;
- retention can cryptographically erase a capsule's DEK and ciphertext;
- no deterministic local asset hash is stored in a database index;
- raw source bytes are never retained by the capsule schema.

`source_ref` is generated at finalization from 128 OS-CSPRNG bits. It is not a
filename, connector ID, source-system record ID, or content hash. The same
local source can therefore create independent public commitments and public
event references.

Bootstrap now provisions the capsule master key through the selected local
secret backend. Existing installations must add it through their secret
manager before provenance mode is used:

```text
ATTESTO_LOCAL_VAULT_CAPSULE_MASTER_KEY=<base64 256-bit secret>
ATTESTO_LOCAL_VAULT_CAPSULE_STORE_DB=/var/lib/attesto/provenance-capsules.sqlite3
```

Only aggregate C2/C3 status is shown by default:

```bash
attesto-local-vault provenance capsule status
attesto-local-vault provenance capsule inspect --capsule-id cap_...
```

Local capsule details are sensitive C1 data. The CLI requires an explicit flag
and writes a warning to stderr before it displays them:

```bash
attesto-local-vault provenance capsule inspect --capsule-id cap_... --show-sensitive
```

Crypto-erasure is irreversible and requires the capsule ID twice to prevent a
mistyped operator command:

```bash
attesto-local-vault provenance capsule erase \
  --capsule-id cap_... --confirm-capsule-id cap_...
```

Finalized envelopes are written to the encrypted finalized-evidence queue and
sent through the dedicated commitment-only endpoint with:

```bash
attesto-local-vault provenance relay-once
attesto-local-vault provenance relay-loop
```

The relay sends the frozen envelope directly; it never wraps or reconstructs a
raw payload. It marks an item delivered only after the platform returns a
matching `provenanceAck`, event hash, and receipt hash. Invalid 2xx responses and
transient transport failures remain retryable; permanent client/schema
rejections enter the dead-letter state for operator resolution. Idempotent
platform replays are accepted only when the exact envelope hash matches.

## 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_PROVENANCE_URL`
- `ATTESTO_LOCAL_VAULT_KEY_ID`
- `ATTESTO_LOCAL_VAULT_ENCRYPTION_KEY`
- `ATTESTO_LOCAL_VAULT_SIGNING_KEY`
- `ATTESTO_LOCAL_VAULT_FINALIZED_QUEUE_DB`
- `ATTESTO_LOCAL_VAULT_CAPSULE_STORE_DB`
- `ATTESTO_LOCAL_VAULT_CAPSULE_MASTER_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.
