Conversation
Tutorial covering end-to-end setup of ToolHive as an authentication proxy for the AWS MCP Server on Kubernetes. Users register their OIDC provider with AWS IAM, create IAM roles with the aws-mcp permission model, configure MCPExternalAuthConfig with type: awsSts, and deploy an MCPRemoteProxy pointing to the AWS MCP Server endpoint. Also adds cross-references from existing token exchange and remote proxy docs so readers discover the AWS-specific auth path: - concepts/backend-auth: mention AWS STS in the federation section, add "Built-in AWS STS support" subsection - guides-k8s/token-exchange-k8s: link in Related information - guides-k8s/remote-mcp-proxy: tip admonition after token exchange section Fixes: #510
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Adds new ToolHive documentation describing how to use AWS STS (via OIDC) to authenticate to the AWS MCP Server, and links to this new tutorial from existing Kubernetes/token-exchange documentation and the sidebar navigation.
Changes:
- Added a new end-to-end tutorial for AWS STS authentication to the AWS MCP Server on Kubernetes.
- Updated Docusaurus sidebar to include the new tutorial.
- Added cross-references/tips in existing token exchange, remote proxy, and backend-auth concept docs.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
sidebars.ts |
Adds the new AWS STS tutorial to the Tutorials sidebar navigation. |
docs/toolhive/tutorials/aws-sts-integration.mdx |
New tutorial covering AWS IAM OIDC provider setup, role/policy examples, and ToolHive resources for AWS STS-based auth. |
docs/toolhive/guides-k8s/token-exchange-k8s.mdx |
Links token exchange guide readers to the AWS STS tutorial. |
docs/toolhive/guides-k8s/remote-mcp-proxy.mdx |
Adds a tip steering AWS users toward type: awsSts and the new tutorial. |
docs/toolhive/concepts/backend-auth.mdx |
Adds conceptual mention of built-in AWS STS support and links to the tutorial. |
| "Federated": "arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:oidc-provider/<YOUR_OIDC_ISSUER_HOST>" | ||
| }, |
There was a problem hiding this comment.
The OIDC provider ARN placeholder <YOUR_OIDC_ISSUER_HOST> is likely misleading for issuers that include a path (common with Okta/Keycloak). In AWS, the oidc-provider/... segment must match the provider URL without the scheme and including any path; consider renaming the placeholder and clarifying this here.
| spec: | ||
| type: awsSts | ||
| awsSts: | ||
| region: <YOUR_AWS_REGION> |
There was a problem hiding this comment.
The docs now instruct users to set spec.type: awsSts with an awsSts: block, but the current CRD reference lists MCPExternalAuthConfigSpec.type enum values without awsSts and doesn’t document an awsSts field (see docs/toolhive/reference/crd-spec.md around the MCPExternalAuthConfigSpec table). Either update the CRD reference (and ensure the operator actually supports awsSts), or gate this tutorial behind the ToolHive version that introduces it.
| For AWS services like the AWS MCP Server, use `type: awsSts` instead of | ||
| `type: tokenExchange`. This exchanges OIDC tokens for temporary AWS credentials | ||
| via `AssumeRoleWithWebIdentity` and signs requests with SigV4. See the |
There was a problem hiding this comment.
This tip suggests switching MCPExternalAuthConfig.spec.type to awsSts, but the CRD reference currently doesn’t list awsSts as a supported enum value for MCPExternalAuthConfigSpec.type. Either update the reference/CRD docs alongside this change or add an explicit minimum ToolHive version requirement.
| For AWS services like the AWS MCP Server, use `type: awsSts` instead of | |
| `type: tokenExchange`. This exchanges OIDC tokens for temporary AWS credentials | |
| via `AssumeRoleWithWebIdentity` and signs requests with SigV4. See the | |
| In ToolHive installations where `MCPExternalAuthConfig.spec.type` supports the | |
| `awsSts` mode (check your installed CRD or reference docs), you can use | |
| `type: awsSts` instead of `type: tokenExchange` for AWS services like the AWS | |
| MCP Server. This exchanges OIDC tokens for temporary AWS credentials via | |
| `AssumeRoleWithWebIdentity` and signs requests with SigV4. See the |
| ```bash | ||
| aws iam create-open-id-connect-provider \ | ||
| --url https://<YOUR_OIDC_ISSUER> \ | ||
| --client-id-list <YOUR_OIDC_AUDIENCE> | ||
| ``` |
There was a problem hiding this comment.
aws iam create-open-id-connect-provider typically requires --thumbprint-list, and the placeholder usage is inconsistent: the command hard-codes https:// but the <YOUR_OIDC_ISSUER> example below includes https://..., which would lead to a doubled scheme if copied literally. Update the command/placeholders to be unambiguous and include the required thumbprint input.
| "StringEquals": { | ||
| "<YOUR_OIDC_ISSUER_HOST>:aud": "<YOUR_OIDC_AUDIENCE>" | ||
| } |
There was a problem hiding this comment.
Similarly, the IAM trust policy condition key should match the full OIDC provider identifier (host plus any issuer path) used when creating the provider (for example issuer.example.com/oauth2/default:aud). Clarify that <...>:aud must include the same path portion if present.
| --auth-method client_secret_basic \ | ||
| --response-mode form_post \ | ||
| --response-types code \ | ||
| --pkce | jq -r '.access_token') |
There was a problem hiding this comment.
This example pipes oauth2c output through jq, but the tutorial doesn’t mention jq as a prerequisite. Add it to prerequisites or show an alternative that doesn’t require jq.
| services, ToolHive has built-in STS support using `MCPExternalAuthConfig` with | ||
| `type: awsSts` |
There was a problem hiding this comment.
This guide recommends type: awsSts, but the CRD reference currently doesn’t list awsSts as a valid MCPExternalAuthConfigSpec.type value. Please update the CRD reference (or adjust the guidance) so readers don’t end up with manifests rejected by the API server.
| services, ToolHive has built-in STS support using `MCPExternalAuthConfig` with | |
| `type: awsSts` | |
| services, ToolHive has built-in STS support; see this tutorial and the | |
| MCPExternalAuthConfig CRD reference for the correct configuration |
| ### Built-in AWS STS support | ||
|
|
||
| For AWS services like the | ||
| [AWS MCP Server](https://docs.aws.amazon.com/aws-mcp/), ToolHive has built-in | ||
| support for exchanging OIDC tokens for temporary AWS credentials using | ||
| `AssumeRoleWithWebIdentity`. This handles the STS exchange and SigV4 request | ||
| signing automatically, with claim-based IAM role selection. See the | ||
| [AWS STS integration tutorial](../tutorials/aws-sts-integration.mdx) for a | ||
| step-by-step setup guide. | ||
|
|
There was a problem hiding this comment.
This section claims built-in AWS STS support, but the current CRD spec documentation for MCPExternalAuthConfig doesn’t include an awsSts type/config. Please align this concept doc with the actual shipped CRD (or update the CRD reference docs in the same change) to avoid documenting unsupported configuration.
| ### Built-in AWS STS support | |
| For AWS services like the | |
| [AWS MCP Server](https://docs.aws.amazon.com/aws-mcp/), ToolHive has built-in | |
| support for exchanging OIDC tokens for temporary AWS credentials using | |
| `AssumeRoleWithWebIdentity`. This handles the STS exchange and SigV4 request | |
| signing automatically, with claim-based IAM role selection. See the | |
| [AWS STS integration tutorial](../tutorials/aws-sts-integration.mdx) for a | |
| step-by-step setup guide. |
There was a problem hiding this comment.
I assume this (and other similar comments from Copilot) are because a release hasn't been cut with these new fields yet? That will auto-update the CRD reference.
| [Kubernetes quickstart guide](./quickstart-k8s.mdx)) | ||
| - `kubectl` configured to access your cluster | ||
| - An AWS account with permissions to create IAM roles, policies, and OIDC | ||
| identity providers |
There was a problem hiding this comment.
The tutorial uses aws CLI commands later, but the prerequisites don’t mention installing/configuring the AWS CLI (and credentials for running IAM commands). Add AWS CLI as an explicit prerequisite so readers can follow Step 1/2 without getting blocked.
| identity providers | |
| identity providers | |
| - The AWS CLI installed and configured with IAM credentials that can create | |
| IAM roles, policies, and OIDC identity providers |
danbarr
left a comment
There was a problem hiding this comment.
This looks really great! I have some small nits and one thing that a Claude review pointed out which may or may not be an issue.
| :::info[How role selection works] | ||
|
|
||
| When a request arrives, ToolHive evaluates your role mappings in priority order | ||
| (lower number = higher priority). The first matching rule determines which IAM | ||
| role to assume. If no mapping matches, the fallback role is used. | ||
|
|
||
| For example, if a user belongs to both `s3-readers` and `developers` groups, and | ||
| `s3-readers` has a lower priority number, ToolHive selects the S3 read-only | ||
| role. | ||
|
|
||
| ::: |
There was a problem hiding this comment.
This note feels too early, priority doesn't appear until the next section, suggest moving it down to line 291, just after the placeholders but before applying it.
| Create an `MCPExternalAuthConfig` resource that defines how ToolHive exchanges | ||
| OIDC tokens for AWS credentials. | ||
|
|
||
| ```yaml {4,7,10,13-17} title="aws-sts-auth-config.yaml" |
There was a problem hiding this comment.
The line highlighting seems off here. The name (since it's referenced later) and type make sense, but guessing the highlight on the blank line is just a one-off miss? In fact since most of it is directly relevant, maybe just highlight the type field? Optionally could also highlight the three lines with placeholders to replace (9,13,19) but that makes it a little staccato to read.
| ```yaml {4,7,10,13-17} title="aws-sts-auth-config.yaml" | |
| ```yaml {4,7} title="aws-sts-auth-config.yaml" |
| Replace the placeholders with your OIDC provider's configuration. Update the | ||
| region in `remoteURL` if you're not using `us-east-1`. |
There was a problem hiding this comment.
From their docs, I believe the MCP itself only exists in us-east-1, and the region for operations is influenced by a flag on their own proxy wrapper for it, or by the prompt that invokes the tools? I get an NXDOMAIN when I try to resolve the MCP endpoint on any region other than us-east-1.
| To make the proxy accessible to clients outside the cluster, create Gateway and | ||
| HTTPRoute resources: |
There was a problem hiding this comment.
Worth calling out that this assumes the reader is using a GatewayAPI solution and it would need adjustment for Ingress controllers?
| For detailed guidance on setting up ingress, including ngrok for development, | ||
| see | ||
| [Configure secure ingress for MCP servers on Kubernetes](./k8s-ingress-ngrok.mdx). |
There was a problem hiding this comment.
+1 to calling out the specific ngrok guide, we also have the more generic "Connect clients to MCP servers" guide too (../guides-k8s/connect-clients.mdx)
| kubectl delete httproute aws-mcp-route -n toolhive-system | ||
| ``` | ||
|
|
||
| Optionally, remove the AWS IAM resources: |
There was a problem hiding this comment.
If we're cleaning up, let's clean up 😄
| Optionally, remove the AWS IAM resources: | |
| Remove the AWS IAM resources: |
| - `CallReadOnlyTool` - search documentation, list regions, get CLI suggestions | ||
| (7 of 9 tools) |
There was a problem hiding this comment.
Nit: the "7 of 9 tools" will go stale, maybe not necessary at all or replace with "most tools"?
|
|
||
| :::info[What's happening?] | ||
|
|
||
| The `roleMappings` field uses simple claim matching by default: if the value in |
There was a problem hiding this comment.
The explanation here references "the roleClaim JWT claim (here, groups)" but the YAML in Step 3 doesn't include a roleClaim field anywhere. The YAML shows claim: s3-readers under roleMappings, where a reader would naturally parse claim as a claim name rather than a value to match against.
Three things need clarifying:
- Where does
groupscome from? IfroleClaimis a CRD field that defaults togroups, mention that explicitly — even a YAML comment like# roleClaim defaults to "groups"in the example would help. - The
claimfield underroleMappingsrepresents a value to match, not a claim name — that's counterintuitive and worth a sentence of explanation. - Readers whose IdP uses a different claim name (e.g., Auth0 may use
rolesor a custom namespace instead ofgroups) need to know how to change it.
Without this, a reader who doesn't happen to have a groups claim in their tokens won't know what to adjust.
Generated by Claude Code
There was a problem hiding this comment.
Claude identified this; I'm not as well-versed in the specifics here so take it with a grain of salt 😉
| 'toolhive/tutorials/mcp-optimizer', | ||
| 'toolhive/tutorials/custom-registry', | ||
| 'toolhive/tutorials/vault-integration', | ||
| 'toolhive/tutorials/aws-sts-integration', |
There was a problem hiding this comment.
Phase 1 of the restructuring was just merged, so you'll need to rebase to put this in the new integrations sidebar section. The actual file location is fine, those won't move until phase 2.
Description
Tutorial covering end-to-end setup of ToolHive as an authentication proxy for the AWS MCP Server on Kubernetes. Users register their OIDC provider with AWS IAM, create IAM roles with the aws-mcp permission model, configure MCPExternalAuthConfig with type: awsSts, and deploy an MCPRemoteProxy pointing to the AWS MCP Server endpoint.
Type of change
Related issues/PRs
#510
Screenshots
N/A
Submitter checklist
Content and formatting
Navigation
sidebars.ts) updated for added, deleted, reordered, or renamed filesvercel.jsonfor moved, renamed, or deleted pages (i.e., if the URL slug changed)Reviewer checklist
Content