Diferença entre IAM User e IAM Role na AWS: Quando Usar Cada Um

Se você já tentou configurar uma aplicação rodando em EC2 para acessar o S3 e ficou em dúvida entre criar um IAM User com chaves de acesso ou anexar uma IAM Role, você não está sozinho — essa é uma das confusões mais comuns em ambientes AWS e a escolha errada deixa credenciais estáticas expostas em código ou variáveis de ambiente por meses sem ninguém perceber.

TL;DR: IAM User vs IAM Role

CaracterísticaIAM UserIAM Role
IdentidadePessoa ou sistema fixoIdentidade assumível temporariamente
CredenciaisAccess Key + Secret (estáticas)Credenciais temporárias via STS
RotaçãoManual, propensa a esquecimentoAutomática (gerenciada pela AWS)
Uso em EC2Não recomendadoRecomendado (Instance Profile)
MFASuportadoSuportado (ao assumir a role)
AuditoriaPor usuárioPor sessão de role (com contexto)

Como IAM User e IAM Role Funcionam na Prática

Um IAM User representa uma identidade permanente dentro da conta AWS. Ele possui credenciais de longo prazo: um Access Key ID e um Secret Access Key. Essas chaves não expiram automaticamente — você as cria, distribui e é responsável por rotacioná-las. Quando uma aplicação usa um IAM User, ela carrega essas chaves em algum lugar: variável de ambiente, arquivo de configuração, parâmetro do sistema. O problema não é técnico, é operacional: chaves estáticas vazam.

Uma IAM Role funciona de forma diferente. Ela não pertence a uma pessoa nem a um sistema fixo — é uma identidade que pode ser assumida por entidades confiáveis (serviços AWS, usuários, contas externas). Quando um serviço como EC2 assume uma role, o AWS STS (Security Token Service) emite credenciais temporárias com prazo de expiração. A instância nunca armazena chaves permanentes; as credenciais são renovadas automaticamente pelo serviço de metadados da instância.

Pense no IAM User como uma chave física de escritório: você a entrega para alguém e ela continua funcionando até alguém lembrar de desativá-la. A IAM Role é mais como um crachá de visitante com validade de horas — expira sozinho, sem intervenção humana.
graph LR subgraph UserModel ["IAM User — Credenciais Estáticas"] U["IAM User"] -->|"Access Key + Secret"| APP1["Aplicação"] APP1 -->|"Chave armazenada no sistema"| API1["AWS API"] end subgraph RoleModel ["IAM Role — Credenciais Temporárias"] ROLE["IAM Role"] -->|"Política de Confiança"| EC2["EC2 Instance"] EC2 -->|"Solicita credenciais"| IMDS["IMDS 169.254.169.254"] IMDS -->|"Token temporário (exp. ~1h)"| APP2["Aplicação"] APP2 -->|"Assina requisição"| API2["AWS API"] end style UserModel fill:#fff3cd,stroke:#856404 style RoleModel fill:#d4edda,stroke:#155724
  1. IAM User: possui credenciais estáticas (Access Key + Secret) armazenadas fora da AWS e usadas diretamente nas chamadas de API.
  2. IAM Role: define permissões e uma política de confiança. Quando assumida por EC2, o STS emite credenciais temporárias acessíveis via IMDS (Instance Metadata Service).
  3. Instance Profile: é o contêiner que vincula uma IAM Role a uma instância EC2. Sem ele, a EC2 não consegue assumir a role.
  4. Renovação automática: o SDK da AWS e o AWS CLI consultam o IMDS automaticamente e renovam as credenciais antes da expiração, sem código adicional.

Por Que IAM Role é a Escolha Certa para EC2 Acessar S3

Aplicações em EC2 que usam IAM User precisam que as chaves estejam disponíveis em tempo de execução. Na prática, isso significa variáveis de ambiente, arquivos ~/.aws/credentials na instância, ou — o pior cenário — chaves hardcoded no código. Qualquer dessas abordagens cria um vetor de exposição: um dump de memória, um log mal configurado, ou um repositório Git público é suficiente para comprometer a conta.

Com IAM Role anexada via Instance Profile, a instância obtém credenciais temporárias do endpoint de metadados (http://169.254.169.254/latest/meta-data/iam/security-credentials/). O AWS SDK faz isso automaticamente — você não precisa escrever nenhum código de autenticação. As credenciais expiram em até uma hora e são renovadas antes disso pelo próprio serviço. Não há chave para vazar porque não há chave permanente.

Credenciais temporárias também aparecem no CloudTrail com o contexto da sessão, incluindo o nome da role e o ID da instância. Isso torna a auditoria muito mais rastreável do que chaves de IAM User compartilhadas entre múltiplas instâncias.

Configurando IAM Role para EC2 Acessar S3: Passo a Passo

Passo 1: Criar a IAM Role com política de confiança para EC2

A política de confiança define quem pode assumir a role. Para EC2, o principal é o serviço ec2.amazonaws.com. Isso impede que outros serviços ou usuários assumam essa role acidentalmente.

# Criar o arquivo de política de confiança
cat > trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

# Criar a role
aws iam create-role \
  --role-name EC2S3ReadRole \
  --assume-role-policy-document file://trust-policy.json \
  --description 'Role para EC2 acessar S3 com leitura'

Passo 2: Criar e anexar a política de permissões S3

Aplique o princípio do menor privilégio: conceda apenas as ações necessárias no bucket específico. Evite usar s3:* ou Resource: "*" em produção — isso expande o raio de impacto em caso de comprometimento da instância.

# Criar política de permissões S3 com escopo mínimo
cat > s3-read-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::meu-bucket-producao",
        "arn:aws:s3:::meu-bucket-producao/*"
      ]
    }
  ]
}
EOF

