Skip to content

Commit b119fa7

Browse files
tgrunnagleclaude
andauthored
Document authServerRef field and combined auth patterns (#702)
* Document authServerRef field and combined auth patterns Implements changes for issue #671: - Update auth-k8s.mdx to use authServerRef as primary example in Step 5 - Add backward compatibility note for externalAuthConfigRef - Add combined embedded auth + AWS STS section in aws-sts.mdx - Add authServerRef configuration section in embedded-auth-server.mdx - Update MCPServer vs VirtualMCPServer table with authServerRef info - Add combined auth pattern reference in backend-auth.mdx * Address code review feedback for authServerRef docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Minor manual tweaks * Address review feedback - Remove references to backwards compatible `externalAuthConfigRef` for embedded AS - Fix em-dash - Emphasize that any outgoing auth can be used with `externalAuthConfigRef` - Move "Combine embedded auth with AWS STS" to just before "next steps" on the AWS STS page * Additional clean up - Remove remaining reference to `authServerRef` being preferred - Tweak the embedded AS in vMCP vs MCPServer table - Run prettier and eslint --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 787a36b commit b119fa7

4 files changed

Lines changed: 129 additions & 35 deletions

File tree

docs/toolhive/concepts/backend-auth.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,15 @@ signing automatically, with claim-based IAM role selection. See the
343343
[AWS STS integration tutorial](../integrations/aws-sts.mdx) for a step-by-step
344344
setup guide.
345345

346+
You can also combine the embedded authorization server with AWS STS on the same
347+
`MCPServer` or `MCPRemoteProxy` resource. In this pattern, the embedded auth
348+
server handles incoming client authentication (using `authServerRef`), while AWS
349+
STS handles outgoing backend credentials (using `externalAuthConfigRef`). This
350+
is useful when your MCP clients don't have their own OIDC tokens and need
351+
ToolHive to manage the full OAuth flow. See
352+
[Combine embedded auth with AWS STS](../integrations/aws-sts.mdx#combine-embedded-auth-with-aws-sts)
353+
for a complete example.
354+
346355
## Related information
347356

348357
- For client authentication concepts, see

docs/toolhive/concepts/embedded-auth-server.mdx

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,39 @@ for a quick setup, or the full
157157
[Redis Sentinel session storage](../guides-k8s/redis-session-storage.mdx) guide
158158
for an end-to-end walkthrough.
159159

160+
## Configuring the embedded auth server with `authServerRef`
161+
162+
On `MCPServer` and `MCPRemoteProxy` resources, use the `authServerRef` field to
163+
reference an `MCPExternalAuthConfig` resource that defines the embedded auth
164+
server. `VirtualMCPServer` resources use an inline `authServerConfig` block
165+
instead.
166+
167+
```yaml
168+
spec:
169+
authServerRef:
170+
kind: MCPExternalAuthConfig
171+
name: my-embedded-auth-server
172+
```
173+
174+
The `authServerRef` field uses a `TypedLocalObjectReference`, so you must
175+
specify both `kind: MCPExternalAuthConfig` and the `name` of the resource.
176+
177+
For setup instructions, see
178+
[Set up embedded authorization server authentication](../guides-k8s/auth-k8s.mdx#set-up-embedded-authorization-server-authentication).
179+
For the combined auth pattern with AWS STS, see
180+
[Combine embedded auth with AWS STS](../integrations/aws-sts.mdx#combine-embedded-auth-with-aws-sts).
181+
160182
## MCPServer vs. VirtualMCPServer
161183

162184
The embedded auth server is available on both `MCPServer` and `VirtualMCPServer`
163185
resources, with some differences:
164186

165-
| | MCPServer | VirtualMCPServer |
166-
| ---------------------- | ------------------------------------------- | ------------------------------------------------------------------------------ |
167-
| Configuration location | Separate `MCPExternalAuthConfig` resource | Inline `authServerConfig` block on the resource |
168-
| Upstream providers | Single upstream provider | Multiple upstream providers with sequential authorization chaining |
169-
| Token forwarding | Automatic (single provider, single backend) | Explicit `upstreamInject` or `tokenExchange` config maps providers to backends |
187+
| | MCPServer | VirtualMCPServer |
188+
| ---------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
189+
| Configuration location | `authServerRef` referencing a separate `MCPExternalAuthConfig` resource | Inline `authServerConfig` block on the resource |
190+
| Upstream providers | Single upstream provider | Multiple upstream providers with sequential authorization chaining |
191+
| Token forwarding | Automatic (single provider, single backend) | Explicit `upstreamInject` or `tokenExchange` config maps providers to backends |
192+
| Combined auth | `authServerRef` for incoming and `externalAuthConfigRef` for outgoing auth | Separate incoming and outgoing auth configuration |
170193

171194
For single-backend deployments on MCPServer, the embedded auth server
172195
automatically swaps the token for each request. For vMCP with multiple backends,

docs/toolhive/guides-k8s/auth-k8s.mdx

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -609,12 +609,12 @@ kubectl apply -f embedded-auth-config.yaml
609609

610610
**Step 5: Create the MCPServer resource**
611611

612-
The MCPServer needs two configuration references: `externalAuthConfigRef`
613-
enables the embedded authorization server, and `oidcConfig` validates the JWTs
614-
that the embedded authorization server issues. Unlike approaches 1-3 where
615-
`oidcConfig` points to an external identity provider, here it points to the
616-
embedded authorization server itself—the `oidcConfig` issuer must match the
617-
`issuer` in your `MCPExternalAuthConfig`.
612+
The MCPServer needs two configuration references: `authServerRef` enables the
613+
embedded authorization server, and `oidcConfig` validates the JWTs that the
614+
embedded authorization server issues. Unlike approaches 1-3 where `oidcConfig`
615+
points to an external identity provider, here it points to the embedded
616+
authorization server itself. The `oidcConfig` issuer must match the `issuer` in
617+
your `MCPExternalAuthConfig`.
618618

619619
```yaml title="mcp-server-embedded-auth.yaml"
620620
apiVersion: toolhive.stacklok.dev/v1alpha1
@@ -629,9 +629,12 @@ spec:
629629
permissionProfile:
630630
type: builtin
631631
name: network
632+
# highlight-start
632633
# Reference the embedded authorization server configuration
633-
externalAuthConfigRef:
634+
authServerRef:
635+
kind: MCPExternalAuthConfig
634636
name: embedded-auth-server
637+
# highlight-end
635638
# Validate JWTs issued by the embedded authorization server
636639
oidcConfig:
637640
type: inline
@@ -652,33 +655,31 @@ spec:
652655
kubectl apply -f mcp-server-embedded-auth.yaml
653656
```
654657

655-
:::tip[Combining embedded auth with outgoing token exchange]
658+
The `authServerRef` field is a `TypedLocalObjectReference` that requires both
659+
`kind` and `name`. This field is also available on `MCPRemoteProxy` resources.
660+
661+
:::tip[Combining embedded auth with outgoing auth]
656662

657-
If you need both an embedded auth server for incoming client authentication
658-
**and** an outgoing token exchange (such as AWS STS) on the same MCPServer, use
659-
the dedicated `authServerRef` field instead of `externalAuthConfigRef` for the
660-
embedded auth server. This separates the two configurations so they don't
661-
compete for the same field:
663+
Use `authServerRef` for the embedded auth server and `externalAuthConfigRef` for
664+
any outgoing auth (such as AWS STS) on the same resource:
662665

663666
```yaml
664667
spec:
665-
# Dedicated field for the embedded auth server
668+
# Embedded auth server for incoming client authentication
666669
authServerRef:
667670
kind: MCPExternalAuthConfig
668671
name: embedded-auth-server
669672
# Outgoing token exchange (e.g., AWS STS)
670673
externalAuthConfigRef:
671674
name: aws-sts-config
672-
kind: MCPExternalAuthConfig
673675
oidcConfig:
674676
type: inline
675677
inline:
676678
issuer: 'https://mcp.example.com'
677679
```
678680

679-
`authServerRef` and `externalAuthConfigRef` cannot both reference an
680-
`embeddedAuthServer` type. The same `authServerRef` field is available on
681-
MCPRemoteProxy resources.
681+
For a complete example, see
682+
[Combine embedded auth with AWS STS](../integrations/aws-sts.mdx#combine-embedded-auth-with-aws-sts).
682683

683684
:::
684685

@@ -1014,7 +1015,7 @@ kubectl logs -n toolhive-system -l app.kubernetes.io/name=weather-server-k8s
10141015

10151016
- Verify the `MCPExternalAuthConfig` resource exists in the same namespace:
10161017
`kubectl get mcpexternalauthconfig -n toolhive-system`
1017-
- Check that the `externalAuthConfigRef.name` in your `MCPServer` matches the
1018+
- Check that the `authServerRef.name` in your `MCPServer` matches the
10181019
`MCPExternalAuthConfig` resource name
10191020
- Verify the upstream provider's client ID and redirect URI are correctly
10201021
configured in the `MCPExternalAuthConfig`

docs/toolhive/integrations/aws-sts.mdx

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -384,17 +384,6 @@ spec:
384384
385385
proxyPort: 8080
386386
transport: streamable-http
387-
388-
audit:
389-
enabled: true
390-
391-
resources:
392-
limits:
393-
cpu: '500m'
394-
memory: 512Mi
395-
requests:
396-
cpu: 100m
397-
memory: 128Mi
398387
```
399388

400389
Replace the placeholders with your OIDC provider's configuration.
@@ -640,6 +629,78 @@ aws iam delete-open-id-connect-provider \
640629
arn:aws:iam::<YOUR_AWS_ACCOUNT_ID>:oidc-provider/<YOUR_OIDC_ISSUER>
641630
```
642631

632+
## Combine embedded auth with AWS STS
633+
634+
If you want ToolHive to handle the full OAuth flow for incoming client
635+
authentication (instead of validating tokens from an external OIDC provider),
636+
you can combine the
637+
[embedded authorization server](../concepts/embedded-auth-server.mdx) with AWS
638+
STS on the same `MCPRemoteProxy`. Use `authServerRef` for the embedded auth
639+
server and `externalAuthConfigRef` for the AWS STS configuration.
640+
641+
This pattern is useful when your MCP clients don't have their own OIDC tokens.
642+
The embedded auth server redirects users to an upstream identity provider (such
643+
as Okta or Google), issues its own JWTs, and ToolHive then exchanges those JWTs
644+
for temporary AWS credentials via STS.
645+
646+
First, create an `MCPExternalAuthConfig` for the embedded auth server following
647+
the steps in
648+
[Set up embedded authorization server authentication](../guides-k8s/auth-k8s.mdx#set-up-embedded-authorization-server-authentication)
649+
(steps 1 through 4). Then deploy the `MCPRemoteProxy` with both references:
650+
651+
```yaml title="aws-mcp-remote-proxy-combined.yaml"
652+
apiVersion: toolhive.stacklok.dev/v1alpha1
653+
kind: MCPRemoteProxy
654+
metadata:
655+
name: aws-mcp-proxy
656+
namespace: toolhive-system
657+
spec:
658+
remoteURL: https://aws-mcp.us-east-1.api.aws/mcp
659+
660+
# Embedded auth server for incoming client authentication
661+
# highlight-start
662+
authServerRef:
663+
kind: MCPExternalAuthConfig
664+
name: embedded-auth-server
665+
# highlight-end
666+
667+
# AWS STS for outgoing backend authentication
668+
# highlight-start
669+
externalAuthConfigRef:
670+
name: aws-mcp-sts-auth
671+
# highlight-end
672+
673+
# Validate JWTs issued by the embedded authorization server
674+
oidcConfig:
675+
type: inline
676+
resourceUrl: https://<YOUR_DOMAIN>/mcp
677+
inline:
678+
# This must match the issuer in your embedded auth server config
679+
issuer: https://<YOUR_EMBEDDED_AUTH_ISSUER>
680+
681+
proxyPort: 8080
682+
transport: streamable-http
683+
```
684+
685+
In this configuration:
686+
687+
- `authServerRef` points to the `MCPExternalAuthConfig` with
688+
`type: embeddedAuthServer`, which handles the OAuth flow for incoming clients.
689+
- `externalAuthConfigRef` points to the `MCPExternalAuthConfig` with
690+
`type: awsSts`, which exchanges OIDC tokens for AWS credentials on outgoing
691+
requests.
692+
- `oidcConfig` validates JWTs issued by the embedded auth server. The `issuer`
693+
must match the `issuer` in your embedded auth server's
694+
`MCPExternalAuthConfig`.
695+
696+
:::info[authServerRef vs. externalAuthConfigRef]
697+
698+
The `authServerRef` field separates embedded auth from outgoing auth concerns.
699+
For more details, see
700+
[Configuring the embedded auth server with authServerRef](../concepts/embedded-auth-server.mdx#configuring-the-embedded-auth-server-with-authserverref).
701+
702+
:::
703+
643704
## Next steps
644705

645706
- Learn about the concepts behind

0 commit comments

Comments
 (0)