AWS Builder Center
Autorização de Granularidade Fina (FGA) em Escala: Implementando Policy-Based Access Control com Amazon Verified Permissions e Cedar

Autorização de Granularidade Fina (FGA) em Escala: Implementando Policy-Based Access Control com Amazon Verified Permissions e Cedar

O artigo problematiza o colapso do RBAC em cenários complexos e estrutura a adoção do PBAC utilizando a linguagem matemática Cedar e o Amazon Verified Permissions. Direcionado a arquitetos de segurança e engenheiros seniores, o material orienta a construção de motores de decisão centralizados e a imposição (enforcement) na borda da nuvem através de Lambda Authorizers no Amazon API Gateway, garantindo isolamento total da camada de domínio hexagonal.

Systems Architect na NTT DATA, Estudante Doutorado na MUST University, 12x AWS e ASD & ADHD
Sistemas corporativos modernos colapsam sob o peso do Controle de Acesso Baseado em Funções (RBAC) quando as regras de negócios exigem autorização contextual. Quando a segurança exige que um usuário edite um documento financeiro apenas se for o proprietário e o recurso estiver em um estado de revisão específico, o RBAC tradicional falha miseravelmente. Equipes de engenharia injetam essas restrições diretamente no núcleo da aplicação, criando um emaranhado de código não auditável que resulta em escalonamento acidental de privilégios e violações de conformidade irrecuperáveis. A externalização completa das regras de acesso através do Policy-Based Access Control (PBAC) utilizando o Amazon Verified Permissions resolve este antipadrão arquitetônico. Ao adotar a linguagem Cedar para modelar políticas de forma rigorosa e avaliar decisões na borda da infraestrutura com o Amazon API Gateway, os arquitetos isolam o domínio de negócios da lógica de segurança. Esta topologia garante auditorias criptograficamente seguras, latência de autorização em milissegundos e um modelo de governança unificado para aplicações distribuídas na nuvem AWS.

Pré-requisitos

A implementação do PBAC exige domínio sobre modelagem de identidade e segurança de interfaces de programação. O provisionamento da infraestrutura necessita do Terraform versão 1.7.0 ou superior, utilizando o provedor HashiCorp AWS versão 5.40.0. A camada de computação de borda e os adaptadores hexagonais exigem o Python 3.12, a biblioteca boto3 versão 1.34.0 e o aws-lambda-powertools versão 2.34.0 para injeção de contexto estruturado. É imperativo possuir conhecimento fundamental sobre a sintaxe da linguagem Cedar e possuir privilégios administrativos no AWS IAM para provisionar repositórios de políticas (Policy Stores) e delegar permissões de avaliação em tempo de execução.

Passo a Passo

Desacoplamento Matemático com Repositórios de Políticas (Cedar)

O isolamento da autorização começa com a modelagem do domínio de segurança fora do código da aplicação, instanciando um Policy Store no Amazon Verified Permissions. A justificativa arquitetônica baseia-se no princípio da separação de interesses. O código Python não deve armazenar as regras societárias de quem pode acessar qual recurso. Provisionamos um esquema fortemente tipado que define as entidades principais (Principals), os recursos (Resources) e as ações (Actions). Em seguida, injetamos políticas escritas na linguagem Cedar. O Cedar foi projetado utilizando raciocínio automatizado, permitindo que as políticas sejam verificadas matematicamente contra contradições. A configuração abaixo ilustra o provisionamento de uma regra PBAC onde a ação de visualização é permitida exclusivamente se o atributo de departamento do usuário coincidir estritamente com a classificação de confidencialidade do documento.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
resource "aws_verifiedpermissions_policy_store" "enterprise_store" {
validation_settings {
mode = "STRICT"
}
}

resource "aws_verifiedpermissions_schema" "document_schema" {
policy_store_id = aws_verifiedpermissions_policy_store.enterprise_store.id
definition {
cedar_json = jsonencode({
"entityTypes": {
"User": {
"shape": { "type": "Record", "attributes": { "department": { "type": "String" } } }
},
"Document": {
"shape": { "type": "Record", "attributes": { "classification": { "type": "String" } } }
}
},
"actions": {
"Action::\"view\"": { "appliesTo": { "principalTypes": ["User"], "resourceTypes": ["Document"] } }
}
})
}
}

