DEV Community

Rogério Fontes
Rogério Fontes

Posted on

Segurança na AWS Inicia com como criar identidade: IAM, além de usuários e roles.

Se pensamos em segurança na nuvem, é comum começarmos falando sobre firewalls, criptografia, redes privadas, WAF ou ferramentas de detecção de ameaças.

Mas precisamos pensar algo antes de praticamente todas essas tecnologias:

  • Quem pode fazer o quê dentro do meu ambiente AWS? Pode parecer um questionamento básico, mas sempre está no centro das decisões de segurança em cloud e não só.

Respondendo a esse questionamento, entra o AWS Identity and Access Management (IAM).

Neste artigo, pretendo ir além da explicação tradicional de usuários, grupos e roles. A ideia é olhar para IAM do ponto de vista de arquitetura e entender como conceitos como least privilege, roles, policies, permission boundaries e temporary credentials ajudam a construir workloads mais seguros na AWS.

1. Segurança geralmente começa com identidade.

Vamos pensar em uma aplicação relativamente simples:

A primeira pergunta de segurança poderia ser:

  • Como bloquear que alguém, por meio da internet, acesse diretamente o DynamoDB?

Outra pergunta:

  • Por que a aplicação precisa ter acesso ao DynamoDB?

E mais uma que poderíamos fazer:

  • Exatamente quais operações essa aplicação precisa executar no DynamoDB?

Ela precisa de:

  • GetItem
  • PutItem
  • UpdateItem

Ou realmente precisa de:

  • dynamodb:* ?

Essa pequena diferença representa um dos princípios mais importantes de segurança:

  • Menor Privilégio (Least Privilege)

Uma identidade deve possuir somente as permissões necessárias para realizar sua função.

  • Nada mais que isso.

2. O problema do (*), quando faz uma policy.

Durante o desenvolvimento e a criação de provas de conceito, é muito tentador criar algo assim:
{
  "Effect": "Allow",
  "Action": "",
  "Resource": "
"
}

Isso funciona normalmente, e esse é justamente o "problema".

Quando damos permissão total para resolver rapidamente um problema de acesso, podemos estar criando uma dívida de segurança.

Em um ambiente real, uma aplicação que precisa apenas escrever mensagens em uma fila não deveria ter permissão para excluir filas, criar recursos ou acessar outros serviços.

Podemos começar restringindo:
{
  "Effect": "Allow",
  "Action": [
     "sqs:SendMessage"
  ],
     "Resource": "arn:aws:sqs:REGION:ACCOUNT_ID:orders-events"
}

Agora estamos dizendo algo muito mais específico:
Esta identidade pode enviar mensagens para esta fila.
Essa mudança representa uma evolução importante:

3. IAM não é apenas Users.

Quando começamos a estudar AWS, normalmente conhecemos uma estrutura parecida com:

  • Isso é útil para aprender os conceitos.

Mas arquiteturas modernas na AWS deveriam depender cada vez menos de credenciais permanentes associadas diretamente a aplicações.

Considere uma aplicação Java executando no ECS.

Uma abordagem problemática seria armazenar:
aws.accessKeyId=...
aws.secretAccessKey=...

Agora temos vários problemas.

  • Onde armazenamos essas credenciais?
  • Quem pode vê-las?
  • Como fazemos rotação?
  • O que acontece se forem expostas?

4. Prefira credenciais temporárias.

Uma alternativa muito melhor é permitir que o workload assuma uma IAM Role.

Por exemplo:


A aplicação não precisa conhecer uma Access Key fixa.

O ambiente AWS fornece credenciais temporárias associadas à role.

Isso reduz significativamente o risco relacionado ao gerenciamento de credenciais de longa duração.
Para quem trabalha com Java e Spring Boot, isso também muda a forma como pensamos configuração.

Em vez de perguntar:

  • Onde vou colocar minha AWS_ACCESS_KEY_ID?

A pergunta deveria ser:

  • Qual identidade este workload deve assumir e quais permissões essa identidade realmente precisa?

Essa é uma pergunta de arquitetura, que sempre podemos fazer.

5. Políticas (Policies) são contratos de autorização.

Podemos pensar que IAM Policy seria como um contrato de autorização.

Ela responde principalmente:

Em uma policy encontramos elementos como:

  • Effect
  • Action
  • Resource
  • Condition

Por exemplo:
{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::my-secure-bucket/*"
}

A identidade não ganhou "acesso ao S3".

Ela ganhou permissão para:

  • Executar GetObject nos objetos daquele bucket específico.

Essa diferença de interpretação é fundamental.

6. Identity-based e Resource-based policies

Outro conceito importante é entender onde a autorização está definida.

Uma identity-based policy está associada a uma identidade:

Já alguns serviços permitem políticas associadas diretamente ao recurso.
Por exemplo:

Isso permite construir modelos de autorização mais sofisticados.

O S3 é um exemplo clássico, mas outros serviços AWS também possuem resource-based policies.

Como criadores de arquitetura, precisamos entender não apenas:

  • Qual policy devo criar?

Um pensamento melhor seria:

  • Onde essa decisão de autorização deveria existir?

7. Permission Boundaries

Agora chegamos a um conceito muito interessante quando começamos a trabalhar com ambientes maiores.

Imagine que uma organização permita que desenvolvedores criem suas próprias IAM Roles.

  • Isso oferece autonomia.
  • Mas também cria um risco.

O desenvolvedor poderia criar:

Uma Permission Boundary permite estabelecer um limite máximo de permissões que aquela identidade poderá receber.

Podemos pensar assim:

A policy pode solicitar determinadas permissões, mas a boundary estabelece até onde elas podem chegar.

Isso é especialmente interessante em ambientes onde queremos combinar:
- Autonomia + governança.

8. RBAC e ABAC

Outro ponto importante de arquiteturas maiores é decidir como as permissões serão organizadas.

Uma abordagem tradicional é o:

RBAC — Role-Based Access Control

Permissões baseadas em funções.

Por exemplo:

  • Developer
  • SecurityEngineer
  • DatabaseAdministrator
  • Auditor

Mas, conforme o ambiente cresce, administrar centenas de combinações de roles e policies pode se tornar complicado.

É aí que entra:

ABAC — Attribute-Based Access Control

No ABAC, podemos tomar decisões utilizando atributos, frequentemente representados por tags.

Por exemplo:

  • Project = Payments
  • Environment = Production
  • Team = Security

Isso permite criar modelos de autorização mais dinâmicos.
Imagine uma regra conceitual:

  • Desenvolvedores podem acessar recursos quando a tag Project do recurso corresponde ao projeto associado à identidade.

Agora o modelo pode escalar sem precisarmos criar uma policy diferente para cada novo projeto.

9. IAM é arquitetura.

Esse talvez seja o principal ponto deste artigo.
IAM não deveria ser algo configurado depois que a arquitetura está pronta.

Ele faz parte da arquitetura.
Quando desenhamos:

Deveríamos também desenhar:

Assim começamos a tratar identidade como parte do design do sistema.

10. Um exercício prático

Considere uma aplicação de pedidos.

Ela precisa:

  1. Criar pedidos no DynamoDB.
  2. Publicar um evento em uma fila SQS.
  3. Ler configurações.
  4. Registrar logs.   Antes de criar qualquer policy, responda:

DynamoDB
Ele precisa acessar todas as tabelas?

  • Provavelmente não.

SQS
Ela precisa administrar a fila?

  • Provavelmente não.

Talvez apenas:

  • sqs:SendMessage
  • IAM

A aplicação precisa criar usuários ou roles?

  • Não.

Credenciais
Precisamos armazenar Access Key e Secret Key?

  • Se o workload está corretamente integrado com IAM Roles, provavelmente não.   O resultado começa a parecer:  Isso é least privilege aplicado à arquitetura.

11. O que eu evitaria

Algumas práticas deveriam levantar imediatamente um alerta:
Evite roles com muitos privilégios:

  • AdministratorAccess, para aplicações. Cuidado, sempre lembre-se do privilégio mínimo.

Evite políticas (policies) com (*):

  • Action: *
  • Resource: *

    Evite usá-la sem justificativa comprovada.

Evite usar Access Keys armazenadas no código.

  • Crie credenciais comitadas no Git (vamos fazer como em um próximo artigo).
  • Usar um Vault, como SecretManager para as credenciais.

Evite uma única IAM Role compartilhada por vários workloads.
Evite permissões adicionadas continuamente sem revisão.

IAM não deveria ser tratado como uma barreira que precisamos remover para fazer a aplicação funcionar. Ele é justamente um dos mecanismos que impedem que uma falha em um componente comprometa todo o ambiente.

Conclusão

Segurança na AWS não começa no firewall.

Ela começa respondendo corretamente:

  • Quem pode fazer o quê, em qual recurso e sob quais condições?

IAM Users, Roles e Policies são apenas as ferramentas.

Os princípios por trás delas são mais importantes:

  • Menor privilégio (Least privilege);
  • Credenciais temporárias;
  • Separação de responsabilidades;
  • Autorização explícita;
  • Redução do blast radius;
  • Governança.

Para um arquiteto ou mesmo quem está pensando em arquiteturas com segurança primeiro (Security first), portanto, IAM não deveria ser apenas um serviço AWS.

  • IAM é uma decisão arquitetural.

E essa será justamente a abordagem desta série: não apenas explicar serviços de segurança da AWS, mas entender como eles participam da construção de arquiteturas seguras.

No próximo artigo, vamos aprofundar esse problema:

  • Designing Least-Privilege Access on AWS

Vamos sair da teoria e construir uma arquitetura real utilizando IAM Roles, Policies e Permission Boundaries, mostrando também alguns erros que podem resultar em privilege escalation.

AWS Security Architecture in Practice — #01
Uma série sobre arquitetura, segurança e construção de workloads seguros na AWS.

Top comments (0)