entra id · sts token exchange · mcp url-mode elicitation
Goose uses Microsoft Entra ID for Solo UI / kagent login, and AgentGateway Enterprise
STS for per-user credential forwarding (elicitations). This page is the lab cheat-sheet:
accounts, URLs, and a repeatable test path for /github-elicit.
Autoauth is off. The Solo UI (AgentGateway and kagent tabs) redirects to
Microsoft Entra ID (tenant maniak.io).
Use your Entra account sebastian@maniak.io (member of security group
kagent-admin → RBAC global.Admin). Prefer HTTPS
:30443 if Entra redirects require it.
| What | URL | Identity | Role |
|---|---|---|---|
| Solo UI (login) | http://172.16.10.155:30854 · HTTPS :30443 |
sebastian@maniak.io (Entra) |
Admin (kagent-admin → global.Admin) |
| AgentGateway product | …/age/ |
same session | full AGE UI |
| Elicitations view | …/age/elicitations/ |
same session | authorize pending OAuth |
| kagent product | …/ |
same session | shared frontend |
| App | Type | Used by |
|---|---|---|
goose-solo-ui-frontend | SPA + PKCE | Solo UI frontend |
goose-solo-ui-backend | Confidential | UI backend · middle-tier JWT for scripts / OBO |
AgentGateway-MCP-SSO | App roles | /mcp-secure · Mcp.Admin / Mcp.User |
UI + MCP SSO apps: ./scripts/configure-entra.sh
Graph OBO client secret / consent: ./scripts/configure-entra-obo.sh
Not a chat form. In Solo Enterprise for AgentGateway, URL-mode elicitation is per-user OAuth credential forwarding via the Security Token Service (STS).
The MCP server never runs the OAuth dance. It only sees a normal request with a token already in
Authorization. Credentials never transit the MCP client/server path.
http://172.16.10.155:31606/github
Static PAT from Vault → github-mcp-token. Good for kagent github-agent.
http://172.16.10.155:<nodePort>/github-elicit
Dedicated Gateway with STS_URI=…/elicitations/oauth2/token (so OBO on :30160 stays intact). Script auto-discovers NodePort.
Stands in for a real GitHub OAuth App. After “Authorize”, STS receives the cluster PAT so MCP still works.
Four steps: log into the UI, trigger a miss, authorize, retry.
Open http://172.16.10.155:30854 → Microsoft Entra
as sebastian@maniak.io. Confirm you can open
/age/elicitations/.
From a machine on the lab LAN (with az login as the same Entra user), run the helper.
It mints a middle-tier Entra JWT and POSTs MCP initialize to
/github-elicit on the agentgateway-elicit NodePort (auto-discovered):
az login --tenant 8635e970-2205-4189-bc77-77519ff5064f ./scripts/test-elicitation.sh
Or the equivalent curl (resolve NodePort first):
# 1) Entra JWT (middle-tier audience) export USER_TOKEN=$(az account get-access-token \ --tenant 8635e970-2205-4189-bc77-77519ff5064f \ --resource api://0c00f6d2-5587-469d-9d35-7360d878fddc \ --query accessToken -o tsv) # 2) NodePort for agentgateway-elicit (not :30160 — that is OBO/oauth2/token) export NP=$(kubectl --context maniak-goose -n agentgateway-system \ get svc agentgateway-elicit -o jsonpath='{.spec.ports[0].nodePort}') # 3) MCP initialize — expect 500 + elicitations URL on first call curl -sS -i -X POST "http://172.16.10.155:${NP}/github-elicit" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -H 'mcp-protocol-version: 2025-06-18' \ -H "Authorization: Bearer $USER_TOKEN" \ -d '{ "jsonrpc":"2.0","id":1,"method":"initialize", "params":{ "protocolVersion":"2025-06-18", "capabilities":{}, "clientInfo":{"name":"elicit-demo","version":"1.0"} } }'
Expected (first call): HTTP 500 and a body like:
HTTP/1.1 500 TokenExchangeInfo { url: Some("http://172.16.10.155:30854/age/elicitations"), ... }
Open http://172.16.10.155:30854/age/elicitations/ (still logged in via Entra). Find the pending elicitation → Authorize.
You’ll hit the lab OAuth stub consent page at :30881 (not real GitHub). Click
Continue / Authorize. You should bounce back to the elicitations view as completed.
Re-run the same script/curl. STS now has a per-user token; the proxy injects it and
initialize should return GitHub MCP serverInfo / protocol result.
./scripts/test-elicitation.sh
| Piece | Where | Notes |
|---|---|---|
| Entra IdP | login.microsoftonline.com | UI + STS subject/api validators (JWKS) |
| Solo UI OIDC | argocd/apps/solo-ui.yaml | Entra issuer (autoauth off) |
| STS | control plane :7777 | tokenExchange.enabled on enterprise-agentgateway |
| OBO / impersonation STS | agentgateway-proxy-params | STS_URI=…/oauth2/token · NodePort 30160 |
| Elicitation STS client | agentgateway-elicit-params | STS_URI=…/elicitations/oauth2/token |
| OAuth provider secret | elicitation-oidc | lab stub URLs + client id/secret |
| OAuth stub | NodePort 30881 | returns existing PAT as access_token |
| Backend + policy | github-mcp-elicit | no static PAT; elicitation injects |
| Route | /github-elicit on agentgateway-elicit | NodePort auto (script discovers) |
172.16.10.155. If DHCP moves the worker, NodePorts move with it (kubectl get nodes -o wide).http://172.16.10.155:30854/age/elicitations, then update
config/elicitations/elicitation-oidc-secret.yaml (client id/secret + GitHub authorize/token URLs).:31606/github so kagent github-agent is unaffected.:30160 — that Gateway’s STS_URI is
/oauth2/token for Entra OBO. Elicitation needs /elicitations/oauth2/token
(dedicated agentgateway-elicit). Wrong path mints junk JWTs → GitHub
“Authorization header is badly formatted”.# Entra token (middle-tier) — requires az login az account get-access-token \ --tenant 8635e970-2205-4189-bc77-77519ff5064f \ --resource api://0c00f6d2-5587-469d-9d35-7360d878fddc \ --query accessToken -o tsv | wc -c # Elicit Gateway + NodePort kubectl --context maniak-goose -n agentgateway-system get gateway,svc agentgateway-elicit # STS port on control plane kubectl --context maniak-goose -n agentgateway-system get svc enterprise-agentgateway # Policy accepted kubectl --context maniak-goose get eagpol github-mcp-elicit-policy -n agentgateway-system