resource "aws_verifiedpermissions_policy" "department_access" {
policy_store_id = aws_verifiedpermissions_policy_store.enterprise_store.id
definition {
static {
description = "Autoriza o acesso apenas se o departamento coincidir com a classificacao do recurso"
statement = "permit (principal, action == Action::\"view\", resource) when { principal.department == resource.classification };"
}
}
}
Se as regras operacionais estão agora governadas por um motor de inferência centralizado e completamente fora do ciclo de vida do software, de que maneira interceptamos as requisições na exata borda da rede antes que cargas maliciosas atinjam a infraestrutura de backend?

Imposição de Fronteira com Lambda Authorizers

Interceptamos o tráfego não confiável acoplando um Lambda Authorizer diretamente ao Amazon API Gateway. O autorizador atua como o ponto de imposição (Enforcement Point) intransponível da arquitetura de segurança. Ao receber a requisição HTTP, a função extrai a identidade do cliente e invoca a API IsAuthorized do Amazon Verified Permissions. A decisão técnica de processar a chamada de autorização nesta camada reside na mitigação ostensiva de ataques volumétricos e chamadas não autorizadas. Se a requisição carece de privilégios para o recurso exato, o API Gateway descarta o pacote no nível de roteamento, preservando a concorrência computacional da camada interna. O motor Cedar avalia os atributos do usuário submetidos contra os atributos do recurso alvo, respondendo com um veredito binário inviolável.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import os
import boto3
from typing import Dict, Any
from aws_lambda_powertools import Logger

logger = Logger(service="EdgeAuthorizer")
avp_client = boto3.client('verifiedpermissions')
POLICY_STORE_ID = os.getenv('POLICY_STORE_ID')

def evaluate_access(user_id: str, department: str, document_id: str, doc_classification: str) -> bool:
response = avp_client.is_authorized(
policyStoreId=POLICY_STORE_ID,
principal={'entityType': 'User', 'entityId': user_id},
action={'actionType': 'Action', 'actionId': 'view'},
resource={'entityType': 'Document', 'entityId': document_id},
entities={
'entityList': [
{
'identifier': {'entityType': 'User', 'entityId': user_id},
'attributes': {'department': {'string': department}}
},
{
'identifier': {'entityType': 'Document', 'entityId': document_id},
'attributes': {'classification': {'string': doc_classification}}
}
]
}
)
return response.get('decision') == 'ALLOW'

@logger.inject_lambda_context
def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
# Extração de identidade simulada (em produção, validada via JWT)
user_id = event.get("requestContext", {}).get("authorizer", {}).get("claims", {}).get("sub", "anon")
document_id = event.get("pathParameters", {}).get("doc_id", "")

# O metadado do documento pode ser injetado via cache rápido de borda
is_allowed = evaluate_access(user_id, "FINANCE", document_id, "FINANCE")

return {
"principalId": user_id,
"policyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Action": "execute-api:Invoke",
"Effect": "Allow" if is_allowed else "Deny",
"Resource": event["methodArn"]
}]
},
"context": {
"tenant_id": "enterprise-alpha",
"pbac_validation": "SUCCESS"
}
}
Uma vez que o roteador de borda confirma a autorização e encaminha a requisição para os serviços internos, como as camadas de negócios hexagonais atestam a validade da chamada sem recalcular políticas no motor Cedar e sem confiar em cabeçalhos de rede adulteráveis?

Propagação Segura de Contexto e Coesão de Domínio

