PEP e PDP para Autorização Segura com Cognito

Este arquivo foi traduzido automaticamente por IA, erros podem ocorrer
Num dos meus posts anteriores Building a serverless connected BBQ as SaaS - Part 4 - AuthZ abordei o tópico sobre Autenticação e Autorização com PEPs distribuídos (Pontos de Aplicação de Política) e um PDP centralizado (Ponto de Decisão de Política). Neste post, vou aprofundar um pouco mais e expandir essa configuração. Explorarei como esses conceitos funcionam na prática, os benefícios que oferecem e como podemos aproveitá-los em nossa arquitetura serverless usando AWS Lambda, API Gateway e Cognito User Pools.
Além disso, falarei sobre o modelo de Controle de Acesso Baseado em Função (RBAC), como implementá-lo usando Grupos do Cognito e DynamoDB, e como o cache pode aumentar o desempenho do nosso sistema de autorização.
Toda a configuração, com instruções detalhadas de implantação e todo o código, pode ser encontrada em Serverless Handbook PEP e PDP
Vamos começar com um breve recapitulação.
Autenticação (AuthN) vs. Autorização (AuthZ)
É crucial distinguir entre Autenticação e Autorização, dois termos que muitas vezes são confundidos e que tive que explicar em muitas ocasiões, mas que servem propósitos muito diferentes.
Autenticação (AuthN)
A autenticação trata da verificação da identidade. Ela responde à pergunta, Quem é você? Quando um utilizador entra na nossa aplicação, a autenticação garante que ele é quem diz ser. Isso pode envolver algo tão simples quanto um nome de utilizador e senha ou uma autenticação multifator (MFA) mais complexa.
Autorização (AuthZ)
Após a identidade do utilizador ser autenticada, a autorização entra em ação. Este processo responde à pergunta, O que você pode fazer? A autorização determina quais recursos, dados e ações um utilizador está autorizado a acessar com base em suas funções e permissões.
O que são PEP e PDP?
Antes de mergulhar em como implementá-los na AWS, é essencial entender os papéis que PEP e PDP desempenham na autorização.
PEP (Ponto de Aplicação de Política)
Em termos simples, o PEP é o guardião. São os pontos em nosso sistema onde as decisões de controle de acesso são aplicadas. Quando um utilizador tenta acessar um recurso protegido, o PEP é o componente responsável por verificar se a solicitação é permitida ou negada com base nas permissões do utilizador.
No nosso caso, o Lambda Authorizer no API Gateway atua como o PEP. O Lambda Authorizer intercepta cada solicitação de API entrada, valida o token JWT (normalmente do Cognito User Pool ou qualquer provedor de identidade) e encaminha as informações do utilizador (claims) para o PDP para avaliação de autorização.
O PEP garante que o JWT é válido, verifica sua expiração, valida sua assinatura e verifica as claims (como aud, iss e sub). Em seguida, passa as claims para o PDP para uma decisão final sobre se o utilizador está autorizado a acessar o recurso solicitado.
PDP (Ponto de Decisão de Política)
O PDP é onde reside a lógica de autorização. Após o PEP verificar o JWT e garantir que o token é válido, o PDP determina se o utilizador está autorizado a acessar o recurso solicitado com base em suas funções, permissões ou políticas.
O PDP é uma implementação separada, um microservice separado. No nosso caso, uma função Lambda, que realiza a decisão de autorização real. Ele verifica as funções do utilizador, que são armazenadas na claim groups no JWT (do Cognito), e as compara com as permissões necessárias para acessar um recurso específico, armazenadas em um armazenamento de dados. No nosso caso, usaremos o DynamoDB.
O PDP valida se o utilizador tem as permissões necessárias (como Admin, User ou Manager) para acessar o recurso (por exemplo, GET /admin, POST /profile). O PDP também pode incorporar lógica de negócios adicional, como verificar o acesso com base no tempo ou geolocalização.
Benefícios de usar PEP e PDP na Autorização
Implementar PEP distribuído e PDP centralizado oferece vários benefícios, especialmente conforme nossas aplicações escalam.
Separação de Preocupações Ao separar as preocupações de aplicação (PEP) e decisão (PDP), obtemos código mais limpo e manutenível. O Lambda Authorizer (PEP) é focado puramente em validação e aplicação. Enquanto o PDP é dedicado à avaliação de políticas.
Redução de Latência: Ao colocar os PEPs próximos de onde as decisões precisam ser aplicadas, podemos reduzir a latência, com uma estratégia de cache isso pode ser reduzido ainda mais.
Gerenciamento: Com um PDP centralizado, toda a nossa lógica de autorização está centralizada em um único local. Isso torna mais fácil gerenciar e atualizar políticas conforme nossos requisitos evoluem. Seja modificando funções ou adicionando novos conjuntos de permissões, ter um PDP central reduz a sobrecarga de atualizar políticas em vários locais.
Consistência e Conformidade: Cada solicitação é avaliada contra o mesmo conjunto de políticas, garantindo uma tomada de decisão consistente em todo o nosso sistema.
Escalabilidade: Ambos os componentes PEP e PDP escalam independentemente com base na demanda. Se nosso sistema precisar lidar com um maior volume de solicitações, o API Gateway e o Lambda podem escalar automaticamente. Além disso, o PDP pode ser otimizado para desempenho implementando cache.
Flexibilidade: Um PDP permite adaptar o modelo de autorização às nossas necessidades. Se nossos requisitos mudarem (por exemplo, mudando para controle de acesso baseado em atributos (ABAC) ou introduzindo um sistema de permissões mais granular), podemos modificar facilmente o PDP para acomodar essas mudanças sem afetar outras partes do sistema.
Usando PEP e PDP na AWS com Arquitetura Serverless
Na AWS, a integração de PEP e PDP se encaixa perfeitamente com componentes serverless como Lambda e API Gateway.
PEP - Lambda Authorizer do API Gateway
Quando um cliente envia uma solicitação ao nosso endpoint do API Gateway, o Lambda Authorizer (PEP) intercepta a solicitação antes que ela chegue ao nosso serviço de backend. Nossa implementação realizará várias etapas-chave.
Validação de JWT: Ele decodifica o JWT, valida a assinatura e verifica se o token expirou.
Encaminhamento de Claims: Após verificar o token, o Lambda Authorizer encaminha as claims (como sub, groups e role) para o PDP para verificações adicionais de autorização. Na nossa solução, na verdade, encaminharemos o token JWT inteiro.
Para reduzir o número de chamadas ao nosso PEP e também ao PDP, podemos utilizar o cache de autorização que existe no API Gateway.
PDP - Função Lambda de lógica de autorização
O PDP é implementado como uma função Lambda separada, no nosso caso, e receberá o token JWT inteiro, ou as claims, para executar a lógica de autorização, que incluirá várias etapas.
- Verificar a função do utilizador (usando a claim
groupsdo Cognito). - Consultar uma tabela DynamoDB que contém mapeamentos de função para permissão (por exemplo, quais funções têm acesso a quais endpoints de API).
- Avalia se a função do utilizador corresponde às permissões necessárias para o recurso ou endpoint de API solicitado.
ID Token vs Access Token
À medida que implementamos o fluxo de trabalho PEP e PDP, é essencial entender a diferença entre ID Tokens e Access Tokens, pois ambos são frequentemente usados em fluxos de trabalho de autorização.
ID Token
O ID Token é usado principalmente para autenticação e contém informações sobre quem é o utilizador. Ele contém claims sobre a identidade do utilizador autenticado, como nome, email e phone_number.
Access Token
O Access Token é usado para conceder acesso ao utilizador a recursos protegidos, autorização. O Access Token contém informações sobre as permissões do utilizador, como a quais recursos ele tem permissão para acessar e os escopos que foram concedidos, que definem o que o utilizador pode fazer (por exemplo, read:profile, write:profile). O access token não inclui a claim aud.
Personalização de tokens no Cognito
Com o trigger Lambda de geração de pré-token, antes só podíamos personalizar o ID Token, portanto era frequentemente usado para autorização também. Com a introdução do novo evento V2 nos Cognito User Pools, podemos personalizar tanto o ID token quanto o Access token.
Implementando PEP e PDP
Com essa introdução concluída, vamos mergulhar na implementação de um PEP e PDP com RBAC. Nosso PEP será o Lambda Authorizer no API Gateway e nosso PDP será uma função Lambda separada. O PDP usará Grupos do Cognito e DynamoDB para a lógica de autorização RBAC.
Visão geral da arquitetura
Só para lembrar, todo o código e toda a arquitetura podem ser encontrados em Serverless Handbook PEP e PDP
Nesta solução, implementaremos nosso PEP usando Lambda Authorizer no API Gateway. O PDP, neste caso, também será implementado usando uma função Lambda. Atribuiremos aos utilizadores uma Função usando Grupos do Cognito e manteremos um mapeamento Função - Permissão no DynamoDB.

