Next slice of epic #413, following the #771 profile-images recipe. Passports and travel documents are encrypted client-of-storage-side by SecureDocumentStorageService (IEncryptionService envelope + ISensitiveDataAuditService audit trail on every access) and the CIPHERTEXT lands in Mongo GridFS bucket sensitive-documents. Per the epic, blobs belong in MinIO — and this slice is low-risk precisely because MinIO only ever holds ciphertext; the encryption envelope and audit logging move over untouched.
Extract the raw byte-store behind SecureDocumentStorageService into a small ISensitiveBlobStore seam (GridFS impl = local-dev fallback, S3 impl = prod via the shared SpikerSoft.Storage registration, bucket sensitive-documents, key = existing GridFS id so no Mongo document rewrites). Encryption/audit stay in the single service — no duplication.
MinIO bucket + api-svc rw grant (live + provision-minio-svc-users.sh parity, infra PR).
Tests: seam unit tests both impls; all existing suites stay green.
After deploy + live verification: drop GridFS sensitive-documents.files/.chunks (operator go-ahead, mongodump archive first — note archive contains ciphertext only).
Remaining GridFS holdouts after this: info-vault files (IGridFsVaultFileService), photograph preview store (#718).
Next slice of epic #413, following the #771 profile-images recipe. Passports and travel documents are encrypted client-of-storage-side by SecureDocumentStorageService (IEncryptionService envelope + ISensitiveDataAuditService audit trail on every access) and the CIPHERTEXT lands in Mongo GridFS bucket `sensitive-documents`. Per the epic, blobs belong in MinIO — and this slice is low-risk precisely because MinIO only ever holds ciphertext; the encryption envelope and audit logging move over untouched.
Plan (hard cutover, #771 pattern):
1. Extract the raw byte-store behind SecureDocumentStorageService into a small ISensitiveBlobStore seam (GridFS impl = local-dev fallback, S3 impl = prod via the shared SpikerSoft.Storage registration, bucket `sensitive-documents`, key = existing GridFS id so no Mongo document rewrites). Encryption/audit stay in the single service — no duplication.
2. MinIO bucket + api-svc rw grant (live + provision-minio-svc-users.sh parity, infra PR).
3. One-shot migration tool with per-object SHA-256 read-back verification (ciphertext copied verbatim), idempotent.
4. Tests: seam unit tests both impls; all existing suites stay green.
5. After deploy + live verification: drop GridFS `sensitive-documents.files/.chunks` (operator go-ahead, mongodump archive first — note archive contains ciphertext only).
Remaining GridFS holdouts after this: info-vault files (IGridFsVaultFileService), photograph preview store (#718).
Implementation up: spikersoft-backend PR #443 + spikersoft-infrastructure PR #135. Ops already executed: bucket sensitive-documents created, api-svc rw granted+verified, 2/2 encrypted envelopes migrated from GridFS with SHA-256 read-back verification. After #443 merges+deploys: spot-check a travel-doc/passport view in the UI, then archive (mongodump) + drop GridFS sensitive-documents.files/.chunks — will hold the drop for operator go-ahead as with #771.
Implementation up: spikersoft-backend PR #443 + spikersoft-infrastructure PR #135. Ops already executed: bucket sensitive-documents created, api-svc rw granted+verified, 2/2 encrypted envelopes migrated from GridFS with SHA-256 read-back verification. After #443 merges+deploys: spot-check a travel-doc/passport view in the UI, then archive (mongodump) + drop GridFS sensitive-documents.files/.chunks — will hold the drop for operator go-ahead as with #771.
Deployed (after a manual digest re-apply — the CI deploy silently rolled back on a transient pull failure, filed separately as #774). App started clean on the S3 sensitive-documents path; profile-image serving re-verified. GridFS sensitive-documents.* pre-archived to ~/backups/gridfs-sensitive-documents-20260721. Remaining: UI spot-check of a passport/travel-doc view, then operator go-ahead to drop the two GridFS collections.
Deployed (after a manual digest re-apply — the CI deploy silently rolled back on a transient pull failure, filed separately as #774). App started clean on the S3 sensitive-documents path; profile-image serving re-verified. GridFS sensitive-documents.* pre-archived to ~/backups/gridfs-sensitive-documents-20260721. Remaining: UI spot-check of a passport/travel-doc view, then operator go-ahead to drop the two GridFS collections.
Operator verified a passport loads through the MinIO path in the UI. GridFS sensitive-documents.files/.chunks dropped (0 remaining; mongodump archive at ~/backups/gridfs-sensitive-documents-20260721 on the 4090 — ciphertext only). MinIO is now the SOLE store for sensitive documents. Slice complete — remaining epic-#413 GridFS holdouts: info-vault files (IGridFsVaultFileService) and the photograph preview store (#718). Closing.
Operator verified a passport loads through the MinIO path in the UI. GridFS sensitive-documents.files/.chunks dropped (0 remaining; mongodump archive at ~/backups/gridfs-sensitive-documents-20260721 on the 4090 — ciphertext only). MinIO is now the SOLE store for sensitive documents. Slice complete — remaining epic-#413 GridFS holdouts: info-vault files (IGridFsVaultFileService) and the photograph preview store (#718). Closing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Next slice of epic #413, following the #771 profile-images recipe. Passports and travel documents are encrypted client-of-storage-side by SecureDocumentStorageService (IEncryptionService envelope + ISensitiveDataAuditService audit trail on every access) and the CIPHERTEXT lands in Mongo GridFS bucket
sensitive-documents. Per the epic, blobs belong in MinIO — and this slice is low-risk precisely because MinIO only ever holds ciphertext; the encryption envelope and audit logging move over untouched.Plan (hard cutover, #771 pattern):
sensitive-documents, key = existing GridFS id so no Mongo document rewrites). Encryption/audit stay in the single service — no duplication.sensitive-documents.files/.chunks(operator go-ahead, mongodump archive first — note archive contains ciphertext only).Remaining GridFS holdouts after this: info-vault files (IGridFsVaultFileService), photograph preview store (#718).
Implementation up: spikersoft-backend PR #443 + spikersoft-infrastructure PR #135. Ops already executed: bucket sensitive-documents created, api-svc rw granted+verified, 2/2 encrypted envelopes migrated from GridFS with SHA-256 read-back verification. After #443 merges+deploys: spot-check a travel-doc/passport view in the UI, then archive (mongodump) + drop GridFS sensitive-documents.files/.chunks — will hold the drop for operator go-ahead as with #771.
Deployed (after a manual digest re-apply — the CI deploy silently rolled back on a transient pull failure, filed separately as #774). App started clean on the S3 sensitive-documents path; profile-image serving re-verified. GridFS sensitive-documents.* pre-archived to ~/backups/gridfs-sensitive-documents-20260721. Remaining: UI spot-check of a passport/travel-doc view, then operator go-ahead to drop the two GridFS collections.
Operator verified a passport loads through the MinIO path in the UI. GridFS sensitive-documents.files/.chunks dropped (0 remaining; mongodump archive at ~/backups/gridfs-sensitive-documents-20260721 on the 4090 — ciphertext only). MinIO is now the SOLE store for sensitive documents. Slice complete — remaining epic-#413 GridFS holdouts: info-vault files (IGridFsVaultFileService) and the photograph preview store (#718). Closing.