Skip to main content

URLs pré-signées

Les fichiers sont stockés sur Cloudflare R2 (compatible S3). Les fichiers publics (logos, photos profil) sont servis directement via CDN. Les fichiers privés (CV, KYC) nécessitent une URL pré-signée temporaire.

Architecture

Flow complet

Buckets

BucketVisibilitéContenu
wethehive-publicPublicLogos entreprise, photos profil, bannières, images blog
wethehive-privatePrivé (presign)CV, documents KYC, justificatifs

Durées de validité

TypeTTL URL signée
Download CV15 min
Download KYC admin15 min
Upload direct-to-R2 (rare)5 min
Les URLs pré-signées ne sont jamais cachées côté client. À chaque besoin d’accès, le client doit redemander une nouvelle URL.

Règles d’accès aux CV privés

Format de réponse

Deux modes :

Mode JSON (recommandé)

GET /v1/api/files/cv/17 HTTP/1.1
Accept: application/json
{
  "url": "https://r2.wethehivers.com/wethehive-private/cv/17.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=...",
  "expiresAt": "2026-04-18T14:15:00Z",
  "fileName": "cv-jean-ngassa.pdf",
  "fileSize": 324512,
  "mimeType": "application/pdf"
}

Mode redirect (compat navigateur)

GET /v1/api/files/cv/17 HTTP/1.1
Accept: */*
HTTP/1.1 302 Found
Location: https://r2.wethehivers.com/wethehive-private/cv/17.pdf?X-Amz-Signature=...

Upload direct depuis le navigateur

Pour éviter de faire transiter les octets par le backend, un flow d’upload direct-to-R2 est disponible :

Révocation

Les URLs pré-signées R2 ne peuvent être révoquées avant expiration que par deux moyens :
  1. Rotation de la paire R2_ACCESS_KEY / R2_SECRET_KEY (invalide TOUTES les signatures actives)
  2. Suppression du fichier sous-jacent

Scan anti-virus

Tout fichier uploadé passe par ClamAV avant d’être exposé :

Quotas de stockage

RôleQuotaAction si dépassé
CANDIDAT50 Mo total (CV + photo)413 Payload Too Large
RECRUTEUR100 Mo (logo + staff photos + bannières)413
ADMINIllimité

CORS R2

AllowedOrigins: https://wethehivers.com, https://recruteur.wethehivers.com, https://admin.wethehivers.com
AllowedMethods: GET, PUT
AllowedHeaders: Content-Type, Content-Length, Authorization
MaxAgeSeconds: 3600