Para entender melhor o fluxo durante um acesso à API.

Como visto, não usaremos um API Gateway para o nosso PDP. Em vez disso, nosso PEP invocará a função Lambda do PDP. Existem prós e contras com esta abordagem, é claro. Do lado dos prós, temos menor latência, uma invocação direta de Lambda é muitas vezes mais rápida do que uma chamada de API. Menor custo pois não temos que pagar pela invocação do API Gateway. Do lado negativo, criamos um acoplamento mais forte e mudar a implementação do PDP pode ficar mais difícil. Precisaríamos implementar um cache separado no PDP, usando um API Gateway poderíamos depender do cache do API Gateway.
No entanto, a abordagem que você escolher precisa ser uma abordagem caso a caso, não há uma regra de ouro exatamente como implementar isso.
Implantar autenticação e Cognito
A primeira coisa que faremos é implantar e configurar o Cognito e os recursos necessários para login. Configuraremos o Cognito User Pool, configuraremos o login gerenciado e um site simples que tratará os callbacks do Cognito e exibirá nossos tokens JWT. Para simplificar, será apenas uma página HTML estática do CloudFront e algumas funções Lambda@Edge. Usarei a configuração que descrevi neste post de blog, então para uma imersão profunda, recomendo que você leia isso.
Portanto, como primeiro passo, implantamos o Lambda@Edge, a distribuição do CloudFront e o certificado SSL de Serverless Handbook PEP e PDP
Em seguida, vamos implantar e configurar o Cognito. Criaremos o UserPool, um cliente, estilo de login, etc.
AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Description: Cria o User Pool e Cliente usados para Autenticação
Parâmetros:
ApplicationName:
Tipo: String
Descrição: O aplicativo que possui este conjunto.
DomainName:
Tipo: String
Descrição: O nome de domínio a usar para cloudfront
HostedAuthDomainPrefix:
Tipo: String
Descrição: O prefixo de domínio a usar para o UI hospedado do UserPool <HostedAuthDomainPrefix>.auth.[região].amazoncognito.com
Recursos:
UserPool:
Tipo: AWS::Cognito::UserPool
Propriedades:
UsernameConfiguration:
CaseSensitive: false
AutoVerifiedAttributes:
- email
UserPoolName: !Sub ${ApplicationName}-user-pool
Schema:
- Nome: email
AttributeDataType: String
Mutable: false
Obrigatório: true
- Nome: name
AttributeDataType: String
Mutable: true
Obrigatório: true
UserPoolClient:
Tipo: AWS::Cognito::UserPoolClient
Propriedades:
UserPoolId: !Ref UserPool
GenerateSecret: True
AllowedOAuthFlowsUserPoolClient: true
CallbackURLs:
- !Sub https://${DomainName}/signin
AllowedOAuthFlows:
- code
- implicit
AllowedOAuthScopes:
- phone
- email
- openid
- profile
SupportedIdentityProviders:
- COGNITO
HostedUserPoolDomain:
Tipo: AWS::Cognito::UserPoolDomain
Propriedades:
Domain: !Ref HostedAuthDomainPrefix
ManagedLoginVersion: 2
UserPoolId: !Ref UserPool
ManagedLoginStyle:
Tipo: AWS::Cognito::ManagedLoginBranding
Propriedades:
ClientId: !Ref UserPoolClient
UserPoolId: !Ref UserPool
UseCognitoProvidedValues: true
UserPoolIdParameter:
Tipo: AWS::SSM::Parameter
Propriedades:
Nome: !Sub /${ApplicationName}/userPoolId
Tipo: String
Valor: !Ref UserPool
Descrição: Parâmetro SSM para o ID do User Pool
Tags:
ApplicationName: !Ref ApplicationName
UserPoolHostedUiParameter:
Tipo: AWS::SSM::Parameter
Propriedades:
Nome: !Sub /${ApplicationName}/userPoolHostedUi
Tipo: String
Valor: !Sub https://${HostedAuthDomainPrefix}.auth.${AWS::Region}.amazoncognito.com/login?client_id=${UserPoolClient}&response_type=code&scope=email+openid+phone+profile&redirect_uri=https://${DomainName}/signin
Descrição: Parâmetro SSM para o User Pool Hosted UI
Tags:
ApplicationName: !Ref ApplicationName
Saídas:
CognitoUserPoolJwksUri:
Valor: !Sub https://cognito-idp.${AWS::Region}.amazonaws.com/${UserPool}/.well-known/jwks.json
Descrição: A URI do jwks do UserPool
Exportar:
Nome: !Sub ${AWS::StackName}:jwks-url
CognitoUserPoolID:
Valor: !Ref UserPool
Descrição: O ID do UserPool
CognitoAppClientID:
Valor: !Ref UserPoolClient
Descrição: O cliente do aplicativo
Exportar:
Nome: !Sub ${AWS::StackName}:app-audience
CognitoUrl:
Descrição: A url
Valor: !GetAtt UserPool.ProviderURL
CognitoHostedUI:
Valor: !Sub https://${HostedAuthDomainPrefix}.auth.${AWS::Region}.amazoncognito.com/login?client_id=${UserPoolClient}&response_type=code&scope=email+openid+phone+profile&redirect_uri=https://${DomainName}/signin
Descrição: A URL da UI hospedada
Com esta implantação concluída, podemos passar para o Console e criar grupos aos quais os utilizadores podem ser adicionados. Criarei três grupos, Admin, Developer e Test. Clique em Criar Grupo e dê um nome. O nome do grupo representaria a Função que o utilizador terá e determinará quais permissões ele/ela obterá, mais sobre essa configuração mais adiante.

