Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion core/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ github.com/aws/smithy-go v1.27.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqx
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/buger/jsonparser v1.2.0 h1:4EFcvK1kD4jyj6YqNK6skK6w+y7FHHBR+XBCtxwu/6g=
github.com/buger/jsonparser v1.2.0/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
github.com/bytedance/sonic v1.15.1 h1:nJD5PmM0vY7J8CT6MxoqbVAAMhkSmV2HgRAUrrpLoOw=
Expand Down
6 changes: 6 additions & 0 deletions docs/mcp/auth/token-exchange.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,12 @@ Sending both an identity token and a virtual key is fine — [`dual_credential_c

---

## Try it yourself

[`examples/mcps/token-exchange-demo-server`](https://github.com/maximhq/bifrost/tree/main/examples/mcps/token-exchange-demo-server) is a runnable MCP server for testing this end-to-end against a real identity provider (Okta, Entra, Keycloak, Auth0, or any generic OIDC provider). It validates every request's bearer token via real OIDC discovery and JWKS signature verification — no shortcuts — and exposes a `whoami` tool that echoes back the caller's identity claims, so you can confirm each caller's own identity reached the upstream server.

---

## Next Steps

- [Per-User OAuth](./per-user-oauth) — when the upstream server runs its own OAuth and doesn't trust your IdP
Expand Down
166 changes: 166 additions & 0 deletions examples/mcps/token-exchange-demo-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Token Exchange (On-Behalf-Of) Demo MCP Server

A plain MCP resource server for exercising Bifrost's `token_exchange` MCP auth
type against a **real identity provider** — Okta, Microsoft Entra, Keycloak,
Auth0, or any generic OIDC provider.

## What is This?

`token_exchange` moves the entire delegation dance into Bifrost and your
identity provider: on every tool call, Bifrost exchanges the caller's own
identity-provider token for one scoped to this server's audience and sends
only the exchanged token upstream. This server has no OAuth server logic of
its own — its only job is what a real internal MCP server behind token
exchange would actually do: **validate the bearer token it receives** and
prove whose identity arrived.

Validation is full OIDC discovery + JWKS signature verification + issuer +
audience checks via [`coreos/go-oidc`](https://github.com/coreos/go-oidc).
Nothing here trusts an unverified token; a missing, malformed, wrong-issuer,
or wrong-audience token is rejected with HTTP 401 before the MCP server ever
sees it.

## Prerequisites

At your identity provider, register a dedicated application authorized to
perform token exchange (or the on-behalf-of grant) for an audience. See
[`docs/mcp/auth/token-exchange.mdx`](../../../docs/mcp/auth/token-exchange.mdx)
for provider-specific setup notes (Okta custom authorization servers, Entra's
`jwt-bearer` grant, etc.) — the exact steps vary by vendor.

You'll need:

- Your identity provider's **issuer URL** (its OIDC discovery document must
be reachable at `<issuer>/.well-known/openid-configuration`)
- The **audience** you registered the exchange application against
- The exchange application's **client ID**, for the Bifrost side
- The exchange application's **client secret**, for the Bifrost side —
optional, depending on your identity provider and whether the application
is registered as a public or confidential client

Comment thread
coderabbitai[bot] marked this conversation as resolved.
## Running the Server

### Prerequisites

```bash
go 1.26.5+
```

### Start the Server

```bash
# From this directory
TOKEN_EXCHANGE_ISSUER_URL="https://your-domain.okta.com/oauth2/your-auth-server-id" \
TOKEN_EXCHANGE_AUDIENCE="api://your-mcp-server" \
go run main.go
```

`TOKEN_EXCHANGE_ISSUER_URL` and `TOKEN_EXCHANGE_AUDIENCE` are both required —
the server fails fast at startup if either is missing, or if OIDC discovery
against the issuer fails.

`MCP_SERVER_PORT` optionally overrides the default port (`3004`).

Output:
```text
token-exchange-demo-server listening on http://localhost:3004/
Validating bearer tokens against issuer=https://your-domain.okta.com/oauth2/your-auth-server-id audience=api://your-mcp-server

Bifrost config:

{
"name": "token_exchange_demo",
"connection_type": "http",
"connection_string": "http://localhost:3004/",
"auth_type": "token_exchange",
"token_exchange": {
"audience": "api://your-mcp-server",
"client_id": "<your exchange application's client_id>",
"client_secret": "<your exchange application's client_secret>"
},
"tools_to_execute": ["*"]
}
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## Connecting via Bifrost

Use the printed config above, filling in your exchange application's
`client_id` / `client_secret`. `auth_type: "token_exchange"` requires your
Bifrost deployment's identity-provider integration to be configured and
pointed at the same identity provider — see
[Token Exchange auth](../../../docs/mcp/auth/token-exchange.mdx#prerequisites).

## Available Tools

### 1. whoami

Returns the identity claims from the caller's exchanged token — the main
point of this server. A successful call proves the caller's own identity
reached this upstream server, not a shared credential.

```json
{
"name": "whoami",
"arguments": {}
}
```

Response:
```json
{
"sub": "00u1a2b3c4d5e6f7g8h9",
"email": "alice@example.com",
"name": "Alice Smith",
"aud": "api://your-mcp-server",
"iss": "https://your-domain.okta.com/oauth2/your-auth-server-id",
"exp": 1735689600
}
```

### 2. echo

Echoes back the input message, tagged with the caller's identity — useful
for seeing the delegated identity attached to an ordinary tool call, not just
`whoami`.

```json
{
"name": "echo",
"arguments": {
"message": "Hello, World!"
}
}
```

## Testing With Two Different Callers

The most useful check: call `whoami` as two different signed-in users (or
with two different bearer tokens) and confirm the response names a different
identity each time — that's the delegation working end-to-end, as opposed to
everyone hitting this server under one shared credential.

A caller with **no identity token at all** (e.g. a virtual-key-only request)
should fail before ever reaching this server — `token_exchange` has no
service-account fallback.

## Implementation Notes

This example intentionally:

- ✅ Validates every request's bearer token via real OIDC discovery + JWKS
signature verification (issuer, audience, expiry) — no shortcuts
- ✅ Rejects with HTTP 401 on any validation failure, before the MCP server
processes the request
- ❌ Does NOT implement any OAuth authorization-server endpoints — that's
entirely Bifrost + your identity provider's job under `token_exchange`
- ❌ Does NOT cache or store anything about the caller — every request is
validated fresh, mirroring how Bifrost itself never persists a caller's
exchanged token to disk

## See Also

- [Token Exchange (On-Behalf-Of) auth](../../../docs/mcp/auth/token-exchange.mdx)
- [MCP Authentication Overview](../../../docs/mcp/auth/overview.mdx)
- [oauth-demo-server](../oauth-demo-server) — the per-user OAuth counterpart,
which *is* a full authorization server, for when the upstream service runs
its own OAuth instead of trusting your identity provider
22 changes: 22 additions & 0 deletions examples/mcps/token-exchange-demo-server/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module token-exchange-demo-server

go 1.26.5

require (
github.com/coreos/go-oidc/v3 v3.16.0
github.com/go-jose/go-jose/v4 v4.1.3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

cd examples/mcps/token-exchange-demo-server

for module in \
  github.com/go-jose/go-jose/v4 \
  github.com/buger/jsonparser
do
  echo "=== $module ==="
  go list -m -u -json "$module"
  go mod why -m "$module"
done

govulncheck ./...

Repository: maximhq/bifrost

Length of output: 2125


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '=== repository state ==='
git status --short
git diff --stat
git branch --all --no-color | head -50

printf '%s\n' '=== module files ==='
cat -n examples/mcps/token-exchange-demo-server/go.mod
printf '%s\n' '=== dependency references ==='
rg -n --hidden --glob '!vendor/**' \
  'go-jose|jsonparser|mcp-go|jsonschema|go-oidc|Bearer|bearer|JWT|JWE|token' \
  examples/mcps/token-exchange-demo-server

printf '%s\n' '=== stack metadata ==='
find .. -maxdepth 3 -type f \( -iname '*stack*' -o -name '.gitmodules' \) -print

Repository: maximhq/bifrost

Length of output: 14415


🌐 Web query:

OSV github.com/go-jose/go-jose/v4 v4.1.3 JWE decryption panic fixed version

💡 Result:

The fixed version for the JWE decryption panic in github.com/go-jose/go-jose/v4 is v4.1.4 [1][2]. This vulnerability, tracked as GHSA-78h2-9frx-2jm8 and CVE-2026-34986, occurs when decrypting a JSON Web Encryption (JWE) object if the alg field specifies a key wrapping algorithm (excluding A128GCMKW, A192GCMKW, and A256GCMKW) and the encrypted_key field is empty [1][3][4]. The issue causes a panic during the key unwrap process, which can lead to a denial-of-service [1][4]. If updating to version 4.1.4 is not immediately possible, you can mitigate the risk by ensuring your application does not accept JWE tokens containing key wrapping algorithms if they are not required, or by pre-validating JWE objects to ensure the encrypted_key field is non-empty [1][3].

Citations:


🌐 Web query:

OSV github.com/buger/jsonparser v1.1.1 denial of service fixed version

💡 Result:

The denial of service vulnerability in github.com/buger/jsonparser version 1.1.1, identified as CVE-2026-32285 (also tracked as GO-2026-4514 and GHSA-6g7g-w4f8-9c9x), is fixed in version 1.1.2 [1][2][3]. This vulnerability occurs because the Delete function fails to properly validate offsets when processing malformed JSON input, which can result in a negative slice index, leading to a runtime panic and denial of service [1][2][4]. Users are advised to upgrade to version 1.1.2 or later to address this issue [1][2][3].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

modroot="$(go env GOPATH)/pkg/mod"

printf '%s\n' '=== owning module requirements ==='
for f in \
  "$modroot/github.com/coreos/go-oidc/v3@v3.16.0/go.mod" \
  "$modroot/github.com/mark3labs/mcp-go@v0.43.2/go.mod" \
  "$modroot/github.com/invopop/jsonschema@v0.13.0/go.mod" \
  "$modroot/github.com/wk8/go-ordered-map/v2@v2.1.8/go.mod"
do
  if test -f "$f"; then
    echo "--- $f"
    cat "$f"
  fi
done

printf '%s\n' '=== vulnerable API usage in cached modules ==='
rg -n --glob '*.go' \
  'jsonparser\.(Delete|Get|ArrayEach|ObjectEach|Parse|Set)|go-jose|jose\.(Parse|Decrypt|DecryptMulti|ParseEncrypted)|ParseEncrypted|Decrypt' \
  "$modroot/github.com/coreos/go-oidc" \
  "$modroot/github.com/mark3labs/mcp-go" \
  "$modroot/github.com/invopop/jsonschema" \
  "$modroot/github.com/wk8/go-ordered-map" 2>/dev/null || true

printf '%s\n' '=== vulnerable implementation excerpts ==='
rg -n -A35 -B10 \
  'func Delete|func \(.*\) Decrypt|func \(.*\) DecryptMulti|func ParseEncrypted' \
  "$modroot/github.com/buger/jsonparser@v1.1.1" \
  "$modroot/github.com/go-jose/go-jose/v4@v4.1.3" 2>/dev/null || true

printf '%s\n' '=== available versions ==='
go list -m -versions github.com/buger/jsonparser
go list -m -versions github.com/go-jose/go-jose/v4

Repository: maximhq/bifrost

Length of output: 50373


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

modroot="$(go env GOPATH)/pkg/mod"

printf '%s\n' '=== application production imports and handlers ==='
sed -n '40,235p' examples/mcps/token-exchange-demo-server/main.go

printf '%s\n' '=== go-oidc token parsing path ==='
sed -n '190,245p' "$modroot/github.com/coreos/go-oidc/v3@v3.16.0/oidc/verify.go"
sed -n '1,55p' "$modroot/github.com/coreos/go-oidc/v3@v3.16.0/oidc/jose.go"

printf '%s\n' '=== jsonparser call sites in non-test cached code ==='
rg -n --glob '*.go' --glob '!**/*_test.go' \
  'github.com/buger/jsonparser|jsonparser\.' \
  "$modroot/github.com/mark3labs/mcp-go@v0.43.2" \
  "$modroot/github.com/invopop/jsonschema@v0.13.0" \
  "$modroot/github.com/wk8/go-ordered-map/v2@v2.1.8" \
  "$modroot/github.com/mailru/easyjson@v0.7.7" 2>/dev/null || true

printf '%s\n' '=== all Delete call sites in the dependency graph ==='
rg -n --glob '*.go' --glob '!**/*_test.go' \
  'jsonparser\.Delete|jsonparser\.Set|jsonparser\.ObjectEach|jsonparser\.ArrayEach' \
  "$modroot/github.com/mark3labs/mcp-go@v0.43.2" \
  "$modroot/github.com/invopop/jsonschema@v0.13.0" \
  "$modroot/github.com/wk8/go-ordered-map/v2@v2.1.8" \
  "$modroot/github.com/mailru/easyjson@v0.7.7" 2>/dev/null || true

printf '%s\n' '=== direct go-jose imports in application ==='
rg -n --glob '*.go' \
  'github.com/go-jose/go-jose/v4|josejwt|ParseEncrypted|Decrypt' \
  examples/mcps/token-exchange-demo-server

Repository: maximhq/bifrost

Length of output: 12349


Update the vulnerable dependency pins before merge.

Upgrade github.com/go-jose/go-jose/v4 to v4.1.4 or later and github.com/buger/jsonparser to v1.1.2 or later. These versions remain in the module graph, although this server does not reach the vulnerable JWE decryption or jsonparser.Delete paths.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@examples/mcps/token-exchange-demo-server/go.mod` at line 7, Update the
dependency pins in the module configuration: raise github.com/go-jose/go-jose/v4
to v4.1.4 or later and github.com/buger/jsonparser to v1.1.2 or later,
preserving the rest of the module graph.

Source: Linters/SAST tools

github.com/mark3labs/mcp-go v0.43.2
)

require (
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/invopop/jsonschema v0.13.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/spf13/cast v1.7.1 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
golang.org/x/oauth2 v0.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
45 changes: 45 additions & 0 deletions examples/mcps/token-exchange-demo-server/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/coreos/go-oidc/v3 v3.16.0 h1:qRQUCFstKpXwmEjDQTIbyY/5jF00+asXzSkmkoa/mow=
github.com/coreos/go-oidc/v3 v3.16.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mark3labs/mcp-go v0.43.2 h1:21PUSlWWiSbUPQwXIJ5WKlETixpFpq+WBpbMGDSVy/I=
github.com/mark3labs/mcp-go v0.43.2/go.mod h1:YnJfOL382MIWDx1kMY+2zsRHU/q78dBg9aFb8W6Thdw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading
Loading