S3 Accès Public Refusé : Pourquoi 'Block Public Access' Bloque Votre Image Malgré les Permissions ACL
Vous venez d'uploader une image sur S3, vous avez coché 'public' sur l'objet, et pourtant l'URL retourne un Access Denied sec. C'est l'un des pièges les plus fréquents sur S3 — et la raison n'est pas dans les permissions de l'objet, mais dans un verrou au niveau du bucket que beaucoup d'ingénieurs oublient de vérifier en premier.
TL;DR — Résumé Rapide
| Couche | Paramètre | Effet si mal configuré |
|---|---|---|
| Compte AWS | Block Public Access (niveau compte) | Bloque tout accès public, toutes régions |
| Bucket | Block Public Access (niveau bucket) | Neutralise ACL et bucket policy publiques |
| Bucket | Bucket Policy | Sans s3:GetObject pour *, l'objet reste privé |
| Objet | ACL public-read | Ignorée si Block Public Access est actif |
Comment S3 Évalue les Accès Publics — Le Mécanisme Réel
S3 n'évalue pas les permissions dans l'ordre que la plupart des gens imaginent. Avant même de regarder l'ACL de l'objet ou la bucket policy, S3 vérifie les paramètres Block Public Access — d'abord au niveau du compte, ensuite au niveau du bucket. Si l'un de ces verrous est actif, la chaîne d'évaluation s'arrête là. L'ACL public-read que vous avez définie sur l'objet ne sera jamais consultée.
C'est comme mettre un badge d'accès sur votre bureau alors que le bâtiment entier est verrouillé de l'extérieur. Le badge existe, mais personne n'arrivera jamais jusqu'à lui.
Les quatre paramètres Block Public Access fonctionnent comme des filtres indépendants. Chacun peut bloquer une catégorie spécifique d'accès public :
- BlockPublicAcls — empêche la création de nouvelles ACL publiques et ignore les ACL publiques existantes lors de l'évaluation des accès.
- IgnorePublicAcls — ignore toutes les ACL publiques sur le bucket et ses objets, même si elles ont été créées avant l'activation de ce paramètre.
- BlockPublicPolicy — empêche la création ou la modification d'une bucket policy qui accorderait un accès public.
- RestrictPublicBuckets — restreint l'accès au bucket aux seuls principals AWS authentifiés et aux services AWS, même si une bucket policy publique existe.
Dans la grande majorité des cas de 'Access Denied' après un upload, c'est IgnorePublicAcls ou RestrictPublicBuckets qui est en cause — le premier neutralise l'ACL objet, le second bloque même une bucket policy correctement rédigée.
URL publique objet"] --> B{"Block Public Access
niveau COMPTE actif ?"} B -- Oui --> Z1["403 Access Denied"] B -- Non --> C{"Block Public Access
niveau BUCKET actif ?"} C -- Oui --> Z2["403 Access Denied"] C -- Non --> D{"Bucket Policy
s3:GetObject pour * ?"} D -- Oui --> OK1["200 OK"] D -- Non --> E{"IgnorePublicAcls
désactivé ?"} E -- Non --> Z3["403 Access Denied
ACL ignorée"] E -- Oui --> F{"ACL objet
public-read ?"} F -- Oui --> OK2["200 OK"] F -- Non --> Z4["403 Access Denied"]
- Requête HTTP GET — un navigateur ou client demande l'objet via son URL publique.
- Vérification Block Public Access (compte) — premier filtre, appliqué avant tout. Si actif, la réponse est immédiatement
403 Access Denied. - Vérification Block Public Access (bucket) — second filtre. Même logique, mais scoped au bucket.
- Évaluation Bucket Policy — si une policy
s3:GetObjectpourPrincipal: *existe et que les verrous précédents sont désactivés, l'accès est accordé. - Évaluation ACL objet — dernier recours. L'ACL
public-readest évaluée uniquement si IgnorePublicAcls est désactivé.
Diagnostic S3 Accès Public Refusé — Étape par Étape
Étape 1 — Vérifier Block Public Access au niveau du compte
C'est le verrou le plus haut dans la hiérarchie et le plus souvent oublié, parce qu'il est configuré dans les paramètres S3 globaux du compte, pas dans le bucket lui-même. Un seul paramètre actif ici bloque tous les buckets de toutes les régions du compte.
aws s3control get-public-access-block \
--account-id 123456789012 \
--region us-east-1
Si la réponse contient "BlockPublicAcls": true, "IgnorePublicAcls": true, "BlockPublicPolicy": true ou "RestrictPublicBuckets": true, vous avez trouvé votre coupable. Pour désactiver tous les verrous au niveau compte :
aws s3control put-public-access-block \
--account-id 123456789012 \
--public-access-block-configuration \
BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false \
--region us-east-1
Attention : désactiver ces paramètres au niveau compte expose potentiellement tous vos buckets. Évaluez si l'approche bucket policy (voir étape 3) n'est pas plus adaptée à votre cas.
Étape 2 — Vérifier Block Public Access au niveau du bucket
Même si le niveau compte est propre, chaque bucket possède ses propres paramètres Block Public Access. Ils s'appliquent en supplément — les deux niveaux doivent être désactivés pour qu'un accès public soit possible.
aws s3api get-public-access-block \
--bucket nom-de-votre-bucket
Pour désactiver les verrous sur le bucket spécifiquement :
aws s3api put-public-access-block \
--bucket nom-de-votre-bucket \
--public-access-block-configuration \
BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
Étape 3 — Appliquer une Bucket Policy pour l'accès public en lecture
Une fois les verrous désactivés, l'ACL public-read sur l'objet peut fonctionner — mais la pratique recommandée est d'utiliser une bucket policy plutôt que des ACL objet. Les ACL sont un mécanisme plus ancien, et AWS recommande de désactiver les ACL au profit des bucket policies pour un contrôle centralisé. Avec une bucket policy, vous n'avez pas besoin de définir les permissions objet par objet.
🔽 Bucket Policy — Accès public en lecture sur tous les objets
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::nom-de-votre-bucket/*"
}
]
}
Pour appliquer cette policy via CLI :
aws s3api put-bucket-policy \
--bucket nom-de-votre-bucket \
--policy file://bucket-policy.json
Si BlockPublicPolicy est encore actif au niveau bucket ou compte, cette commande échouera avec une erreur BlockPublicPolicy. Revenez à l'étape 1 ou 2 selon le cas.
Étape 4 — Vérifier l'ACL de l'objet si vous n'utilisez pas de bucket policy
Si vous préférez rester sur les ACL objet (cas d'usage spécifique, bucket avec Object Ownership configuré sur 'Bucket owner preferred' ou 'Object writer'), vérifiez que l'ACL est bien public-read et qu'IgnorePublicAcls est désactivé aux deux niveaux.
aws s3api get-object-acl \
--bucket nom-de-votre-bucket \
--key chemin/vers/votre-image.jpg
Pour définir l'ACL publique sur un objet existant :
aws s3api put-object-acl \
--bucket nom-de-votre-bucket \
--key chemin/vers/votre-image.jpg \
--acl public-read
Notez que si Object Ownership est configuré sur BucketOwnerEnforced (le défaut pour les nouveaux buckets depuis avril 2023), les ACL sont désactivées et cette commande retournera une erreur. Dans ce cas, seule la bucket policy fonctionne.
Étape 5 — Vérifier la configuration Object Ownership
C'est le détail que la plupart des guides oublient. Depuis avril 2023, AWS a modifié le comportement par défaut des nouveaux buckets S3 : Object Ownership est défini sur BucketOwnerEnforced par défaut, ce qui désactive complètement les ACL S3. Si votre bucket a été créé après cette date, l'ACL public-read n'a aucun effet — elle est silencieusement ignorée.
aws s3api get-bucket-ownership-controls \
--bucket nom-de-votre-bucket
Si la réponse indique "ObjectOwnership": "BucketOwnerEnforced", les ACL sont désactivées. Vous devez utiliser une bucket policy (étape 3). Si vous souhaitez réactiver les ACL (non recommandé pour les nouveaux projets) :
aws s3api put-bucket-ownership-controls \
--bucket nom-de-votre-bucket \
--ownership-controls Rules=[{ObjectOwnership=BucketOwnerPreferred}]
Le Piège Classique — Symptôme, Mauvais Diagnostic, Cause Réelle
Le scénario se répète régulièrement : un ingénieurs upload une image, clique sur 'Make public' dans la console S3, copie l'URL, et obtient un 403. Il vérifie l'ACL de l'objet — elle est bien public-read. Il vérifie la bucket policy — il n'y en a pas, mais l'ACL devrait suffire. Il relit la documentation des ACL. Tout semble correct.
Le mauvais diagnostic : un problème de propagation, ou un bug de la console. Certains vont même attendre quelques minutes en espérant que 'ça se propage'.
La cause réelle : IgnorePublicAcls était activé au niveau bucket. L'ACL public-read existait bien sur l'objet, mais S3 l'ignorait complètement lors de l'évaluation. La console affichait 'public' parce qu'elle lit l'ACL — elle ne simule pas l'évaluation complète incluant Block Public Access.
La correction prend 30 secondes une fois qu'on sait où regarder. Le diagnostic peut prendre une heure si on commence par l'objet plutôt que par le bucket.
ACL public-read"] --> B["Accès URL
→ 403 Access Denied"] B --> C["Mauvais diagnostic :
vérifier ACL objet"] C --> D["ACL = public-read
semble correct"] D --> E["Cause réelle :
IgnorePublicAcls actif"] E --> F["Désactiver Block Public Access
niveau bucket"] F --> G["Ou : créer Bucket Policy
s3:GetObject Principal *"] G --> H["200 OK"] F --> H
- Block Public Access compte actif → 403 immédiat, aucune autre vérification effectuée.
- Block Public Access bucket actif → 403, même si le niveau compte est propre.
- BucketOwnerEnforced → ACL ignorées, bucket policy requise.
- Bucket policy manquante + ACL ignorée → 403 même si l'objet a l'ACL
public-read. - Tous les verrous désactivés + bucket policy ou ACL valide → 200 OK.
IAM — Permissions Requises pour Modifier ces Paramètres
Pour exécuter les commandes de diagnostic et de correction ci-dessus, le principal IAM doit disposer des permissions suivantes. Appliquez le principe du moindre privilège — si vous n'avez besoin que de lire la configuration, retirez les actions Put.
🔽 Politique IAM minimale pour gérer Block Public Access et Bucket Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GererBlockPublicAccessBucket",
"Effect": "Allow",
"Action": [
"s3:GetBucketPublicAccessBlock",
"s3:PutBucketPublicAccessBlock",
"s3:GetBucketOwnershipControls",
"s3:PutBucketOwnershipControls",
"s3:GetBucketPolicy",
"s3:PutBucketPolicy",
"s3:GetObjectAcl",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::nom-de-votre-bucket",
"arn:aws:s3:::nom-de-votre-bucket/*"
]
},
{
"Sid": "GererBlockPublicAccessCompte",
"Effect": "Allow",
"Action": [
"s3:GetAccountPublicAccessBlock",
"s3:PutAccountPublicAccessBlock"
],
"Resource": "*"
}
]
}
Note : s3:GetAccountPublicAccessBlock et s3:PutAccountPublicAccessBlock opèrent via le service s3control et nécessitent "Resource": "*" — ces actions ne supportent pas la restriction par ARN de ressource spécifique.
Conclusion et Prochaines Étapes — S3 Accès Public
L'erreur 'S3 accès public refusé' malgré une ACL public-read sur l'objet est presque toujours causée par Block Public Access actif au niveau bucket ou compte, ou par Object Ownership configuré sur BucketOwnerEnforced. Commencez toujours le diagnostic par les couches les plus hautes — compte, puis bucket — avant d'inspecter l'objet lui-même.
Pour aller plus loin :
- Consultez la documentation officielle AWS sur Block Public Access pour les détails de chaque paramètre.
- Si vous gérez des assets statiques publics à grande échelle, envisagez Amazon CloudFront devant S3 avec une Origin Access Control (OAC) — le bucket reste privé, CloudFront gère l'accès public, et vous bénéficiez du CDN.
- Pour auditer les buckets publics de votre compte, utilisez AWS Config avec la règle managée
s3-bucket-public-read-prohibited.
Glossaire
| Terme | Définition |
|---|---|
| Block Public Access | Ensemble de quatre paramètres S3 qui neutralisent les ACL et bucket policies publiques, applicables au niveau compte ou bucket. |
| ACL S3 (Access Control List) | Mécanisme de contrôle d'accès au niveau objet ou bucket, hérité. Désactivé par défaut sur les nouveaux buckets depuis avril 2023. |
| Bucket Policy | Document JSON attaché au bucket définissant les permissions d'accès via le langage de politique IAM. Mécanisme recommandé pour l'accès public. |
| Object Ownership | Paramètre bucket contrôlant qui possède les objets uploadés et si les ACL sont activées. BucketOwnerEnforced désactive les ACL. |
| Principal: * | Dans une bucket policy, désigne tout utilisateur, authentifié ou non. Requis pour un accès véritablement public. |
Commentaires
Enregistrer un commentaire