As camadas de negócios asseguram a validade extraindo o contexto criptograficamente protegido inserido pelo API Gateway diretamente no bloco de invocação interno. O adaptador hexagonal primário da aplicação intercepta o objeto requestContext.authorizer. Este invólucro lógico contém as chaves que a função de borda validou no passo anterior. O fundamento técnico garante que entidades externas são incapazes de forjar esse injetor de contexto. O adaptador higieniza esses dados contextuais vitais e os materializa em um objeto de Comando de Domínio Python puro. O serviço de domínio interno executa a alteração de dados focando-se estritamente na regra corporativa, alheio aos mecanismos de verificação. Essa orquestração blinda o núcleo computacional, assegurando que instâncias unitárias de teste funcionem isoladamente em ambientes locais sem necessitar de integração remota com serviços de autorização.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import json
from dataclasses import dataclass
from typing import Dict, Any
from aws_lambda_powertools import Logger

logger = Logger(service="DocumentDomain")

@dataclass(frozen=True)
class DocumentRequestCommand:
user_id: str
document_id: str
tenant_id: str

class DocumentDomainService:
def fetch_document(self, command: DocumentRequestCommand) -> Dict[str, str]:
logger.info(f"Identidade {command.user_id} consultando {command.document_id} no escopo {command.tenant_id}")
# Acesso direto a dados assumindo validação prévia absoluta
return {"content": "Base de conhecimento restrita.", "id": command.document_id}

domain_service = DocumentDomainService()

@logger.inject_lambda_context
def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
authorizer_context = event.get("requestContext", {}).get("authorizer", {})

command = DocumentRequestCommand(
user_id=authorizer_context.get("principalId", "unauthenticated"),
document_id=event.get("pathParameters", {}).get("doc_id", ""),
tenant_id=authorizer_context.get("tenant_id", "default")
)

result = domain_service.fetch_document(command)

return {
"statusCode": 200,
"body": json.dumps(result)
}

Solução de Problemas Comuns

O obstáculo primordial na implantação do Amazon Verified Permissions manifesta-se através de falhas silenciosas na avaliação, onde a API IsAuthorized retorna persistente e indefinidamente DENY sem disparar exceções no log de execução. Isso indica inequivocamente uma assimetria de tipos (Type Mismatch) entre os atributos injetados via Python e a estrutura estrita do Schema no Terraform. O Cedar opera com verificação de tipo rígida; se o esquema determina que a classificação do documento seja um String e a aplicação omitir este dicionário ou tentar passar um tipo numérico, a engine de avaliação recusará a transação por incompletude. Inspecione ativamente a matriz determiningMatch na resposta da API para rastrear a ausência da variável exata.
Um segundo gargalo crítico surge na governança do cache do API Gateway. Se o Cache TTL (Time to Live) do Lambda Authorizer for configurado para janelas extensas e um administrador revogar permissões no Verified Permissions simultaneamente, o usuário mal-intencionado manterá acesso irrestrito até a degradação temporal do cache. Em infraestruturas corporativas requerendo revogação instantânea em caso de desligamento de funcionários, ajuste o TTL do autorizador para o valor exato de zero, abdicando deliberadamente do cache em favor do isolamento temporal absoluto de acesso.

Conclusão

A migração de lógicas condicionais estáticas de segurança para o Policy-Based Access Control transforma a resiliência arquitetônica. Centralizar parâmetros matemáticos no Verified Permissions e executar as decisões de corte imediato através de componentes de borda assegura isolamento lógico e bloqueia escalonamentos transversais na arquitetura da nuvem. Como vetor de avanço, as equipes corporativas devem codificar repositórios Cedar diretamente em esteiras de integração e implantação contínuas, executando suítes de regressão matemática sobre políticas antes da aplicação em produção. Em transições operacionais focadas em neutralidade de provedor, essa padronização semântica traduz-se de maneira contígua para ecossistemas Open Source como o OpenFGA baseados no modelo Zanzibar, homogeneizando governança em arquiteturas distribuídas multicloud.

Referências

Evans, E. (2003). Domain-driven design: Tackling complexity in the heart of software. Addison-Wesley Professional.
Gilman, E., & Barth, D. (2017). Zero trust networks: Building secure systems in untrusted networks. O'Reilly Media.
Amazon Web Services. (2024). Cedar policy language reference guide. AWS Documentation. https://docs.aws.amazon.com/cedar/latest/guide/what-is-cedar.html 
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article