Fence managed file object effects
This commit is contained in:
+52
-3
@@ -517,6 +517,50 @@ dry-run by default, rechecks that no database reference exists, remains scoped
|
||||
to the scanned tenant prefix, and is idempotent. Both applied and dry-run
|
||||
actions emit audit evidence.
|
||||
|
||||
### Recovery ledger for object effects
|
||||
|
||||
Every managed blob creation or integrity repair starts a Core recovery
|
||||
operation in an independent committed transaction before Files protects or
|
||||
writes bytes. The operation records tenant/blob identifiers, an opaque object
|
||||
locator or locator digest, semantic SHA-256/size evidence, the recovery mode,
|
||||
and a distributed lease fence. It never records file contents, ZIP passwords,
|
||||
connector credentials, or a newly uploaded filename. New object keys are opaque;
|
||||
legacy filename-bearing keys remain readable but repair operations record only
|
||||
their digest and recover through the blob ID.
|
||||
|
||||
The Files business transaction then creates or updates the blob, version, and
|
||||
asset rows. Its actual SQLAlchemy commit or rollback settles every pending
|
||||
operation:
|
||||
|
||||
- commit reloads the blob through an independent session and streams the object
|
||||
to verify its stored-byte SHA-256 and size before recording success;
|
||||
- rollback deletes only a newly reserved object after independently proving
|
||||
that no `FileBlob` references it, then records verified compensation;
|
||||
- a repaired existing object is forward-completed only when its identity,
|
||||
envelope, semantic evidence, and stored bytes all match;
|
||||
- missing or mismatched bytes quarantine a committed blob and leave the
|
||||
operation `recovery_required`; an unavailable probe remains
|
||||
`outcome_unknown` rather than becoming an ordinary upload failure.
|
||||
|
||||
Applied orphan cleanup has its own forward-recovery operation. The database
|
||||
reference check and tenant-prefix check happen before deletion; object absence
|
||||
and the durable finding state are verified afterward. If the caller transaction
|
||||
rolls back after deletion, Files may forward-complete only that existing
|
||||
finding after rechecking that the key is still unreferenced.
|
||||
|
||||
Archive preview and confirmation use bounded process-local temporary staging.
|
||||
Staging is not authoritative and is removed on every handled exit; extracted
|
||||
members enter the same per-blob recovery boundary as direct uploads. A hard
|
||||
process loss may leave a temporary OS file for normal host temporary-file
|
||||
cleanup, but cannot make that staging path a managed Files object.
|
||||
|
||||
Use the Ops recovery-operation view to inspect `files` operations. Do not retry
|
||||
a busy or unresolved blob blindly: first verify the FileBlob row, object hash,
|
||||
integrity state, and any Encryption envelope named by the blob. Hard purge,
|
||||
legal hold, and two-way remote connector mutation are not implemented yet, so
|
||||
they cannot claim recovery-ledger adoption; their owning work remains tracked
|
||||
separately.
|
||||
|
||||
After restore:
|
||||
|
||||
1. Verify the active tenant and module migration state.
|
||||
@@ -644,6 +688,9 @@ Files baseline indiscriminately.
|
||||
every protected blob; they are identical for unprotected blobs.
|
||||
- Upload and archive-confirm APIs can select an Encryption vault. Protected
|
||||
writes and reads fail closed if the optional Encryption capability is absent.
|
||||
- Managed-object writes and applied orphan cleanup start lease-fenced Core
|
||||
recovery operations before their physical effects; terminal success and
|
||||
compensation require independent database and object checks.
|
||||
|
||||
The module does **not** currently provide malware scanning, content disarm and
|
||||
reconstruction, a file-type allowlist, per-user quota, automatic encryption
|
||||
@@ -794,8 +841,8 @@ returning different content or credentials.
|
||||
|
||||
| Area | Implemented now | Planned or explicitly outside the current boundary |
|
||||
| --- | --- | --- |
|
||||
| Managed storage | Core local/S3 backend, exact managed-Garage or explicitly trusted HTTPS external S3, state-profile validation, fallback local read roots, tenant blob deduplication, checksums, bounded resumable integrity scans, quarantine, and dry-run-first orphan cleanup | Scheduled scan execution and deployment-specific S3 HA/backup automation |
|
||||
| Upload | Bounded direct upload, drag-and-drop UI, archive preview/selective extraction, password-protected ZIP support, explicit conflicts | Malware scanning, quotas, type policy, resumable/chunked upload |
|
||||
| Managed storage | Core local/S3 backend, exact managed-Garage or explicitly trusted HTTPS external S3, state-profile validation, fallback local read roots, tenant blob deduplication, checksums, bounded resumable integrity scans, quarantine, dry-run-first orphan cleanup, and Core-ledger verification/forward recovery | Scheduled scan execution and deployment-specific S3 HA/backup automation |
|
||||
| Upload | Bounded direct upload, drag-and-drop UI, archive preview/selective extraction, password-protected ZIP support, explicit conflicts, opaque new object keys, and rollback compensation | Malware scanning, quotas, type policy, resumable/chunked upload |
|
||||
| Organization | Folders, bulk rename preview/apply, move/copy, drag-and-drop, ZIP download, pattern resolution | General file-history UI and user-driven append-version/restore |
|
||||
| Sharing | User/group/tenant/campaign grants, expiry, idempotent revocation, searchable share-management UI, and campaign linkage display | Richer policy-driven share lifecycles |
|
||||
| Deletion/retention | Soft-delete assets/folders/spaces; immediate audited connector-secret scrubbing | File restore API, hard purge, retention policy, legal hold, and blob GC ([#38](https://git.add-ideas.de/GovOPlaN/govoplan-files/issues/38)) |
|
||||
@@ -829,7 +876,9 @@ Before releasing Files:
|
||||
8. Verify credential deletion scrubs dependents and produces audit evidence.
|
||||
9. Verify a campaign attachment snapshot still identifies its exact version and
|
||||
checksum after the current file changes.
|
||||
10. Update the implemented/planned table whenever a boundary changes.
|
||||
10. Exercise a committed upload, a rolled-back upload, object tamper detection,
|
||||
and applied orphan cleanup; inspect their `files` operations in Ops.
|
||||
11. Update the implemented/planned table whenever a boundary changes.
|
||||
|
||||
## Related documents
|
||||
|
||||
|
||||
@@ -10,6 +10,13 @@ versioning, configured blob backend, and conflict behavior. An idempotency key
|
||||
is represented as source provenance so an unchanged retry does not create an
|
||||
unrelated file version.
|
||||
|
||||
The shared Files session owns finalization. Before a new managed object is
|
||||
written, Files commits a lease-fenced Core recovery operation containing only
|
||||
identifiers and digests. The caller's eventual session commit independently
|
||||
verifies both `FileBlob` metadata and stored bytes; rollback compensates only an
|
||||
unreferenced key. Producers must therefore complete the supplied transaction
|
||||
normally and must not bypass or replace Files session lifecycle handling.
|
||||
|
||||
The response contains only file/version identifiers, display path, media type,
|
||||
size, digest, and storage provenance. Producers must not put credentials,
|
||||
tokens, or rendered plaintext into metadata. Storing an artifact proves Files
|
||||
|
||||
Reference in New Issue
Block a user