# Criar a política gerenciada
aws iam create-policy \
  --policy-name EC2S3ReadPolicy \
  --policy-document file://s3-read-policy.json

# Anexar a política à role (substitua 123456789012 pelo seu Account ID)
aws iam attach-role-policy \
  --role-name EC2S3ReadRole \
  --policy-arn arn:aws:iam::123456789012:policy/EC2S3ReadPolicy

Passo 3: Criar o Instance Profile e associar a Role

O Instance Profile é o objeto que a EC2 usa para carregar a role. É um contêiner separado da role em si — um detalhe que o console da AWS oculta ao criar automaticamente um Instance Profile com o mesmo nome da role, mas que a CLI exige explicitamente. Sem esse passo, a role existe mas a instância não consegue assumi-la.

# Criar o Instance Profile
aws iam create-instance-profile \
  --instance-profile-name EC2S3ReadProfile

# Adicionar a role ao Instance Profile
aws iam add-role-to-instance-profile \
  --instance-profile-name EC2S3ReadProfile \
  --role-name EC2S3ReadRole

Passo 4: Associar o Instance Profile à instância EC2

Se a instância já existe, use associate-iam-instance-profile. Para instâncias novas, especifique o Instance Profile no momento do lançamento via --iam-instance-profile. A associação pode levar alguns segundos para propagar — se o primeiro acesso falhar imediatamente após a associação, aguarde e tente novamente antes de investigar permissões.

# Associar a uma instância EC2 já existente
aws ec2 associate-iam-instance-profile \
  --instance-id i-0abcdef1234567890 \
  --iam-instance-profile Name=EC2S3ReadProfile

# Verificar a associação
aws ec2 describe-iam-instance-profile-associations \
  --filters Name=instance-id,Values=i-0abcdef1234567890

Passo 5: Verificar se as credenciais estão disponíveis na instância

Antes de testar a aplicação, confirme que o IMDS está entregando credenciais corretamente. Esse diagnóstico elimina a camada de infraestrutura como causa de falhas — se as credenciais chegam aqui, o problema está nas permissões da policy, não na configuração da role ou do Instance Profile.

# Dentro da instância EC2, via SSH:

# Passo 1: Obter o nome da role associada à instância
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

# O comando acima retorna o nome da role, por exemplo: EC2S3ReadRole
# Use esse nome exato no comando abaixo:

# Passo 2: Obter as credenciais temporárias da role
# IMPORTANTE: o caminho da URL deve conter o nome da role retornado pelo comando anterior
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2S3ReadRole

A resposta deve conter um JSON com AccessKeyId, SecretAccessKey, Token e Expiration. Se o endpoint retornar 404 ou um corpo vazio, verifique se o Instance Profile está corretamente associado à instância e se o IMDSv2 está configurado — nesse caso, o curl simples não funciona e é necessário obter um token de sessão primeiro.

🔽 Verificação com IMDSv2 (quando IMDSv1 está desabilitado)
# Obter token de sessão IMDSv2
TOKEN=$(curl -s -X PUT 'http://169.254.169.254/latest/api/token' \
  -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600')

# Obter nome da role
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

# Obter credenciais (substitua EC2S3ReadRole pelo nome retornado acima)
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/EC2S3ReadRole

Passo 6: Testar o acesso ao S3 via AWS CLI na instância

Com as credenciais confirmadas no IMDS, o AWS CLI usa automaticamente a role sem nenhuma configuração adicional. Se esse comando falhar com AccessDenied mas o passo anterior retornou credenciais válidas, o problema está na política de permissões — revise as actions e resources da policy anexada à role.

# Listar objetos no bucket (sem configurar credenciais manualmente)
aws s3 ls s3://meu-bucket-producao/

# Verificar qual identidade está sendo usada
aws sts get-caller-identity
sequenceDiagram participant App as Aplicação (EC2) participant SDK as AWS SDK participant IMDS as IMDS (169.254.169.254) participant STS as AWS STS participant S3 as Amazon S3 App->>SDK: s3.getObject(bucket, key) SDK->>IMDS: GET /iam/security-credentials/EC2S3ReadRole IMDS-->>SDK: AccessKeyId + SecretAccessKey + Token + Expiration SDK->>S3: GET s3://bucket/key (assinado com credenciais temporárias) S3->>STS: Valida token e permissões STS-->>S3: Autorizado S3-->>App: Objeto retornado Note over SDK,IMDS: SDK renova automaticamente antes da expiração
  1. Aplicação na EC2 faz chamada ao SDK/CLI sem credenciais explícitas.
  2. SDK consulta o IMDS no endpoint 169.254.169.254 para obter credenciais temporárias.
  3. IMDS retorna AccessKeyId, SecretAccessKey e Token com prazo de expiração.
  4. SDK usa essas credenciais para assinar a requisição ao S3.
  5. S3 valida a assinatura e as permissões via IAM antes de retornar os dados.
  6. Antes da expiração, o SDK renova automaticamente as credenciais repetindo o ciclo.

Diagnóstico: O Erro Que Todo Mundo Comete na Primeira Vez

O cenário mais comum: você cria a IAM Role, cria o Instance Profile, associa à instância — e a aplicação ainda retorna NoCredentialProviders ou AccessDenied. O instinto é revisar a política de permissões. Geralmente está errado.

O que realmente aconteceu na maioria dos casos que vi: o Instance Profile foi criado mas a role não foi adicionada a ele. São dois objetos distintos na API do IAM. O console da AWS mascara isso criando ambos com o mesmo nome automaticamente, mas via CLI ou CloudFormation é um passo separado que é fácil de pular. A associação entre Instance Profile e Role é feita com add-role-to-instance-profile — sem isso, o Instance Profile existe mas está vazio.

Verifique com:

aws iam get-instance-profile \
  --instance-profile-name EC2S3ReadProfile

Se o array Roles na resposta estiver vazio, essa é a causa. Execute o add-role-to-instance-profile do Passo 3 e aguarde a propagação.

Outro caso: a instância foi lançada sem Instance Profile e você tentou associar depois. A associação funciona para instâncias em execução via associate-iam-instance-profile, mas pode levar alguns minutos para as credenciais aparecerem no IMDS. Testar imediatamente após a associação pode gerar falsos negativos.

Quando Ainda Faz Sentido Usar IAM User

IAM User tem casos de uso legítimos. Acesso humano ao console da AWS é o principal — usuários reais precisam de identidades permanentes com MFA. Sistemas externos que não rodam em infraestrutura AWS (pipelines CI/CD em servidores on-premises, ferramentas de terceiros sem suporte a roles) também podem precisar de IAM Users com chaves de acesso.

Mesmo nesses casos, aplique controles compensatórios: rotação periódica de chaves com aws iam create-access-key e aws iam delete-access-key, política de senha forte, MFA obrigatório, e monitoramento via AWS Config para detectar chaves inativas. Para pipelines CI/CD em plataformas como GitHub Actions ou GitLab CI, avalie primeiro o suporte a OIDC — ambas as plataformas permitem assumir IAM Roles diretamente sem criar IAM Users.

Diferença entre IAM User e IAM Role: Resumo de Quando Usar Cada Um

CenárioRecomendaçãoMotivo
Aplicação em EC2 acessando S3, DynamoDB, etc.IAM Role (Instance Profile)Credenciais temporárias, sem gestão manual
Função Lambda acessando outros serviçosIAM Role (Execution Role)Mesmo modelo, gerenciado pelo serviço
Acesso humano ao console AWSIAM User com MFAIdentidade permanente necessária
CI/CD em GitHub Actions / GitLab CIIAM Role via OIDCSem chaves estáticas, federação nativa
Sistema externo sem suporte a OIDCIAM User com rotação de chavesÚltimo recurso — aplique controles compensatórios
Cross-account accessIAM Role com política de confiançaModelo padrão para acesso entre contas

Próximos Passos e Recursos

Se você está migrando de IAM Users com chaves estáticas para IAM Roles em EC2, o caminho mais seguro é criar a role e o Instance Profile primeiro, associar à instância, validar o acesso via IMDS, e só então remover as variáveis de ambiente com as chaves antigas. Nunca remova as chaves antes de confirmar que a role está funcionando.

Glossário

TermoDefinição
IAM UserIdentidade permanente na conta AWS com credenciais de longo prazo (Access Key + Secret Key).
IAM RoleIdentidade assumível com permissões definidas; emite credenciais temporárias via STS quando assumida.
Instance ProfileContêiner IAM que vincula uma Role a uma instância EC2, permitindo que ela assuma a role.
IMDS (Instance Metadata Service)Endpoint interno (169.254.169.254) que fornece metadados e credenciais temporárias para instâncias EC2.
STS (Security Token Service)Serviço AWS que emite credenciais temporárias quando uma role é assumida.

Comentários

Postagens mais visitadas deste blog

EC2 SSH Connection Timeout: Quais Regras do Security Group Verificar

EC2 Sem Acesso à Internet em VPC Customizada: Como Configurar Internet Gateway e Route Table

S3 Access Denied: Por que 'Bloquear Acesso Público' impede seu objeto mesmo após torná-lo público