feat/attachment-rehosting #13
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/attachment-rehosting"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Réhébergement des images du contenu archivé
Ferme le constat de sécurité « contenu archivé actif au niveau réseau » : le
content_htmlstocké ne contient plus aucune URL distante — les pixels desuivi et les GET aveugles vers des services internes depuis le navigateur du
lecteur sont éliminés, sans amputer le contenu archivé.
Ce que fait cette PR
ExtractDocumenttélécharge chaque imagedu contenu extrait via le client SSRF-safe existant (
PublicOnlyResolver,garde IP littérale par hop, budget de redirections), la stocke dans le bucket
privé sous
sources/{sid}/attachments/{aid}, et réécrit le HTML vers/api/documents/{id}/attachments/{aid}. Toute image en échec est remplacéepar son texte
alt; un garde-fou (contains_remote_image) rend fatal toutrésidu d'URL distante.
.svget blocs<svg>inline(extraits avant Ammonia, qui les supprimait) passent par
svg-hush; servisavec
nosniff+ CSPdefault-src 'none'en défense en profondeur.document_attachmentssous RLS : « lisible ⇔ le document estlisible » (l'
EXISTStraversedocuments_select), cycle de vie par triggertombstone + drain + sweep étendu, boot guards du serveur mis à jour en
symétrie.
GET /api/documents/{id}/attachments/{attachment_id}:404 indistinct (inexistant/refusé),
Cache-Control: private, immutable,bucket 100 % privé. Zéro changement frontend (URLs relatives same-origin).
d'une URL ne déstage plus immédiatement l'ancien snapshot ; un flag
force_refetchdéclenche le fetch, et l'ancienne version (snapshot, contenu,attachments) n'est remplacée/tombstonée qu'au commit de la nouvelle. Un
recrawl sur un site devenu 404 laisse l'archive intacte.
ExtractDocumentpasse enDetached(trouvé en revue finale) : leréseau ne pinne plus la transaction du job ; les écritures
attachments + contenu commitent atomiquement dans une transaction courte
dédiée.
Limites et configuration
INDARA_ATTACHMENT_MAX_BYTES(10 Mio/image),INDARA_ATTACHMENT_MAX_PER_DOC(50),
INDARA_ATTACHMENT_FETCH_TIMEOUT_SECS(15) ; allowlist MIME fixe(png, jpeg, gif, webp, avif, svg+xml).
Validation
cargo test --workspace,clippy -D warnings, fmt.zéro-URL-distante vérifié en base, endpoint 200-avec-cookie / 401-sans avec
les bons headers, recrawl réussi → remplacement + tombstones drainées de S3,
recrawl échoué → archive intacte.
trouvé et corrigé, cf. ci-dessus).
Spec :
docs/superpowers/specs/2026-07-18-attachment-rehosting-design.md·Plan :
docs/superpowers/plans/2026-07-18-attachment-rehosting.mdSuivis post-merge notés en revue : qualifier
document_iddans la policy RLS,test du cap streamé de
fetch_image, tests nested-svg/commentaires,document_iddans les warns par image, cap par image pour les SVG inline,lock_durationexplicite sur la queue Pipeline.