MCP Authentication
The MCP server reuses the web app's Cognito user pool and enforces the same approval gate and workspace RBAC. Authentication happens in four layers.
The four layers
- Client → Gateway. The client (Claude Code / Desktop) connects via streamable-HTTP to
the AgentCore Gateway URL. It discovers OAuth requirements through RFC 9728 Protected
Resource Metadata (PRM), then opens the Cognito Hosted UI in a browser for login (Google
or email/password). No
mcp-remoteproxy is required. - Gateway validates the JWT. AgentCore Gateway validates the Cognito access token — signature, expiry, issuer, and client_id — and serves PRM for OAuth discovery.
- Interceptor Lambda. A pass-through Lambda forwards the MCP request body and the
Authorizationheader, unchanged, to the AgentCore Runtime. - MCP container. The FastMCP server extracts the JWT from the header and independently
re-verifies its RS256 signature against the issuer's
/.well-known/jwks.json(fetched and cached for one hour, keyed bykid), and validatesexp,iss, and — whenLKWIZ_MCP_COGNITO_CLIENT_IDis set — the token'sclient_idclaim. This happens wheneverLKWIZ_MCP_ALLOWED_ISSUERis configured, which it is in bothdev.tfvarsandprod.tfvars; an unverified decode only happens if that setting is left empty, a dev/test-only escape hatch that isn't reachable in a properly configured deployment. The verifiedsubclaim is then used to read the user'sPROFILEitem from DynamoDB. Seeservices/mcp/src/lkwiz_mcp/auth/middleware.pyfor the implementation.
Approval & workspace access
- Only users with
approved: truein DynamoDB can call any tool. - Workspace-scoped tools check membership only — a shared
_check_workspace_accesshelper confirms the caller has aMEMBER#{user_id}record in the workspace. It does not read or branch on the member's role, so today any workspace member (owner, editor, or viewer) can call any workspace-scoped tool, including mutating ones likecreate_idea,generate_post, andcreate_action. This is coarser than the REST API, which in places enforces role-specific checks. - Admin-only tools (
admin_list_users,admin_approve_user) require the caller's platform role (USER#{id}/PROFILE.role) to beadmin— a separate concept from workspace role.
See specs/features/mcp.md ("Authorization (RBAC)") for the full breakdown, including the
one exception, and each domain's specs/mcp/<domain>.md / /mcp/<domain> page for
tool-by-tool detail.
Cognito app clients
lkwiz-mcp-gateway-m2m— a machine-to-machine client (client_credentialsflow) with a resource-server scope (mcp/invoke), used by the Gateway to reach the runtime.lkwiz-mcp-oauth— a user client (authorizationcodeflow) for interactive OAuth login, with a callback URL matching Claude Code's OAuth callback.
A pre-token-generation Lambda (shared with the web app) injects email into the access
token so the MCP server can identify callers without a /userinfo roundtrip.