Se você está construindo uma API para um produto digital, especialmente em uma startup, um dos pontos mais críticos é garantir a segurança desde o primeiro deploy. A pressa por entregar MVPs muitas vezes leva a soluções improvisadas de autenticação e autorização, que futuramente viram dívidas técnicas caras.
Com base nas soluções que implementei ao longo dos anos em ambientes Java e cloud (especialmente com Quarkus e AWS), compartilho aqui um guia direto com boas práticas para proteger APIs REST utilizando OAuth2, OpenID Connect e AWS Cognito.
1. Conceitos que você precisa entender primeiro
- Autenticação (Authentication): verificar se o usuário é quem diz ser (ex: login).
 - Autorização (Authorization): verificar se esse usuário tem permissão para acessar certo recurso.
 - OAuth2: protocolo para autorização segura, usado por APIs modernas.
 - OpenID Connect: camada de identidade em cima do OAuth2 (inclui login e perfis).
 - JWT: token compactado com as informações do usuário (e do sistema) usado para validar requisições.
 
2. Por que usar Cognito em Startups?
AWS Cognito é um serviço gerenciado de identidade da AWS. Ele resolve autenticação de forma escalável e segura, com:
- Cadastro/login de usuários
 - Recuperação de senha
 - Validação por e-mail/SMS
 - Suporte a login com Google, Facebook, Apple
 - Integração nativa com API Gateway, Lambda e IAM
 
Ideal para startups que não querem reimplementar do zero.
3. Estrutura de segurança recomendada
- Criar um User Pool no Cognito (base de usuários)
 - Criar um App Client com o fluxo de autenticação que deseja (ex: Authorization Code ou Password)
 - Configurar o backend (Quarkus, Spring etc.) para validar os tokens JWT emitidos
 - Definir roles (admin, user, viewer) e usar nos tokens
 - Proteger os endpoints por escopo ou grupo
 
4. Configurando a API Java com JWT do Cognito
Exemplo com Quarkus:
mp.jwt.verify.publickey.location=https://cognito-idp.sa-east-1.amazonaws.com/<pool-id>/.well-known/jwks.json mp.jwt.verify.issuer=https://cognito-idp.sa-east-1.amazonaws.com/<pool-id> quarkus.oidc.tenant-enabled=true
No código, você pode extrair as informações do token:
@Inject
SecurityIdentity identity;
String email = identity.getPrincipal().getName();
String companyId = identity.getAttribute("custom:company_id");
5. Protegendo endpoints por Role e Escopo
Com base nas claims do JWT, é possível proteger endpoints de forma simples.
Exemplo:
@RolesAllowed("admin")
@GET
@Path("/usuarios")
public List<Usuario> listarUsuarios() {
    // apenas admins acessam
}
Ou, usando escopos OAuth:
@Authenticated
@GET
@Path("/dados")
@AccessToken(
  requiredScopes = {"dados:leitura"}
)
6. Lidando com tenants (multiempresa)
Se seu sistema é multiempresa (multitenant), inclua o company_id no JWT.
- Configure uma Lambda de Pre Token Generation no Cognito para enriquecer o token com atributos do banco
 - Valide esse 
company_idno backend e associe o acesso aos dados corretos 
Exemplo:
String tenantId = identity.getAttribute("custom:company_id");
repository.findByTenantId(tenantId);
7. Cuidados e boas práticas
- Nunca confie em tokens sem validação (sempre use assinatura + expiração)
 - Use HTTPS sempre
 - Mantenha o tempo de expiração dos tokens curto (ex: 15min)
 - Atualize o 
JWKperiodicamente se fizer cache - Use refresh tokens com controle de revogação
 - Sempre audite acessos sensíveis com 
user_id,ip,timestamp 
Conclusão
Implementar segurança em APIs não precisa ser um monstro. Com OAuth2, OpenID e Cognito você cobre as principais frentes: login, escopo, roles, expiração, auditabilidade e escalabilidade.
Se você está construindo uma API em Java para um produto digital, comece com essas boas práticas e evite dores no futuro. Se quiser conversar mais sobre arquitetura segura para startups, me chama!
