Skip to content

feat(auth): replace stub bearer with LIME OAuth 2.1 + agent identity - #1

Open
Mawyxx wants to merge 1 commit into
ByteAsk:mainfrom
Mawyxx:feat/lime-oauth-auth
Open

feat(auth): replace stub bearer with LIME OAuth 2.1 + agent identity#1
Mawyxx wants to merge 1 commit into
ByteAsk:mainfrom
Mawyxx:feat/lime-oauth-auth

Conversation

@Mawyxx

@Mawyxx Mawyxx commented Jul 11, 2026

Copy link
Copy Markdown

Problem

  • HTTP transport used a shared static bearer token (MCP_HTTP_AUTH_TOKEN).
  • No RFC 9728 Protected Resource Metadata (PRM).
  • No per-agent audit trail (sub identity).
  • Fail-open when token unset (dev warning only).

Solution

  • FastMCP native OAuth RS: token_verifier + AuthSettings + mcp.run(transport="streamable-http").
  • LIME JWT verification via lime-mcp-server-sdk.
  • New auth/ package: settings, verifier adapter, agent context, factory.
  • Per-tool structured logging with agent_id (JWT sub, never raw JWT).

Breaking changes

  • MCP_HTTP_AUTH_TOKEN deprecated; production uses MCP_AUTH_MODE=lime.
  • MCP_RESOURCE_SERVER_URL required in lime mode.
  • Legacy mode kept for one release (http_auth_legacy.py).

Test plan

  • pytest tests/ -v — full matrix in docs/AUTH_TEST_MATRIX.md (27/27 passing)
  • PRM: GET /.well-known/oauth-protected-resource
  • 401 without token + invalid JWT
  • 200 with mock JWKS-signed JWT
  • Legacy bearer middleware
  • Live E2E with real LIME agent (lime-agents-sdk): JWT from LIME AS → list_tools + call_tool search_docs → server log tool=search_docs agent_id=<sub>
  • ./scripts/verify_checklist_live.py — 20/20 automated checks (none / legacy / lime + live JWT)

Production deploy checklist

MCP_AUTH_MODE=lime
MCP_RESOURCE_SERVER_URL=https://mcp.byteask.ai
MCP_ALLOWED_HOSTS=mcp.byteask.ai
LIME_BASE_URL=https://lime.pics
LIME_OAUTH_AUDIENCE=mcp

Agent documentation

See docs/AUTH.md — two integration paths:

  1. SDK (lime-agents-sdk): list_tools / call_tool
  2. Manual: get_mcp_access_token() + Authorization: Bearer

Developer API for per-request identity:

from byteask_embedded_mcp.auth import current_agent_id
agent_id = current_agent_id()  # JWT sub, no manual parsing

Files changed

Area Files
Auth module src/byteask_embedded_mcp/auth/*
Server factory server.py, config.py
HTTP transport http_auth.py, http_auth_legacy.py
Observability obs.py (agent_id in document requests)
Tests tests/test_auth.py
Docs docs/AUTH*.md, README.md, .env.example, server.json

Non-goals (follow-up PRs)

  • Rate limits / billing per agent
  • Per-agent corpus ACL
  • Human browser OAuth
  • Removing legacy mode (next release)

- Removes MCP_HTTP_AUTH_TOKEN stub
- Adds LIME JWT verification via lime-mcp-server-sdk
- Every request carries agent_id from JWT sub claim
- Full audit trail: who called which tool
- Adds auth/ module with LimeMcpTokenVerifier and current_agent_id()
- HTTP transport now uses native FastMCP OAuth RS
- Legacy mode for backward compatibility (1 release)
- Tests: 27/27 passing
- Docs: README, .env.example, AUTH.md, UPSTREAM_PR.md

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant