docs: correct OIDC architecture framing for Login Flow v2

The previous round of review feedback rested on a misunderstanding —
that the MCP server is "the OAuth issuer" under Login Flow v2 and that
NEXTCLOUD_OIDC_CLIENT_ID/SECRET are external-IdP-only. Code says
otherwise (app.py:619/625/703-717, unified_verifier.py:72):

- The MCP server is an OIDC relying party of Nextcloud OIDC. Tokens are
  signed by Nextcloud and validated against Nextcloud's JWKS in all
  modes — the server has no private signing keys.
- Static NEXTCLOUD_OIDC_CLIENT_ID/SECRET are the preferred way to
  register the MCP server as that relying party; RFC 7591 DCR is a
  fallback when both are unset.
- Login Flow v2 layers per-user app-password acquisition on top — it
  governs the MCP→Nextcloud data leg, not the relying-party setup.

This commit reverts the inaccuracies introduced by 35c115e and reframes
the original `login-flow-v2.md` to match what the code does:

- login-flow-v2.md: revise "How It Works" to describe the MCP server
  as an OIDC RP + OAuth facade (not a standalone issuer); rename
  "OAuth Issuer Endpoints" → "OAuth Endpoints" with a note that those
  endpoints front Nextcloud OIDC; add NEXTCLOUD_OIDC_CLIENT_ID/SECRET
  to the required env vars with DCR documented as fallback.
- running.md: restore the static-creds Docker example (deleted in
  35c115e on the wrong reasoning that it was tied to the retired
  direct-OAuth-to-Nextcloud flow); rewrite the OAuth Mode section
  intro to describe the actual relying-party + facade architecture.
- configuration.md: fix Best Practices "For Production" to mention
  static creds as preferred / DCR as fallback; restore the .oauth
  Docker volume alongside data so DCR-registered MCP-client state and
  the encrypted app-password DB both persist.
- auth-flows.md: drop the note added in 35c115e that wrongly claimed
  the MCP server validates Bearer tokens against its own JWKS under
  Login Flow v2 — it validates against Nextcloud's JWKS in all modes;
  reword the Login Flow v2 "Key characteristics" bullet that called
  the MCP server "the OAuth authorization server".

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-04-30 02:29:01 +02:00
co-authored by Claude Opus 4.7
parent 35c115ead6
commit 319e82774e
4 changed files with 52 additions and 27 deletions
+15 -8
View File
@@ -636,7 +636,7 @@ uv run nextcloud-mcp-server --no-oauth \
Pick the mode that matches your deployment topology — there is no single "always" answer:
- **Multi-user / hosted** — use [Login Flow v2](login-flow-v2.md). MCP clients authenticate via OAuth 2.1 + DCR (no pre-configured client to manage); per-user Nextcloud access is stored as encrypted app passwords.
- **Multi-user / hosted** — use [Login Flow v2](login-flow-v2.md). The MCP server registers with Nextcloud OIDC via static `NEXTCLOUD_OIDC_CLIENT_ID` / `NEXTCLOUD_OIDC_CLIENT_SECRET` (preferred) or RFC 7591 DCR (fallback); MCP clients authenticate via OAuth 2.1 + PKCE; per-user Nextcloud access is stored as encrypted app passwords.
- **Internal multi-user** — Multi-User BasicAuth pass-through (clients send `Authorization: Basic` headers) is fully supported when users manage their own Nextcloud credentials.
- **Personal / self-hosted** — Single-User BasicAuth with a Nextcloud app password is the simplest production setup.
@@ -648,13 +648,20 @@ In all modes:
### For Docker
- Under Login Flow v2, mount the encrypted app-password store as a volume so per-user provisioning survives container restarts:
```bash
docker run -v $(pwd)/data:/app/data --env-file .env \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
```
(`TOKEN_STORAGE_DB=/app/data/tokens.db` in `.env`.)
- Use Docker secrets for sensitive values in production (`TOKEN_ENCRYPTION_KEY`, `NEXTCLOUD_PASSWORD`, etc.)
Mount **two** volumes for OAuth-mode deployments:
- `/app/.oauth` — DCR-registered MCP-client state (only used when DCR is the chosen registration path; harmless to mount otherwise).
- `/app/data` — encrypted app-password store under Login Flow v2 (`TOKEN_STORAGE_DB=/app/data/tokens.db`).
```bash
docker run \
-v $(pwd)/.oauth:/app/.oauth \
-v $(pwd)/data:/app/data \
--env-file .env \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
```
Use Docker secrets for sensitive values in production (`TOKEN_ENCRYPTION_KEY`, `NEXTCLOUD_OIDC_CLIENT_SECRET`, `NEXTCLOUD_PASSWORD`, etc.)
---