Controle de acesso granular em aplicações B2C com Amazon Cognito e Amazon Verified Permissions

Por que autenticação e autorização precisam andar juntas

Aplicações web modernas precisam responder duas perguntas fundamentais de segurança: quem é você? e o que você pode fazer? Implementar esses controles corretamente é um dos maiores desafios para equipes de desenvolvimento — especialmente quando se trabalha com frameworks orientados a dados como o Streamlit (um framework Python de código aberto para criação de aplicações web interativas) ou quando a aplicação exige controles de acesso muito granulares.

A AWS publicou um guia técnico mostrando como combinar o Amazon Cognito e o Amazon Verified Permissions com políticas Cedar para resolver exatamente esse problema — entregando segurança de nível empresarial com esforço de desenvolvimento reduzido.

Visão geral da arquitetura de segurança

A arquitetura de referência proposta segue um design de segurança em camadas com quatro componentes principais, cada um com responsabilidade bem definida:

  • Camada de autenticação: O Amazon Cognito cuida da verificação de identidade do usuário com validação segura de credenciais e Tokens Web JSON (JWT — JSON Web Tokens). Inclui políticas de senha integradas, proteção contra bloqueio de conta e gerenciamento de sessão.
  • Camada de autorização: O Verified Permissions usa o motor de políticas Cedar para avaliar requisições de acesso granulares com base em políticas armazenadas centralmente.
  • Camada de aplicação: O frontend em Streamlit integra ambos os serviços, gerenciando sessões de usuário e aplicando os controles de acesso na interface.
  • Fronteiras de segurança: Múltiplas camadas de controle protegem contra acesso não autorizado, escalada de privilégios, falhas de autenticação e validação de entradas.

Essa separação de responsabilidades permite que autenticação e autorização funcionem como controles complementares, seguindo os princípios de defesa em profundidade.

Como o fluxo de trabalho funciona na prática

O fluxo completo de autenticação e autorização envolve três camadas trabalhando em sequência:

  • O usuário envia uma requisição de login pelo Streamlit
  • A requisição é autenticada pelo Amazon Cognito
  • Um token de acesso é retornado ao Streamlit
  • Uma requisição de autorização é enviada ao Verified Permissions
  • O motor de políticas Cedar avalia a requisição
  • Uma decisão é retornada pelo motor de políticas
  • A instrução de permitir ou negar é enviada de volta ao Streamlit
  • Se a instrução for de permissão, o acesso é concedido

Entendendo a autorização com Cedar

Enquanto a autenticação estabelece a identidade do usuário, a autorização determina quais ações ele pode executar. O Verified Permissions oferece um serviço de autorização escalável baseado no Cedar, uma linguagem de políticas projetada especificamente para controle de acesso granular.

As políticas Cedar seguem um formato estruturado que define quem pode executar quais ações em quais recursos. Os componentes de uma política são:

  • Efeito: permit ou forbid — define se a política permite ou nega o acesso
  • Principal: A entidade (usuário) que faz a requisição, representada por ?principal como variável
  • Action: A operação sendo executada, com escopo no namespace da aplicação
  • Resource: O alvo da ação, também representado como variável
  • Condições: A cláusula when contém expressões lógicas que precisam ser verdadeiras

Padrões avançados de políticas Cedar

O artigo original descreve padrões de políticas Cedar amplamente utilizados para implementar autorização granular com o Amazon Verified Permissions. Os exemplos ilustram como modelar propriedade de recursos, acesso baseado em papéis, permissões hierárquicas e controles administrativos.

Controle de propriedade de recurso

Este padrão garante que usuários só acessem recursos que lhes pertencem. No exemplo acadêmico apresentado, um estudante só pode visualizar suas próprias notas:

permit(
  principal == ?principal,
  action == application::Action::"ViewGrade",
  resource == ?resource
)
when {
  principal has role == "Student" &&
  resource.student == principal.entityId
};

A política verifica se o usuário tem o papel de Student e confirma que o atributo student do recurso corresponde ao entityId do estudante — impedindo que um aluno acesse as notas de outro.

Acesso baseado em papel e tipo de recurso

Este padrão concede acesso com base no papel do usuário e no tipo do recurso. No exemplo, um professor só pode editar cursos que ele mesmo leciona:

permit(
  principal == ?principal,
  action == application::Action::"EditCourse",
  resource == ?resource
)
when {
  principal has role == "Faculty" &&
  resource has resourceType == "Course" &&
  resource.instructor == principal.entityId
};

Autorização hierárquica

Este padrão permite que chefes de departamento gerenciem professores dentro do seu departamento:

permit(
  principal == ?principal,
  action == application::Action::"ManageFaculty",
  resource == ?resource
)
when {
  principal has role == "DepartmentHead" &&
  resource has role == "Faculty" &&
  resource.department == principal.department
};

Acesso administrativo de emergência

Este padrão fornece acesso emergencial com justificativa obrigatória:

permit(
  principal == ?principal,
  action == ?action,
  resource == ?resource
)
when {
  principal has role == "Administrator" &&
  context has emergencyAccess == true &&
  context has justification
};

A política exige que a flag de acesso emergencial esteja definida como true e que uma justificativa seja fornecida — garantindo rastreabilidade sem bloquear operações críticas. Vale destacar que isso não é uma substituição automática: o contexto precisa ser explicitamente configurado.

Como o Cedar avalia as políticas

