feat(v2): complete v2 reimplementation
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# M11 recovery import evidence
|
||||
|
||||
- Recovery bundles use the existing versioned `BTREC` Argon2id/AES-GCM codec
|
||||
and now carry a version-2 authenticated catalog containing repositories,
|
||||
key epochs, sources, jobs, executions, and backups required for encrypted
|
||||
restore.
|
||||
- `backup-tool admin recovery import` requires a migrated empty destination DB,
|
||||
re-inspects every surviving repository through configured allowlists, writes
|
||||
signing/data keys exclusively with mode `0600`, and rejects conflicts.
|
||||
- Imported sources are `unavailable`; imported jobs are `archived` and disabled.
|
||||
Imported metadata therefore supports existing restore records without silently
|
||||
restarting backup schedules.
|
||||
- The focused host-loss drill exports an encrypted backup, imports it into a
|
||||
fresh metadata/key host, and restores the file byte-for-byte. It also proves
|
||||
unsafe repository paths and non-empty destination metadata are rejected.
|
||||
- Encrypted repository creation is enabled only after that drill passed and now
|
||||
records its active data-key epoch atomically with repository metadata.
|
||||
- Interrupted imports remove newly installed key files on handled failure; a
|
||||
retry also safely adopts only exact, authenticated key files left by an
|
||||
unclean process loss. Rotation writes an fsynced repository journal before
|
||||
its DB transition; worker startup deterministically completes a committed
|
||||
epoch transition or removes an uncommitted one while retaining old-active.
|
||||
A stale rollback journal is cleared safely even when the unreferenced new key
|
||||
was already deleted before the journal cleanup could run.
|
||||
- Key-aware GC decrypts encrypted manifests using their declared epoch key and
|
||||
remains fail-closed for absent, wrong, or corrupt keys/manifests. Restore
|
||||
removes setuid, setgid, and sticky bits from captured modes. Migration 0007
|
||||
refuses downgrade while key metadata is populated.
|
||||
- Recovery catalog import preserves backup `created_at` and `tombstoned_at`.
|
||||
- Snapshot staging roots, per-execution directories, blob directories, and
|
||||
plaintext temporary blobs are created owner-only (`0700`/`0600`) independent
|
||||
of umask and are rejected if their permissions are unsafe.
|
||||
|
||||
## Verification
|
||||
|
||||
```text
|
||||
pytest tests/integration/test_encrypted_repository.py -q
|
||||
5 passed
|
||||
|
||||
make test-fault
|
||||
11 passed
|
||||
|
||||
make test-security
|
||||
21 passed
|
||||
|
||||
make lint && make typecheck && make frontend-build
|
||||
passed
|
||||
|
||||
make check
|
||||
86 unit/contract, 53 integration, 12 fault, and 22 security tests passed;
|
||||
Ruff, mypy, TypeScript, and frontend build passed.
|
||||
|
||||
git diff --check && git diff --cached --quiet
|
||||
passed
|
||||
```
|
||||
Reference in New Issue
Block a user