Em seguida, podemos criar alguns utilizadores e atribuí-los a um dos grupos.
Para testar esta configuração, podemos navegar até a página da web implantada com a distribuição do CloudFront e inspecionar os tokens JWT, cookies.

Se coparmos o access token e decodificarmos, eu uso jwt.io, podemos ver que meu utilizador tem a claim cognito:groups que nosso PEP e PDP usarão mais tarde para permissões.
Configuração e implantação do PDP
Em seguida, podemos implantar nosso serviço de autorização, nosso PDP, responsável por tomar decisões de permissão.
A lógica será implementada em uma função Lambda e, para gerenciar permissões baseadas em função, criaremos uma tabela DynamoDB que armazena permissões para cada função. Cada permissão define quais recursos o utilizador pode acessar, pode ser um endpoint de API específico e método HTTP, mas claro, não limitado a isso. Modelaremos os dados da tabela
PK (Chave de partição): A Função (por exemplo, Admin, User). SK (Chave de classificação): O recurso, por exemplo, endpoint e Método, por exemplo, GET /unicorn. Ação: A ação, por exemplo, GET, PUT, WRITE, READ, LIST etc Recurso: O Recurso, por exemplo, o endpoint /unicorn Efeito: O Efeito, Permitir ou Negar Descrição: Uma descrição da permissão.
| PK | SK | Ação | Recurso | Efeito | Descrição |
|---|---|---|---|---|---|
| Admin | GET /unicorn | GET | /unicorn | Permitir | Admin pode acessar todos os unicórnios |
| Test | POST /unicorn | POST | /unicorn | Permitir | Test pode postar em unicórnios |
| Developer | DELETE /unicorn | DELETE | /unicorn | Negar | Manager não pode excluir um unicórnio |
Isso nos permite pesquisar eficientemente as permissões para cada função usando uma consulta simples ao DynamoDB.
AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Descrição: Aplicativo Connected BBQ Serviço de Locatário
Parâmetros:
ApplicationName:
Tipo: String
Descrição: Nome do aplicativo proprietário
UserManagementStackName:
Tipo: String
Descrição: O nome da pilha que contém a parte de gerenciamento de utilizadores, por exemplo, o Cognito UserPool
Globais:
Função:
Timeout: 30
MemorySize: 2048
Architectures:
- arm64
Runtime: python3.12
Recursos:
PermissionsTable:
Tipo: AWS::DynamoDB::Table
Propriedades:
TableName:
Fn::Sub: ${ApplicationName}-pdp-role-permission-map
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: PK
AttributeType: S
- AttributeName: SK
AttributeType: S
KeySchema:
- AttributeName: PK
KeyType: HASH
- AttributeName: SK
KeyType: RANGE
LambdaPDPFunction:
Tipo: AWS::Serverless::Function
Propriedades:
CodeUri: Lambda/AuthZ
Handler: authz.handler
Políticas:
- DynamoDBReadPolicy:
TableName: !Ref PermissionsTable
Ambiente:
Variáveis:
JWKS_URL:
Fn::ImportValue: !Sub ${UserManagementStackName}:jwks-url
AUDIENCE:
Fn::ImportValue: !Sub ${UserManagementStackName}:app-audience
PERMISSIONS_TABLE:
!Ref PermissionsTable
Saídas:
PDPLambdaArn:
Valor: !GetAtt LambdaPDPFunction.Arn
Descrição: O ARN da função Lambda PDP
Exportar:
Nome: !Sub ${AWS::StackName}:pdp-lambda-arn
PDPLambdaName:
Valor: !Ref LambdaPDPFunction
Descrição: O Nome da função Lambda PDP
Exportar:
Nome: !Sub ${AWS::StackName}:pdp-lambda-nameLógica de autorização de função
O PDP Lambda decodificará o JWT, recuperará a função da claim cognito:groups e consultará a tabela DynamoDB para verificar se a função tem permissão para acessar o recurso solicitado.
import os
import json
import jwt
import boto3
from jwt import PyJWKClient
from botocore.exceptions import ClientError
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table(os.environ["PERMISSIONS_TABLE"])
JWKS_URL = os.environ["JWKS_URL"]
AUDIENCE = os.environ["AUDIENCE"]
def handler(event, context):
data = event
jwt_token = data["jwt_token"]
resource = data["resource"]
action = data["action"]
return check_authorization(jwt_token, action, resource)
def check_authorization(jwt_token, action, resource):
try:
jwks_client = PyJWKClient(JWKS_URL)
signing_key = jwks_client.get_signing_key_from_jwt(jwt_token)
decoded_token = jwt.decode(
jwt_token,
signing_key.key,
algorithms=["RS256"],
audience=AUDIENCE,
)
role = (
decoded_token["cognito:groups"][0]
if "cognito:groups" in decoded_token
else None
)
if not role:
raise Exception("Não autorizado: Função não encontrada no token")
if validate_permission(role, action, resource):
response_body = generate_access(
decoded_token["sub"], "Permitir", action, resource
)
return {
"statusCode": 200,
"body": json.dumps(response_body),
"headers": {"Content-Type": "application/json"},
}
except Exception as e:
print(f"Erro de autorização: {str(e)}")
response_body = generate_access(decoded_token["sub"], "Negar", action, resource)
return {
"statusCode": 403,
"body": json.dumps(response_body),
"headers": {"Content-Type": "application/json"},
}
def validate_permission(role, action, resource):
print(f"validate_permission Função: {role}, Ação: {action}, Recurso: {resource}")
try:
response = table.query(
KeyConditionExpression="PK = :role AND SK = :endpoint",
ExpressionAttributeValues={
":role": role,
":endpoint": f"{action} {resource}",
},
)
if response["Items"] and response["Items"][0]["Effect"] == "Permitir":
return True
else:
return False
except ClientError as e:
print(f"Erro ao consultar DynamoDB: {e}")
return False
def generate_access(principal, effect, action, resource):
auth_response = {
"principalId": principal,
"effect": effect,
"action": action,
"resource": resource,
}
return auth_response
Implantar API e PEP
Agora podemos implantar nossa API e PEP, Lambda Authorizer.
AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Descrição: Cria a API para gerenciamento autônomo de certificados
Parâmetros:
ApplicationName:
Tipo: String
Descrição: Nome do aplicativo proprietário
UserManagementStackName:
Tipo: String
Descrição: O nome da pilha que contém a parte de gerenciamento de utilizadores, por exemplo, o Cognito UserPool
PDPStackName:
Tipo: String
Descrição: O nome da pilha que contém o serviço PDP
Globais:
Função:
Timeout: 30
MemorySize: 2048
Runtime: python3.12
Recursos:
LambdaGetUnicorn:
Tipo: AWS::Serverless::Function
Propriedades:
CodeUri: Lambda/API/GetUnicorn
Handler: handler.handler
Eventos:
GetUnicorns:
Tipo: Api
Propriedades:
Caminho: /unicorn
Método: get
RestApiId: !Ref UnicornApi
UnicornApi:
Tipo: AWS::Serverless::Api
Propriedades:
Descrição: API para criar e gerenciar Unicórnios
Nome: !Sub ${ApplicationName}-api
StageName: prod
OpenApiVersion: '3.0.1'
AlwaysDeploy: true
EndpointConfiguration: REGIONAL
Cors:
AllowMethods: "'GET,PUT,POST,DELETE,OPTIONS'"
AllowHeaders: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
AllowOrigin: "'*'"
Auth:
AddDefaultAuthorizerToCorsPreflight: false
Authorizers:
LambdaRequestAuthorizer:
FunctionArn: !GetAtt LambdaApiAuthorizer.Arn
FunctionPayloadType: REQUEST
Identity:
Headers:
- Authorization
ReauthorizeEvery: 600
DefaultAuthorizer: LambdaRequestAuthorizer
LambdaApiAuthorizer:
Tipo: AWS::Serverless::Function
Propriedades:
CodeUri: Lambda/Authorizer/
Handler: auth.handler
Políticas:
- LambdaInvokePolicy:
FunctionName:
Fn::ImportValue: !Sub ${PDPStackName}:pdp-lambda-name
Ambiente:
Variáveis:
JWKS_URL:
Fn::ImportValue: !Sub ${UserManagementStackName}:jwks-url
AUDIENCE:
Fn::ImportValue: !Sub ${UserManagementStackName}:app-audience
PDP_AUTHZ_ENDPOINT:
Fn::ImportValue: !Sub ${PDPStackName}:pdp-lambda-name
Definimos nosso PEP como o autorizador padrão, assim ele será adicionado a cada recurso e método. Para reduzir o número de chamadas ao nosso PDP, o cache de autorização no API Gateway é usado com um TTL de 600 segundos.
Lógica de autorização PEP
O Lambda Authorizer PEP decodificará o JWT, verificará a validade e, em seguida, chamará o PDP para uma decisão final de permissão.
import os
import json
import jwt
import boto3
from jwt import PyJWKClient
lambda_client = boto3.client("lambda")
def handler(event, context):
print(f"Evento: {json.dumps(event)}")
token = event["headers"].get("authorization", "")
path = event["path"]
method = event["httpMethod"]
if not token:
raise Exception("Não autorizado")
token = token.replace("Bearer ", "")
decoded_token = None
try:
jwks_url = os.environ["JWKS_URL"]
jwks_client = PyJWKClient(jwks_url)
signing_key = jwks_client.get_signing_key_from_jwt(token)
decoded_token = jwt.decode(
token,
signing_key.key,
algorithms=["RS256"],
audience=os.environ["AUDIENCE"],
)
data = {
"jwt_token": token,
"resource": path,
"action": method,
}
response = lambda_client.invoke(
FunctionName=os.environ["PDP_AUTHZ_ENDPOINT"],
InvocationType="RequestResponse",
Payload=json.dumps(data),
)
response_payload = json.loads(response["Payload"].read())
body = json.loads(response_payload["body"])
effect = body["effect"]
return generate_policy(
decoded_token["sub"], effect, event["methodArn"], decoded_token
)
except Exception as e:
print(f"Erro de autorização: {str(e)}")
return generate_policy(
decoded_token["sub"], "Negar", event["methodArn"], decoded_token
)
def generate_policy(principal_id, effect, resource):
auth_response = {
"principalId": principal_id,
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{"Action": "execute-api:Invoke", "Effect": effect, "Resource": resource}
],
},
}
return auth_response
Importância do cache
O cache é importante para otimizar nosso fluxo de autorização. Ao reduzir as chamadas ao PDP e acelerar a tomada de decisões, o cache ajuda a melhorar o desempenho geral, a escalabilidade e a eficiência de custo de nossa aplicação.
Reduzir Latência: Ao armazenar em cache os dados de função e permissão, o PEP evita chamadas repetidas ao nosso PDP, levando a tempos de resposta mais rápidos e menor latência para cada solicitação. Diminuir a Carga do PDP: O cache minimiza o número de chamadas feitas ao nosso PDP, reduzindo o risco de atingir limites de taxa ou limitação. Melhorar a Escalabilidade: Com menos solicitações atingindo nosso PDP, nossa arquitetura pode escalar de forma mais eficiente. Reduzir Custos: O cache reduz a necessidade de invocações repetidas ao PDP, o que diretamente reduz os custos de invocação do Lambda.
Resumo e conclusão
Implementar PEP e PDP em nosso fluxo de autorização oferece uma maneira altamente escalável, flexível e segura de controlar o acesso aos recursos. Ao aproveitar o AWS Lambda e o API Gateway, podemos construir um sistema de autorização serverless que separa as preocupações de autenticação e autorização, escala com a demanda e simplifica o gerenciamento de políticas.
Com a adição de Controle de Acesso Baseado em Função e DynamoDB para armazenar permissões, combinado com cache em memória para maior desempenho, podemos criar uma solução de autorização que atenda às necessidades atuais e futuras.
Entender a diferença entre ID Tokens e Access Tokens garante que nosso sistema use cada um apropriadamente, ajudando-nos a construir um sistema de autorização mais seguro e eficiente.
Boa codificação e mantenha-se seguro!
Código-fonte
Toda a configuração, com instruções detalhadas de implantação e todo o código, pode ser encontrada em Serverless Handbook PEP e PDP
Palavras Finais
Não se esqueça de me seguir no LinkedIn e X para mais conteúdo, e leia o restante dos meus Blogs
Como Werner diz! Agora vá construir!