Artificial Intelligence
Implementing defense-in-depth authorization for MCP tools on Amazon Quick
Each Model Context Protocol (MCP) tool invocation on Amazon Quick is an access event that can require defense-in-depth authorization at the tool and parameter level. This applies in addition to a valid token. Without granular controls, a single misconfigured permission can bypass the access requirements that organizations might need to fulfill for compliance purposes. In this blog post, you implement a multi-gate authorization pattern that evaluates OpenID Connect (OIDC) JSON Web Token (JWT) claims in sequence. The pattern enforces role-based and attribute-based access control on each invocation. You configure which authorization controls to activate based on your compliance requirements, from group-based permissions to parameter-level attribute checks. Microsoft Entra ID serves as the identity provider (IdP) for this walkthrough.
When you connect MCP tools to Amazon Quick, a valid single sign-on (SSO) confirms who the caller is but not what they should be allowed to do. Authorization closes that gap, turning a verified identity into a set of enforceable rules about what each caller can reach. Model Context Protocol (MCP) is an open protocol that connects applications to internal tools, databases, and APIs, reducing the need for custom integrations. However, the moment those tools reach sensitive data, a valid SSO token is no longer enough. Without layered, defense-in-depth authorization, a single over-broad token can reach tools and data beyond the caller’s role, which can expose data and complicate compliance audits.
When an organization connects sensitive data sources to Amazon Quick through MCP, “authenticated” no longer equals “authorized.” Authorization decides which tools a caller can invoke, from which locations, and at what privilege level. For example, a regulated organization requires multi-factor authentication (MFA) at sign-in and restricts access from unapproved countries. The identity provider enforces the first requirement, and the authorization layer enforces the second. Standard OAuth 2.0 identity verification doesn’t enforce what callers can do at the tool and parameter level.
This post explains how the multi-gate authorization pattern works and walks you through configuring the identity layer that drives it. The interceptor processes OpenID Connect (OIDC) JSON Web Token (JWT) claims through four gates: MFA, geographic restriction, group-to-role mapping, and tool-level permission checks. In this walkthrough you configure the Microsoft Entra ID applications, claims, and policies the gates rely on. You then connect Amazon Quick to an existing Amazon Bedrock AgentCore Gateway, a capability of Amazon Bedrock AgentCore. The gateway provides the HTTP endpoint and JWT validation layer between clients and MCP tools. You validate the allow and restricted paths by signing in as different personas. This walkthrough assumes you have already deployed the AWS components, including the gateway, the interceptor AWS Lambda function, the tool Lambda functions, and the Amazon DynamoDB tables. You get an auditable, composable security layer that sits between the user’s natural-language request and your business logic.
Solution overview
This blog post uses a fictional example: AnyCompany Global Services, an enterprise that maintains a multi-tenant risk register hosted on Amazon DynamoDB accessed through MCP tools on Amazon Quick. This pattern is relevant for financial services, healthcare, and government organizations that can require granular access controls for compliance audits.
AnyCompany requires that each tool invocation comes from an authenticated caller who has completed MFA. Callers connecting from unapproved countries are denied access. Role-based permissions enforce a strict read/write boundary: readers can query risks but can’t create, update, or delete them, while administrators can bypass conditional gates for operational flexibility. Finally, every mutation must produce an immutable audit record to satisfy compliance and forensic requirements.
The multi-gate authorization user flow shown in Figure 1 addresses each of the preceding requirements. You implement it through a single AWS Lambda REQUEST interceptor attached to Amazon Bedrock AgentCore Gateway. The interceptor evaluates JWT claims in a fixed sequence, and each gate operates independently.
The authorization gates process requests in this order:
| Gate | Name | JWT Claim | Purpose | Active when |
| 1 | MFA verification | Enforced by Identity Provider (IdP) | Require MFA before token issuance | Conditional Access Policy |
| 2 | Country geo-fence | ctry | Restrict access to approved countries | REQUIRE_COUNTRY=true |
| 3 | Group role-based access control (RBAC) | groups | Map group membership to reader, author, or admin policies | Always (core gate) |
| 4 | Tool permission | Policy allowlists | Verify the requested tool exists in the matched policy | Always (core gate) |
Each gate is independently configured through environment variables. Gates 3 and 4, group role-based access control (RBAC) and tool permission, form the core authorization layer and are always active. The remaining two gates are conditional and can be disabled by setting the environment variables to false or by omitting them entirely. This means a deployment requiring only RBAC and geo-fencing activates three gates. A deployment requiring further granularity and control can activate each of the four checks.
Gate 1 is the only gate that is enforced outside the interceptor. Entra ID applies the Conditional Access Policy before it issues a token, so every token that reaches the gateway has already satisfied MFA. Setting REQUIRE_MFA turns on an additional check of the amr claim inside the interceptor, for identity providers that record MFA evidence in the token. The two mechanisms work together: the policy keeps unverified callers out, and the claim check confirms in the request path that the token carries the evidence.
The interceptor evaluates all four authorization gates before business logic runs. A request that fails a gate is denied with a 403 and doesn’t reach the tool or its data. Each mutation that passes writes an immutable audit record, giving you a complete, queryable trail of who did what.
Before deploying the solution, set up your identity provider.
Prerequisites
This walkthrough assumes familiarity with AWS Lambda, OAuth 2.0 authorization flows, and Microsoft Entra identity provider configuration. You also need access to a few AWS services and an OIDC identity provider, described in the following sections.
AWS services access
This walkthrough assumes the AWS side of the pattern is already deployed in your account. That side comprises an Amazon Bedrock AgentCore Gateway configured with a CUSTOM_JWT authorizer, the AWS Lambda REQUEST interceptor, the tool Lambda functions, and the Amazon DynamoDB tables they use. Deploying those resources is outside the scope of this post, which focuses on the identity and authorization configuration.
Identity provider setup
This walkthrough uses Microsoft Entra ID as the identity provider. The authorization pattern works with OIDC-eligible identity providers. However, the configuration steps vary based on the identity provider you choose. You need the following in your Entra ID tenant: a Global Administrator or Application Administrator role to create app registrations, security groups, and the Conditional Access Policy that enforces MFA. Conditional Access Policies need a Microsoft Entra ID P1 or P2 license. For validation, prepare at least three test users with different group memberships.
Deploy the Entra ID applications
The following sections walk you through registering the two app registrations, exposing the API, and wiring up permissions. You also configure the claims the AWS Lambda interceptor reads to control permissions on the MCP tools. Throughout, replace the placeholder identifiers ({TENANT_ID}, {RESOURCE_APP_ID}, {GATEWAY_URL}, and so on) with the values from your own tenant.
Amazon Quick uses Proof Key for Code Exchange (PKCE) and RFC 8707 Resource Indicators, a standard for binding tokens to specific API endpoints. Together they scope each access token to a specific MCP server. During the token exchange, Amazon Quick sends the AgentCore Gateway URL as the resource parameter. Entra ID requires the client and resource represented by separate app registrations when the resource is identified by a URL.
Configure the resource application
Steps 1 through 3 register the resource application, set its Application ID URI, and expose the API scopes that Amazon Quick requests.
Step 1: Register the resource application (AnyCompany-MCP-Authorization)
The resource application represents the protected MCP API. Its access token is the token that AgentCore Gateway validates.
- In the Microsoft Entra admin center, go to Entra ID > App registrations and choose New registration.
- For Name, enter
AnyCompany-MCP-Authorization. - Under Supported account types, select Accounts in this organizational directory only (single tenant).
- Keep Redirect URI empty (the resource app does not handle sign-in redirects). Choose Register.
Figure 2 shows the completed registration form for the resource application, with the name entered and single-tenant selected.
- On the application Overview page, note and copy the Application (client) ID, Object ID, and the Directory (tenant) ID. You need these values later.
Figure 3 shows the Overview page, where the Application (client) ID, Object ID, and Directory (tenant) ID appear.
Step 2: Set the Application ID URI and token version using Microsoft Graph API
The next two settings on the resource application are applied through the Microsoft Graph API:
- Application ID URI: the identifier is a full URL (the AgentCore Gateway URL), so you set
identifierUristhrough the Graph API. - Access token version: the pattern requires a v2.0 access token, so you update the Microsoft Graph
apiattribute underapi.requestedAccessTokenVersion.
You can apply both in a single PATCH against the application object. Use the application’s Object ID (distinct from the client ID), which you noted in Step 1.
Option A: Microsoft Graph Explorer
- Open Microsoft Graph Explorer and sign in as an administrator. Consent to the
Application.ReadWrite.Allscope when prompted. - Set the method to PATCH and the URL to
https://graph.microsoft.com/v1.0/applications/{OBJECT_ID}. - Set the request body to the following, replacing {GATEWAY_URL} with your gateway URL (for example, api://{RESOURCE_APP_ID} or the full gateway endpoint, depending on your tenant policy):
- Choose Run query. A 204 No Content response indicates success.
Figure 4 shows the PATCH request in Microsoft Graph Explorer and the 204 No Content response that confirms it succeeded.
Option B: Azure CLI
- Sign in to the tenant with the Tenant ID from Step 1.
- PATCH identifierUris and the requested access token version in one call using the Object ID.
- Confirm the change by reading the application back.
The response should list your identifierUris and show “requestedAccessTokenVersion”: 2.
Step 3: Expose the API scopes
With the Application ID URI set, add the delegated scopes the gateway and Amazon Quick request.
- In the resource application, go to Expose an API.
- Choose Add a scope. In the Add a scope panel, complete the form for the first scope:
- Scope name:
mcp. - Who can consent?: Select Admins and users (or Admins only if your tenant requires administrator consent for all scopes)
- Admin consent display name: A short label, for example Access MCP tools.
- Admin consent description: For example, Allows the app to invoke MCP tools on behalf of the signed-in user.
- User consent display name and User consent description: Optional. Provide user-facing equivalents if you allowed user consent.
- State: Leave set to Enabled.
- Repeat Add a scope for each of the remaining delegated scopes, using the same consent and state settings:
mcp:stream.stream.invoke.
- When done, the Scopes defined by this API list shows all four scopes, each with its full Application ID URI (for example,
api://<gateway-id>.../mcp) and an Enabled state.
If Add a scope reports that the Application ID URI isn’t set, confirm that Step 2 completed successfully because the portal reads identifierUris set through Graph.
Configure the client application
Steps 4 and 5 register the client application and grant it permission to call the resource API.
Step 4: Register the client application (AnyCompany-Quick-MCP-Client)
The client application is the OAuth client Amazon Quick authenticates as.
- In App registrations, choose New registration.
- For Name, enter
AnyCompany-Quick-MCP-Client. - Under Supported account types, select Accounts in this organizational directory only (single tenant).
- Under Redirect URI, select platform Web and enter https://us-east-1.quicksight.aws.amazon.com/sn/oauthcallback. Choose Register.
- Go to Certificates & secrets > Client secrets > New client secret. Add a description and expiry, choose Add, then copy the secret Value (it’s shown only once).
- On the Overview page, copy the Application (client) ID. You now have the Client ID and Client Secret Amazon Quick requires.
Step 5: Grant the client permission to the resource API
- In the client application (
AnyCompany-Quick-MCP-Client), go to API permissions > Add a permission. - Choose My APIs and select
AnyCompany-MCP-Authorization. - Select Delegated permissions, check the invoke scope, and choose Add permissions.
For this flow, the invoke delegated permission on the resource application is sufficient. Amazon Quick is the OAuth client and manages PKCE, refresh tokens, and the user session internally. You therefore don’t need to request
offline_accessor Microsoft Graphopenid/profilescopes on the resource app. The token the AgentCore Gateway validates is the resource app’s access token (audience = your resource app). The identity claims the interceptor reads (oid,sub,groups,ctry,amr) come from the claims you configure on that token in Steps 6 and 7.
- Select Grant admin consent for {your tenant} and confirm.
Figure 5 shows the client application API permissions after admin consent, with the invoke scope granted on the resource application.
Configure claims, groups, and MFA
Steps 6–9 add the claims the AWS Lambda interceptor reads, create the security groups that back the RBAC policies, and require MFA at sign-in.
Step 6: Configure the groups claim
- In the resource application (
AnyCompany-MCP-Authorization), go to Token configuration. - Choose Add groups claim.
- Select Security groups, and under ID for the Access token type, choose the Group ID format. Choose Add.
Figure 6 shows the Token configuration page with the groups claim added for the access token.
Step 7: Add optional claims
- Staying on the Token configuration page of the resource application, choose Add optional claim.
- Set the token type to Access and add the ctry and email claims. Choose Add.
- If prompted to turn on the Microsoft Graph permissions the claims require, accept.
Figure 7 shows the Microsoft Graph API permissions with admin consent granted for the claims.
Step 8: Create the security groups
Create three security groups in Identity > Groups > All groups > New group (group type Security):
| Group name | Purpose | Members |
| Risk-Register-Readers | Read-only access to risk tools | Users who can query risks |
| Risk-Register-Authors | Read and write access to risk tools | Users who can create, update, and delete risks |
| Risk-Register-Admins | Super user access, bypasses conditional gates | Operational administrators |
Figure 8 shows the three security groups created in Microsoft Entra ID.
After creating each group, open it and copy its Object ID from the Overview page, the interceptor maps these IDs to RBAC policies. Then assign your test users to the appropriate groups. When a user signs in to Amazon Quick, the resulting access token includes their group Object IDs using the groups claim. The interceptor reads these IDs from the token. It then maps them to the corresponding RBAC policy.
Step 9: Require MFA with a Conditional Access Policy
Gate 1 (MFA verification) is enforced by Entra ID before a token is ever issued.
- Go to Protection > Conditional Access > Policies > New policy.
- Name the policy (for example, Require MFA for MCP Authorization).
- Under Assignments > Users, select your test users or a group containing them.
- Under Target resources > Cloud apps, select the resource application (
AnyCompany-MCP-Authorization). - Under Access controls > Grant, choose Grant access and select Require multifactor authentication.
- Set Enable policy to On and choose Create.
From the preceding steps, collect the values the interceptor requires to enforce authorization. This is the tenant ID, the application client IDs, and the Object IDs of the three security groups you created. The interceptor reads these as environment variables, along with the toggle settings that activate each conditional gate.
| Variable | Purpose |
| READERS_GROUP_ID, AUTHORS_GROUP_ID, ADMINS_GROUP_ID | Object IDs of the three security groups, mapped to RBAC policies |
| REQUIRE_COUNTRY | Activate the country geo-fence (true/false) |
| ALLOWED_COUNTRIES | Comma-separated ISO country codes permitted when the geo-fence is active |
With the identity provider configured, the next section walks you through the architecture that connects these components.
Architecture design
The architecture follows a linear request flow from user authentication through authorization to tool execution and data storage.
Figure 9 shows the end-to-end architecture, from the user request in Amazon Quick through the gateway and interceptor to the tool functions and data store.
The numbered steps in the architecture are:
- Amazon Quick authenticates with the client application (
AnyCompany-Quick-MCP-Client) in Entra ID. Entra ID redirects the caller to its authorization endpoint, where the caller authenticates and completes MFA as required by the Conditional Access Policy. - Entra ID issues a token scoped to the resource application (
AnyCompany-MCP-Authorization). Amazon Quick exchanges the authorization code at the token endpoint and includes the gateway URL as the resource parameter. The resulting JWT contains group memberships and country claims. - Amazon Quick attaches the JWT as a bearer token on each call to the Amazon Bedrock AgentCore Gateway endpoint.
- Amazon Bedrock AgentCore Gateway validates the JWT signature, issuer, audience, and expiry using the Entra ID JSON Web Key Set (JWKS) endpoint.
- AWS Lambda REQUEST interceptor receives the validated JWT claims and processes the active authorization gates in sequence.
- Tool AWS Lambda function executes the requested operation and writes risk data to the
fgac-riskstable in Amazon DynamoDB using tenant-scoped partition keys and conditional expressions. - Tool AWS Lambda function appends an immutable audit record to the audit table, capturing the actor identity, action, timestamp, and outcome.The response returns through Amazon Bedrock AgentCore Gateway to Amazon Quick. When you grant access, the authorization layers remain invisible. When you deny access, clear messages surface.
Amazon Bedrock AgentCore Gateway provides the HTTP endpoint and JWT validation layer that connects Amazon Quick to your MCP tools.
Entra ID configuration to AWS enforcement map
| Entra ID configuration | What it produces | Where enforced in AWS |
| App registration | client_id + tenant_id | Gateway JWT authorizer (audience + issuer) |
| Token config: groups claim | groups array of Object ID UUIDs | Interceptor maps UUIDs to RBAC policies |
| Security groups | Group Object IDs | Interceptor environment variables: READERS_GROUP_ID, AUTHORS_GROUP_ID, ADMINS_GROUP_ID |
| User group assignment | User membership | Determines tool access level |
| Conditional Access Policy | Enforces MFA before token issuance | Identity provider blocks unauthenticated requests before they reach the gateway |
| ctry claim | ctry string in JWT | Interceptor country geo-fence |
With the architecture mapped, you can examine how the authorization layer reads the claims.
Understand the authorization pattern
The Amazon Bedrock AgentCore Gateway uses a CUSTOM_JWT authorizer configured with three values from your Entra ID tenant, the issuer, the audience (your client ID), and the JWKS URI:
The gateway validates the token signature, issuer, audience, and expiry before the interceptor runs. The interceptor then decodes the JWT payload and evaluates the active gates in order. A failed gate returns a 403 and the tool Lambda is not invoked:
- Gate 1: MFA verification. Enforced by the Conditional Access Policy before the token is issued, so tokens reaching the interceptor have already passed MFA. An optional
amrclaim check (REQUIRE_MFA) is available for IdPs that embed MFA evidence in the token. - Gate 2: Country geo-fence. When
REQUIRE_COUNTRY=true, reject the request if thectryclaim is not inALLOWED_COUNTRIES. - Gate 3: Group RBAC. Map each UUID in the
groupsclaim to areaders,authors, oradminspolicy. If none match, deny all access. - Gate 4: Tool permission. Confirm the requested tool name is in the matched policy allowlist.
The policy definitions and group-to-policy mapping provide a single source of truth, built from the security group Object IDs you collected in Step 8 and supplied as environment variables:
MCP tool Lambdas. The pattern uses six tool Lambdas, one per MCP tool:
| Tool | Operation | Access level |
| list_risks | List all risks for a tenant | Readers, Authors, Admins |
| get_risk | Get a specific risk by ID | Readers, Authors, Admins |
| search_risks | Search risks by keyword | Readers, Authors, Admins |
| create_risk | Create a new risk | Authors, Admins |
| update_risk | Update an existing risk | Authors, Admins (owner check) |
| delete_risk | Delete a risk | Authors, Admins |
Each tool Lambda re-checks the caller’s permissions server-side, so authorization holds even if the interceptor is misconfigured or bypassed. Every mutation appends an immutable audit record with the actor, action, timestamp, tool name, and outcome to the Amazon DynamoDB audit table.
With the Entra application deployed and the pattern understood, connect the AgentCore Gateway to Amazon Quick and validate each gate.
Connect to Amazon Quick and validate
Before connecting the gateway, confirm your test users have access to the Amazon Quick instance. Provision users through AWS IAM Identity Center, either by Configuring SAML and SCIM automatic provisioning from Entra ID. Alternatively, you can manually assign users in the IAM Identity Center console to the Amazon Quick application. You can then connect Amazon Quick to remote MCP servers over HTTP using the built-in MCP client.
Connect Amazon Quick to the Amazon Bedrock AgentCore Gateway endpoint by providing four values for Service-to-Service Authentication. In Amazon Quick, navigate to Home > Connectors > Create for your team > MCP and add a new MCP server with the following configuration:
| Field | Value | Source |
| MCP Server URL | https://{gateway-id}.gateway.bedrock-agentcore.us-east-1.amazonaws.com/mcp | Gateway MCP endpoint |
| Client ID | Your Entra ID application (client) ID | Entra ID app registration (Step 4) |
| Client Secret | Your Entra ID client secret | Entra ID certificates & secrets (Step 4) |
| Token URL | https://login.microsoftonline.com/{tenant-id}/oauth2/token | Entra ID |
Figure 11 shows the MCP server connection configuration, where you enter the AgentCore Gateway endpoint.
Figure 12 shows the service-to-service authentication settings for the connection.
In the next step, Amazon Quick validates the OAuth token and discovers the available tools from the gateway.
After connecting the MCP Connector, the six risk register tools appear in Amazon Quick as available actions. You can interact with them through natural language. When you grant access, the authorization layers remain invisible to the user. When you deny access, clear messages surface.
Figure 13 shows the connected MCP server with the six risk register tools listed as available actions.
Validate with test personas
Sign in to Amazon Quick as callers with different group memberships and attributes to test each authorization gate independently. Figure 14 illustrates the successful path. An Author invokes create_risk, and each of the four gates passes. The tool AWS Lambda function writes the risk and audit record to Amazon DynamoDB, and Amazon Quick receives a 200 OK.
Figure 15 shows the denial path. A Reader invokes create_risk, passes Gates 1 through 3, but is rejected at Gate 4 (tool permission) because the Readers policy lacks write tool permissions. The tool AWS Lambda function is not invoked.
The user receives a clear message on Amazon Quick for the failed action, which is tied to their access level.
Figure 16 shows the access denied response that Amazon Quick returns for an unauthorized tool invocation.
With each gate validated end to end, the pattern is enforcing authorization on each tool invocation. If a persona behaves unexpectedly, the following table maps common symptoms to their resolutions.
Troubleshooting
If a persona behaves unexpectedly during validation, the cause is usually a configuration mismatch between Entra ID and the interceptor. The following table maps the symptoms you are most likely to see to their typical cause and resolution.
| Symptom | Cause | Resolution |
| 401 Unauthorized on every request | JWT signature validation fails at the gateway | Verify the JWKS URI is correct and accessible. Confirm the issuer and audience match the identity provider’s token configuration |
| Can’t set Application ID URI in the portal | The portal UI rejects a full URL as the identifier | Set identifierUris through Microsoft Graph (see Step 2) |
| Tokens are v1.0 instead of v2.0 | requestedAccessTokenVersion not set on the resource app | PATCH api.requestedAccessTokenVersion to 2 through Microsoft Graph (see Step 2) |
| 403 for a user who should have access | Group Object ID mismatch between Entra ID and interceptor env vars | Copy the exact Object ID from Entra ID and update READERS_GROUP_ID, AUTHORS_GROUP_ID, or ADMINS_GROUP_ID |
| Callers can sign in without MFA | Conditional Access Policy not configured or not targeting the resource application | Create a Conditional Access Policy requiring MFA, targeting the resource application (not the client application). Verify the policy state is On |
| Country geo-fence denies approved country | ctry claim not present or using wrong code format | Add the ctry optional claim in Entra ID token configuration. Use two-letter ISO country codes |
| No logs visible for the interceptor | Lambda not invoked or log group permissions missing | Check Amazon CloudWatch Logs for the interceptor function. Verify the function’s execution role has logs:CreateLogGroup and logs:PutLogEvents permissions |
Cleanup
Remove the AWS resources you deployed for this pattern. This walkthrough does not cover provisioning the AWS resources. On the Amazon Quick console, you can delete the MCP connector if it is no longer required.
To complete the cleanup, delete the Entra ID resources manually. Remove the AnyCompany-MCP-Authorization and AnyCompany-Quick-MCP-Client app registrations, the Conditional Access Policy on the tenant, and the three security groups if they are no longer needed.
Conclusion
You can use the multi-gate authorization pattern to provide composable, defense-in-depth access control for MCP tools on Amazon Quick. By processing MFA verification, country geo-fencing, group-based RBAC, and tool-level permissions in sequence, the pattern enforces granular authorization without changing the end-user experience.
You can apply the interceptor pattern wherever MCP tools access sensitive resources. Point the gates at your own Entra ID tenant and replace the risk register with your own domain. Adjust the RBAC policies to match your organization’s requirements and activate the gates your compliance framework requires. The pattern scales to your needs. A basic configuration can rely on the single groups claim for RBAC alone, leaving the conditional MFA and country gates disabled. A regulated workload can activate every authorization gate.
For more information, see the following resources:
- Amazon Quick User Guide
- Amazon Bedrock AgentCore documentation
- Apply fine-grained access control with Bedrock AgentCore Gateway interceptors
- Secure AI agents with Policy and Lambda interceptors in Amazon Bedrock AgentCore gateway
- Implement on-behalf-of token exchange for multi-tenant agents with Amazon Bedrock AgentCore Gateway
- Integrate external tools with Amazon Quick Agents using Model Context Protocol (MCP)