Entender o fluxo de avaliação de políticas ajuda a projetar sistemas de autorização mais eficazes. O processo segue estas etapas:

  • O usuário tenta acessar um recurso protegido
  • A aplicação envia uma requisição de autorização ao Verified Permissions
  • O Verified Permissions recupera as políticas Cedar aplicáveis do repositório de políticas
  • O motor Cedar avalia cada política contra a requisição
  • Se qualquer política forbid corresponder, o acesso é negado imediatamente
  • Se alguma política permit corresponder e nenhuma forbid corresponder, o acesso é permitido
  • Se nenhuma política corresponder, o acesso é negado por padrão
  • O resultado (ALLOW ou DENY) é retornado à aplicação

Um ponto importante: políticas forbid têm precedência sobre políticas permit. Se qualquer política de negação corresponder, o acesso é bloqueado independentemente das permissões existentes.

Aplicação prática: sistema acadêmico

O artigo usa um sistema acadêmico como exemplo concreto, com diferentes papéis de usuário e suas permissões correspondentes:

  • Estudante: Visualiza apenas as próprias notas. A política verifica o papel e faz a correspondência entre o dono do recurso e o entityId do principal.
  • Professor (Faculty): Edita conteúdo de cursos que leciona e gerencia notas dos alunos nesses cursos.
  • Assistente de ensino (TA — Teaching Assistant): Gerencia notas dos cursos aos quais está vinculado, com acesso restrito aos cursos atribuídos.
  • Chefe de departamento (Department Head): Gerencia atribuições de professores dentro do seu departamento, com escopo hierárquico.
  • Administrador: Acesso amplo ao sistema com justificativa obrigatória, com todas as ações registradas e auditadas.

Dicas de otimização de políticas

O artigo traz duas recomendações práticas para melhorar a performance das avaliações:

  • Ordene as condições pela probabilidade de sucesso: Coloque as condições mais frequentemente verdadeiras primeiro na cláusula when para habilitar avaliação em curto-circuito. Por exemplo, verifique o papel antes da propriedade do recurso, pois incompatibilidades de papel são detectadas mais cedo. Veja as boas práticas do Cedar.
  • Use atributos indexados para buscas mais rápidas: Utilize atributos de entidade que o Verified Permissions indexa nativamente (entityId, role, tipo de recurso) como condições primárias. Consulte as boas práticas para design de modelo de autorização.

Pré-requisitos e como executar o exemplo

Para implementar o sistema acadêmico de exemplo, são necessários: uma conta AWS ativa, Python 3.8 ou superior, conhecimento básico de Streamlit e permissões de Gerenciamento de Identidade e Acesso da AWS (IAM — AWS Identity and Access Management) para o Amazon Cognito e o Verified Permissions.

Os passos para executar o ambiente de demonstração são:

  • Baixe o código-base: Acesse o repositório de exemplos avp-streamlit no GitHub.
  • Configure o ambiente de desenvolvimento: Instale o SDK da AWS para Python (boto3) e configure suas credenciais AWS.
    pip install boto3

    Faça login na sua conta AWS:

    aws login --region $REGION

    Verifique se a Interface de Linha de Comando da AWS (AWS CLI), o Python e as dependências estão corretamente configurados:

    ./verify-setup.sh
  • Crie os recursos AWS: Use o Console de Gerenciamento da AWS ou ferramentas de Infraestrutura como Código (IaC — Infrastructure as Code) para provisionar o user pool do Amazon Cognito e o repositório de políticas do Verified Permissions.
    ./deploy-demo-environment.sh
    Do you want to start the demo now? (Y/N): Y

    Esse script provisiona o user pool do Amazon Cognito, o repositório de políticas do Verified Permissions e os recursos de amostra necessários para a demonstração.

  • Demonstração e encerramento: Interaja com a demo e teste as políticas e funcionalidades. Quando quiser sair, pressione Ctrl+C para encerrar.

Boas práticas de segurança

O artigo reúne um conjunto de recomendações para quem for implementar essa arquitetura:

  • Aplique controles em camadas: Use autenticação e autorização como controles complementares, nunca dependa de um único mecanismo.
  • Siga o princípio do menor privilégio: Conceda apenas as permissões necessárias para cada papel. Comece com permissões mínimas e adicione conforme necessário.
  • Implemente gerenciamento adequado de sessão: Configure expiração e renovação de tokens com base nos requisitos de segurança da aplicação. O Amazon Cognito lida com grande parte disso automaticamente.
  • Valide todas as entradas: Sanitize entradas do usuário para prevenir ataques de injeção. Não confie apenas na validação do lado do cliente.
  • Monitore eventos de autenticação: Configure logging com AWS CloudTrail e alarmes no Amazon CloudWatch para atividades suspeitas, como tentativas repetidas de login ou padrões de acesso incomuns.
  • Faça revisões regulares de segurança: Audite periodicamente suas políticas e configurações para garantir que ainda atendem aos requisitos.
  • Implemente tratamento seguro de erros: Evite revelar detalhes internos do sistema nas mensagens de erro. Forneça feedback útil ao usuário sem expor informações que possam auxiliar atacantes.

Conclusão

A combinação de Amazon Cognito e Amazon Verified Permissions permite construir controles de segurança robustos sem a necessidade de código personalizado complexo. A arquitetura descrita pela AWS entrega autenticação de nível empresarial com esforço mínimo, políticas de autorização granulares centralizadas, escalabilidade conforme a base de usuários cresce e auditoria centralizada das políticas de segurança.

Para quem quiser se aprofundar, a AWS disponibiliza a documentação do Amazon Cognito e a documentação do Amazon Verified Permissions como recursos adicionais.

Fonte

Building secure B2C applications with fine-grained access control using Amazon Cognito and Amazon Verified Permissions (https://aws.amazon.com/blogs/security/building-secure-b2c-applications-with-fine-grained-access-control-using-amazon-cognito-and-amazon-verified-permissions/)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *