Skip to content

Update AWS STS tutorial for MCP Server authorization model change (March 24, 2026) #587

@jhrozek

Description

@jhrozek

Background

AWS announced (effective March 24, 2026) that the AWS MCP Server will no longer require separate aws-mcp:* IAM permissions. Authorization moves to the AWS service level using existing IAM roles and policies. Two new IAM condition context keys are being added:

  • aws:ViaAWSMCPService (Bool) — true for all requests via any AWS-managed MCP server
  • aws:CalledViaAWSMCP (String) — identifies the specific MCP server (e.g., aws-mcp.amazonaws.com)

The following IAM actions are being removed: aws-mcp:InvokeMcp, aws-mcp:CallReadOnlyTool, aws-mcp:CallReadWriteTool.

Affected file

docs/toolhive/tutorials/aws-sts-integration.mdx — 4 locations need changes. No other docs files are affected (other references to aws-mcp are for SigV4 service naming, which is unchanged).


Change 1: Rewrite permission model explanation (lines 120–135)

Current text:

### Understanding the AWS MCP Server permission model

AWS MCP Server authorization works in two layers:

1. **MCP layer** (`aws-mcp:*` actions) - controls which categories of MCP tools
   the user can invoke
2. **AWS service layer** (e.g., `s3:*`, `ec2:*`) - controls what the
   `aws___call_aws` tool can actually do when it makes AWS API calls

The `aws-mcp` namespace defines three actions:

- `InvokeMcp` - required to connect and discover available tools
- `CallReadOnlyTool` - search documentation, list regions, get CLI suggestions
- `CallReadWriteTool` - execute real AWS API calls via the `aws___call_aws` tool

Required change: Rewrite to explain that as of March 24, 2026, authorization happens directly at the AWS service level (e.g., s3:GetObject, ec2:DescribeInstances). The aws-mcp:* action namespace no longer exists. Introduce the two new context keys (aws:ViaAWSMCPService and aws:CalledViaAWSMCP) as the mechanism for scoping permissions to MCP-originated requests only.


Change 2: Replace default role permission policy example (lines 166–179)

Current text:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["aws-mcp:InvokeMcp", "aws-mcp:CallReadOnlyTool"],
      "Resource": "*"
    }
  ]
}

Required change: Replace with a policy that grants actual read-only service actions (e.g., sts:GetCallerIdentity or whatever minimal set makes sense for a default role), optionally scoped with "Condition": { "Bool": { "aws:ViaAWSMCPService": "true" } }. Consider also showing a deny guardrail to prevent credential use outside MCP:

{
  "Sid": "DenyDirectAPIAccess",
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "BoolIfExists": {
      "aws:ViaAWSMCPService": "false"
    }
  }
}

Change 3: Replace S3 read-only role permission policy example (lines 213–232)

Current text:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "aws-mcp:InvokeMcp",
        "aws-mcp:CallReadOnlyTool",
        "aws-mcp:CallReadWriteTool"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": "*"
    }
  ]
}

Required change: Remove the entire first statement (the aws-mcp:* actions). The policy only needs the S3 actions. Update the prose (lines 208–211) to explain that under the new model, only the underlying service permissions are needed. Optionally add aws:CalledViaAWSMCP condition to scope S3 actions to MCP-originated requests only.


Change 4: Update troubleshooting section (lines 590–606)

Current text:

<details>
<summary>Service access denied: "User is not authorized to perform
aws-mcp:InvokeMcp"</summary>

This error means the assumed role doesn't have the required permissions. Verify
the permission policy attached to the role includes the necessary actions:

...

Ensure the policy includes `aws-mcp:InvokeMcp` and any other actions your MCP
tools require.
</details>

Required change: Replace the error summary with the new service-level authorization error (e.g., "User is not authorized to perform s3:ListBucket"). Update guidance to explain that permissions are now checked at the AWS service level — the role needs actual service actions rather than aws-mcp:* actions.


Files that do NOT need changes

These reference aws-mcp only as a SigV4 service name (unchanged) or link to the tutorial without repeating IAM actions:

  • reference/crd-spec.md — SigV4 service name
  • static/api-specs/toolhive-api.yaml — SigV4 service name
  • guides-k8s/remote-mcp-proxy.mdx — links to tutorial
  • concepts/backend-auth.mdx — describes STS/SigV4 technology
  • guides-k8s/token-exchange-k8s.mdx — CRD references only
  • guides-k8s/auth-k8s.mdx — CRD references only
  • guides-vmcp/backend-discovery.mdx — CRD references only

Additional suggestion

The new context keys (aws:ViaAWSMCPService, aws:CalledViaAWSMCP) are not documented anywhere in our docs yet. Consider adding a "Security best practices" section to the tutorial showing the deny-guardrail pattern — this prevents stolen STS session credentials from being used outside the MCP channel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions