You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Cognito实现API访问权限的精细化控制

How to Implement Granular Permission Control for Cognito User Groups in API Gateway + Lambda Setup

Great question! Let's walk through exactly how to lock down access so your two Cognito user groups can't reach each other's services. Since API Gateway is only validating the ID Token right now, we need to add checks for user group membership and tie that to resource access. Here's a step-by-step solution tailored to your stack:

1. Leverage Cognito Group Information in Token Validation

When a user authenticates via Cognito, their ID Token includes a cognito:groups claim that lists all groups they belong to. We can use this to enforce permissions in two key places:

Option A: Use a Lambda Authorizer (Custom Authorizer) in API Gateway

This is the cleanest approach because it handles permission checks before the request reaches your Lambda function. Here's how to set it up:

  • Create a Lambda function that receives the incoming API request, extracts and validates the ID Token, checks the user's groups, and returns an allow/deny policy for the requested resource.
  • Configure API Gateway to use this authorizer for all your protected API methods. The authorizer will block unauthorized requests early in the pipeline.

Option B: Check Groups Inside Your Lambda Functions

If you prefer to handle checks at the function level (or have existing logic there), you can:

  • Extract the ID Token from the request headers (or the API Gateway event object).
  • Validate and decode the token to get the cognito:groups claim.
  • Immediately return a 403 Forbidden response if the user's group doesn't have permission to access that service.

2. Properly Bind IAM Roles to Cognito User Groups

You mentioned you already have two user groups with different IAM roles—make sure these roles have strict, scoped permissions:

  • For GroupA's role: Grant access only to ServiceA's Lambda function and its corresponding DynamoDB tables (use specific ARNs instead of wildcards).
  • For GroupB's role: Do the same for ServiceB's resources.
  • Note: These roles control what the user can do after accessing the API, so combining them with group-based API access checks creates a layered security model.

3. Example Lambda Authorizer Code

Here's a Python example that implements group-based access control:

import jwt
from jwt import PyJWKClient

def lambda_handler(event, context):
    # Extract the ID Token from the Authorization header
    try:
        token = event['authorizationToken'].split(' ')[1]
    except (KeyError, IndexError):
        return generate_policy('unauthorized', 'Deny', event['methodArn'])

    # Fetch Cognito public keys to validate the token (cache this in production!)
    jwks_url = "https://cognito-idp.<your-region>.amazonaws.com/<your-user-pool-id>/.well-known/jwks.json"
    jwks_client = PyJWKClient(jwks_url)
    
    try:
        signing_key = jwks_client.get_signing_key_from_jwt(token).key
        # Decode and validate the token (check audience, issuer, expiration)
        payload = jwt.decode(
            token,
            signing_key,
            algorithms=["RS256"],
            audience="<your-app-client-id>",
            issuer=f"https://cognito-idp.<your-region>.amazonaws.com/<your-user-pool-id>"
        )
    except jwt.InvalidTokenError:
        return generate_policy('unauthorized', 'Deny', event['methodArn'])

    # Get the user's groups from the token payload
    user_groups = payload.get('cognito:groups', [])
    # Extract the target service from the API resource ARN
    resource_path = event['methodArn'].split('/')[2]

    # Enforce group-service matching
    if resource_path == 'serviceA' and 'GroupA' in user_groups:
        return generate_policy(payload['sub'], 'Allow', event['methodArn'])
    elif resource_path == 'serviceB' and 'GroupB' in user_groups:
        return generate_policy(payload['sub'], 'Allow', event['methodArn'])
    else:
        # Deny access if the group doesn't match the service
        return generate_policy(payload['sub'], 'Deny', event['methodArn'])

def generate_policy(principal_id, effect, resource):
    """Helper function to create the IAM policy response"""
    return {
        'principalId': principal_id,
        'policyDocument': {
            'Version': '2012-10-17',
            'Statement': [{
                'Action': 'execute-api:Invoke',
                'Effect': effect,
                'Resource': resource
            }]
        }
    }

4. Additional Security Hardening Tips

  • Cache Authorizer Results: API Gateway lets you set a TTL for Lambda Authorizer responses to reduce redundant token validation calls and improve performance.
  • Strict Token Validation: Never skip checks for token expiration, audience, or issuer—this prevents tampered or invalid tokens from being used.
  • Layered Permissions: Combine API Gateway authorizer checks with IAM policies on Lambda and DynamoDB. Even if someone bypasses the API layer, the underlying resources will still be protected.

内容的提问来源于stack exchange,提问作者Himanshu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:34:47