S3 Access Denied: Por que 'Bloquear Acesso Público' impede seu objeto mesmo após torná-lo público
Você fez upload de uma imagem no S3, marcou o objeto como público, copiou a URL e abriu no navegador — e recebeu um 403 Access Denied. A configuração de ACL do objeto está correta, mas o acesso público continua bloqueado. O culpado quase sempre é o Block Public Access no nível do bucket, uma camada de controle que opera acima das ACLs e políticas de objeto e que muita gente ignora até levar o primeiro 403 em produção.
TL;DR — S3 Access Denied com objeto público
| Camada | O que controla | O que verificar |
|---|---|---|
| Block Public Access (bucket) | Bloqueia ACLs e políticas públicas no bucket inteiro | aws s3api get-public-access-block --bucket NOME |
| ACL do objeto | Permissão pública no objeto individual | aws s3api get-object-acl --bucket NOME --key CHAVE |
| Bucket Policy | Permissões baseadas em política no bucket | aws s3api get-bucket-policy --bucket NOME |
| Object Ownership | Controla se ACLs são respeitadas ou ignoradas | aws s3api get-bucket-ownership-controls --bucket NOME |
Como o S3 Access Denied acontece — o modelo de autorização em camadas
O S3 não toma decisões de acesso em uma única verificação. Cada requisição passa por múltiplas camadas de avaliação em sequência. Se qualquer camada retornar um bloqueio explícito, a requisição é negada — independentemente do que as camadas subsequentes permitiriam. Entender essa ordem é o que separa um diagnóstico rápido de horas perdidas verificando a ACL errada.
GET objeto"] BPA{"Block Public Access
ativo?"} OWN{"Object Ownership
BucketOwnerEnforced?"} BP{"Bucket Policy
tem Deny explícito?"} ACL{"ACL do objeto
tem public-read?"} DENY["403 Access Denied"] ALLOW["200 OK"] REQ --> BPA BPA -- "Sim (qualquer flag)" --> DENY BPA -- "Não" --> OWN OWN -- "Sim (ACLs ignoradas)" --> BP OWN -- "Não" --> ACL ACL -- "Não" --> DENY ACL -- "Sim" --> BP BP -- "Deny explícito" --> DENY BP -- "Allow ou ausente" --> ALLOW
- Block Public Access é avaliado primeiro, antes de qualquer ACL ou política. Se qualquer uma das quatro flags estiver ativa, requisições anônimas são bloqueadas imediatamente.
- Object Ownership determina se ACLs de objeto têm efeito. Com o modo
BucketOwnerEnforced, todas as ACLs são desativadas — mesmo que você tenha definidopublic-readno objeto. - Bucket Policy pode conceder ou negar acesso público explicitamente via
s3:GetObjectpara o principal*. - ACL do objeto só é avaliada se Block Public Access permitir e Object Ownership não estiver em modo
BucketOwnerEnforced.
Pense no Block Public Access como um porteiro na entrada do prédio. Não importa se o inquilino (objeto) deixou a porta do apartamento aberta — se o porteiro não deixar entrar, ninguém chega lá.
Diagnóstico passo a passo do S3 Access Denied
Siga os passos na ordem. Cada passo cobre o que o anterior não consegue detectar.
Passo 1 — Verificar Block Public Access no bucket
Esta é a causa mais comum e deve ser a primeira verificação. As quatro flags do Block Public Access operam de forma independente, e basta uma delas estar ativa para bloquear o acesso público.
aws s3api get-public-access-block \
--bucket NOME-DO-BUCKET \
--region us-east-1
Saída esperada quando o acesso público está bloqueado:
{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}
Se qualquer flag estiver true e você precisa de acesso público, desative as flags relevantes:
aws s3api put-public-access-block \
--bucket NOME-DO-BUCKET \
--region us-east-1 \
--public-access-block-configuration \
"BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"
Atenção: Desativar o Block Public Access expõe o bucket a requisições anônimas. Avalie se o caso de uso realmente exige acesso público irrestrito ou se uma URL pré-assinada atende melhor.
Passo 2 — Verificar Object Ownership
Mesmo com Block Public Access desativado, se o bucket estiver no modo BucketOwnerEnforced, as ACLs de objeto são completamente ignoradas. Esse modo passou a ser o padrão para novos buckets criados após abril de 2023, o que quebra silenciosamente fluxos que dependiam de public-read via ACL.
aws s3api get-bucket-ownership-controls \
--bucket NOME-DO-BUCKET \
--region us-east-1
Se a resposta for BucketOwnerEnforced, ACLs não têm efeito. Nesse caso, use uma bucket policy para conceder acesso público em vez de ACL de objeto.
Passo 3 — Verificar a ACL do objeto
Se Object Ownership não estiver em modo BucketOwnerEnforced, verifique se a ACL do objeto realmente concede leitura pública. Definir o objeto como público via console nem sempre persiste se o Block Public Access estava ativo no momento do upload.
aws s3api get-object-acl \
--bucket NOME-DO-BUCKET \
--key caminho/para/objeto.jpg \
--region us-east-1
Procure por um grant com URI: http://acs.amazonaws.com/groups/global/AllUsers e permissão READ. Se não estiver presente, aplique a ACL:
aws s3api put-object-acl \
--bucket NOME-DO-BUCKET \
--key caminho/para/objeto.jpg \
--acl public-read \
--region us-east-1
Passo 4 — Verificar a Bucket Policy
Uma política de bucket com Deny explícito sobrepõe qualquer ACL ou permissão concedida. Verifique se existe alguma instrução negando s3:GetObject para o principal * ou para o objeto em questão.
aws s3api get-bucket-policy \
--bucket NOME-DO-BUCKET \
--region us-east-1 \
--query Policy \
--output text | python3 -m json.tool
Se quiser conceder acesso público via política (abordagem recomendada quando ACLs estão desativadas):
🔽 Clique para expandir — Bucket Policy para acesso público de leitura
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::NOME-DO-BUCKET/*"
}
]
}
Aplique com:
aws s3api put-bucket-policy \
--bucket NOME-DO-BUCKET \
--region us-east-1 \
--policy file://policy.json
Passo 5 — Confirmar acesso público com requisição anônima
Após ajustar as configurações, valide com uma requisição genuinamente anônima — sem credenciais AWS. O --no-sign-request simula exatamente o que um navegador faria ao acessar a URL pública.
aws s3api get-object \
--bucket NOME-DO-BUCKET \
--key caminho/para/objeto.jpg \
--no-sign-request \
/tmp/teste-objeto.jpg
Alternativamente, com curl direto na URL pública:
curl -I "https://NOME-DO-BUCKET.s3.us-east-1.amazonaws.com/caminho/para/objeto.jpg"
Um HTTP 200 confirma que o acesso público está funcionando. Um 403 persistente indica que ainda há uma camada bloqueando — volte ao Passo 1 e revise cada flag individualmente.
Block Public Access"] --> P2["Passo 2
Object Ownership"] P2 --> P3["Passo 3
ACL do objeto"] P3 --> P4["Passo 4
Bucket Policy"] P4 --> P5["Passo 5
Teste anônimo"] P5 --> OK["200 OK"] P1 -- "flags ativas" --> FIX1["put-public-access-block"] P2 -- "BucketOwnerEnforced" --> FIX2["usar Bucket Policy"] P3 -- "sem public-read" --> FIX3["put-object-acl"] P4 -- "Deny explícito" --> FIX4["revisar policy"] P5 -- "403 persiste" --> P1
Diagnóstico de experiência — o caso do BlockPublicPolicy silencioso
Um cenário recorrente: a equipe desativa BlockPublicAcls e IgnorePublicAcls, aplica a ACL public-read no objeto, e o acesso ainda falha com 403. Horas depois, alguém percebe que RestrictPublicBuckets ainda está true.
O diagnóstico errado inicial é focar na ACL do objeto — afinal, foi o que foi configurado. A ACL está correta. O problema é que RestrictPublicBuckets bloqueia o acesso de qualquer principal anônimo ao bucket, independentemente de ACLs ou políticas que concedam acesso. Ele opera no nível da requisição, não no nível da política.
Outro caso: a equipe tenta aplicar uma bucket policy pública, mas a chamada put-bucket-policy retorna AccessDenied imediatamente — sem aplicar a política. Isso acontece porque BlockPublicPolicy está ativo. Quando essa flag está true, o S3 rejeita qualquer tentativa de aplicar uma política que conceda acesso público, retornando erro na própria chamada de API. Não é um bloqueio silencioso — é uma falha explícita na operação de escrita da política.
A lição: as quatro flags do Block Public Access são independentes. Desativar uma não desativa as outras. Sempre verifique o estado completo da configuração com get-public-access-block antes de investigar ACLs.
Verificar Block Public Access no nível da conta
Existe uma camada adicional que opera acima do bucket: o Block Public Access no nível da conta AWS. Se estiver ativo, ele bloqueia o acesso público em todos os buckets da conta, independentemente das configurações individuais de cada bucket.
aws s3control get-public-access-block \
--account-id 123456789012 \
--region us-east-1
Se precisar desativar no nível da conta (faça isso com cautela — afeta todos os buckets):
aws s3control put-public-access-block \
--account-id 123456789012 \
--region us-east-1 \
--public-access-block-configuration \
"BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"
Política IAM para gerenciar Block Public Access
Para permitir que uma role ou usuário gerencie as configurações de Block Public Access tanto no nível de bucket quanto de conta:
🔽 Clique para expandir — Política IAM para gerenciar Block Public Access
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GerenciarBlockPublicAccessBucket",
"Effect": "Allow",
"Action": [
"s3:GetBucketPublicAccessBlock",
"s3:PutBucketPublicAccessBlock"
],
"Resource": "arn:aws:s3:::NOME-DO-BUCKET"
},
{
"Sid": "GerenciarBlockPublicAccessConta",
"Effect": "Allow",
"Action": [
"s3control:GetPublicAccessBlock",
"s3control:PutPublicAccessBlock"
],
"Resource": "*"
}
]
}
Alternativas ao acesso público irrestrito
Na maioria dos casos de uso — compartilhar uma imagem, permitir download temporário, servir assets para uma aplicação — o acesso público irrestrito não é necessário. URLs pré-assinadas oferecem acesso temporário e auditável sem expor o bucket publicamente:
aws s3 presign s3://NOME-DO-BUCKET/caminho/para/objeto.jpg \
--expires-in 3600 \
--region us-east-1
O comando retorna uma URL com credenciais temporárias embutidas, válida pelo tempo especificado em segundos. O bucket permanece privado.
Próximos passos e referências para S3 Access Denied
Se o 403 persistir após verificar todas as camadas acima, verifique também: SCPs (Service Control Policies) aplicadas à conta via AWS Organizations, VPC Endpoint Policies se o acesso for originado de dentro de uma VPC, e logs do S3 Server Access Logging ou AWS CloudTrail para identificar exatamente qual camada está retornando o bloqueio.
- AWS Docs — Blocking public access to your Amazon S3 storage
- AWS Docs — Controlling object ownership
- AWS Docs — Access control list (ACL) overview
Glossário
| Termo | Definição |
|---|---|
| Block Public Access | Conjunto de quatro flags no S3 que bloqueiam acesso público no nível de bucket ou conta, operando acima de ACLs e políticas. |
| ACL (Access Control List) | Mecanismo legado do S3 para conceder permissões em buckets e objetos individuais, incluindo a permissão public-read. |
| Object Ownership | Configuração de bucket que controla se ACLs de objeto têm efeito. No modo BucketOwnerEnforced, ACLs são desativadas. |
| Bucket Policy | Política baseada em recursos aplicada ao bucket, avaliada após Block Public Access e Object Ownership. |
| URL Pré-assinada | URL temporária com credenciais embutidas que permite acesso a um objeto S3 privado por um período determinado. |
Comentários
Postar um comentário