Skip to content

feat(http): per-user OAuth resource server mode - #1

Merged
gusocegodk merged 3 commits into
mainfrom
feat/oauth-resource-server
Oct 6, 2026
Merged

gusocegodk merged 3 commits into
mainfrom
feat/oauth-resource-server

Conversation

@gusocegodk

@gusocegodk gusocegodk commented Oct 6, 2026 •

Copy link
Copy Markdown

Summary

MCP_AUTH_MODE=oauth lets each user sign in with an OIDC provider, and BookStack then acts as that user instead of one shared API token.

  • Resource server (MCP authorization spec 2025-11-25): serves protected resource metadata (RFC 9728) and answers 401 with a WWW-Authenticate challenge. It checks each JWT's signature against the issuer's published keys, plus iss, exp, sub, the token type, and an aud naming this server.
  • No passthrough: each verified token is exchanged (RFC 8693) by this server's own confidential client for BookStack's audience. The result is cached and sent to BookStack as Authorization: Bearer. The token the MCP client sent is never forwarded.
  • Refused in OAuth mode: MCP_AUTH_TOKEN, BOOKSTACK_API_TOKEN, BOOKSTACK_UPLOAD_ROOT and the x-bookstack-* overrides.
  • Readiness: /health checks issuer discovery and that BookStack answers at all.
  • Unchanged: token mode and stdio.
  • Image: a v<version>-r<revision> tag (e.g. v2.1.0-r1) builds the Docker image, runs the image smoke suite against it, and pushes ghcr.io/<owner>/bookstack-mcp-server:2.1.0-r1 with provenance and an SBOM. <version> must match package.json, and the image reports the full version.

Needs BookStack with OIDC access-token API auth (https://codeberg.org/bookstack/bookstack/pulls/6237).

Testing

  • tests/unit/oauth-*, tests/unit/token-exchange.test.ts and tests/transport/oauth.test.ts run against an RS256-signing OIDC stub.
  • The image smoke suite now covers OAuth startup and the 401 challenge.

@gusocegodk gusocegodk self-assigned this Oct 6, 2026
MCP_AUTH_MODE=oauth makes the HTTP transport an OAuth resource server per
the MCP authorization spec: protected resource metadata, Bearer challenges,
and JWT validation against MCP_OAUTH_ISSUER with this server's URL as the
required audience. Each verified token is exchanged (RFC 8693) for a
BookStack API token, so BookStack acts as the signed-in user; the inbound
token is never forwarded.
@gusocegodk
gusocegodk force-pushed the feat/oauth-resource-server branch from 4dc536f to 8520130 Compare October 6, 2026 09:16
A v* tag (pushed, or dispatched for tags release-please created) checks
the tag against package.json, builds the image, runs the image smoke
suite against it and only then pushes it to GHCR with provenance and an
SBOM.
Image tags are now v<package.json version>-r<N>, so changes on top of
the same package version can be re-released, and plain vX.Y.Z tags build
nothing. The release version is baked in as SERVER_VERSION and the image
smoke suite asserts the version the container reports.
@gusocegodk
gusocegodk marked this pull request as ready for review October 6, 2026 09:31
@gusocegodk
gusocegodk merged commit 12733e3 into main Oct 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant