Stockage de fichiers
Buckets publics ou privés, RLS PostgreSQL, URLs signées temporaires, transformations d'images à la volée. Stockage objets européen, CDN edge inclus Pro+.
Stockage de fichiers par projet
Le service de stockage du Pool C offre buckets publics ou privés, politiques d'accès basées sur RLS PostgreSQL, URLs signées pour les accès temporaires, et transformations d'images à la volée. Stockage physique sur objets compatibles S3, hébergement européen.
Quand l'utiliser — quand non
Idéal pour
- Avatars utilisateurs, images de profil
- PDF, documents, exports
- Médias d'application (photos, vidéos courtes)
- Uploads directs depuis le browser via URL signée
Pas adapté
- Backups volumineux récurrents (préférer un bucket S3 dédié)
- Streaming vidéo HD (préférer un CDN vidéo)
- Fichiers > 50 GB (cf. limites par plan)
Endpoints Storage
POST /storage/v1/bucket Créer un bucket GET /storage/v1/bucket Lister les buckets GET /storage/v1/bucket/:name Détails d'un bucket DELETE /storage/v1/bucket/:name Supprimer un bucket POST /storage/v1/object/:bucket/:path Uploader un fichier GET /storage/v1/object/public/:bucket/:path Télécharger (bucket public) GET /storage/v1/object/authenticated/:b/:p Télécharger (avec auth) DELETE /storage/v1/object/:bucket/:path Supprimer POST /storage/v1/object/sign/:bucket/:path Générer une URL signée GET /storage/v1/render/image/:bucket/:path Transformation image
Gestion des buckets
# Bucket privé (accès contrôlé par RLS)
curl -L -X POST "https://wzfbhd.runtime.di2amp.com/storage/v1/bucket" \
-H "apikey: $SERVICE_ROLE_KEY" -H "Authorization: Bearer $SERVICE_ROLE_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "documents",
"public": false,
"allowedMimeTypes": ["application/pdf","image/jpeg","image/png","image/webp"],
"fileSizeLimit": 10485760
}'
# Bucket public (accès anonyme aux fichiers)
curl -L -X POST "https://wzfbhd.runtime.di2amp.com/storage/v1/bucket" \
-H "apikey: $SERVICE_ROLE_KEY" -H "Authorization: Bearer $SERVICE_ROLE_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"avatars","public":true,"fileSizeLimit":2097152}'
Upload de fichiers
# Upload binaire direct curl -L -X POST "https://wzfbhd.runtime.di2amp.com/storage/v1/object/avatars/alice/photo.jpg" \ -H "apikey: $ANON_KEY" -H "Authorization: Bearer $USER_TOKEN" \ -H "Content-Type: image/jpeg" \ --data-binary @photo.jpg # URL publique générée https://wzfbhd.runtime.di2amp.com/storage/v1/object/public/avatars/alice/photo.jpg
URL signées (accès temporaire)
Permettent d'accorder un accès temporaire à un fichier d'un bucket privé, sans authentification du destinataire. Signature HMAC-SHA256 avec le jwt_secret du projet.
# Générer une URL signée valide 1h
curl -L -X POST "https://wzfbhd.runtime.di2amp.com/storage/v1/object/sign/documents/reports/2026-mai.pdf" \
-H "apikey: $SERVICE_ROLE_KEY" -H "Authorization: Bearer $SERVICE_ROLE_KEY" \
-H "Content-Type: application/json" \
-d '{"expiresIn": 3600}'
# Réponse : { "signedURL": "/object/sign/documents/...?token=..." }
Upload direct browser (presigned)
Pour les fichiers volumineux, l'upload direct browser → storage évite de transiter par votre serveur. Le serveur génère l'URL signée d'upload, le client uploade en PUT.
Politiques RLS sur les fichiers
-- Lecture publique d'un bucket
CREATE POLICY "public_read_avatars" ON storage.objects
FOR SELECT USING (bucket_id = 'avatars');
-- Chaque user peut uploader dans son propre dossier
CREATE POLICY "user_upload_own_folder" ON storage.objects
FOR INSERT WITH CHECK (
bucket_id = 'user-files' AND
(storage.foldername(name))[1] = auth.uid()::text
);
-- Chaque user peut lire ses propres fichiers
CREATE POLICY "user_read_own_files" ON storage.objects
FOR SELECT USING (
bucket_id = 'user-files' AND
(storage.foldername(name))[1] = auth.uid()::text
);
Transformations d'images
GET /storage/v1/render/image/public/avatars/alice/photo.jpg?
width=200&height=200&resize=cover&format=webp&quality=80
| Paramètre | Valeurs |
|---|---|
| width / height | entiers en px |
| resize | cover, contain, fill |
| format | webp, jpeg, png, avif |
| quality | 1 à 100 |
Images transformées mises en cache au CDN edge — une transformation identique sur la même image n'est calculée qu'une fois.
Limites par plan
| Plan | Stockage inclus | Taille max fichier | CDN |
|---|---|---|---|
| Free | 1 GB | 50 MB | Non |
| Pro | 100 GB | 5 GB | Oui |
| Business | 1 TB | 50 GB | Oui |
| Entreprise | illimité | illimité | Oui |
Sécurité et isolation
Chaque projet possède ses propres buckets — aucun croisement possible. RLS PostgreSQL en première ligne sur la table storage.objects. URLs signées avec expiration courte recommandée pour les contenus sensibles.
Pour aller plus loin
- Authentification utilisateurs
- RLS PostgreSQL — explication détaillée
- Validation upload via fonction serverless
Tarification associée
Stockage inclus jusqu'au quota du plan, transferts CDN inclus Pro+. Au-delà : facturation à l'usage. Voir tarifs.