Skip to content

Releases: acartag7/mcp-sso

v0.2.3

Choose a tag to compare

@github-actions github-actions released this 12 Jul 10:52
Immutable release. Only release title and notes can be modified.
d7d7b33

npx mcp-sso init

Scaffolds a working zero-setup MCP server into a new directory:

npx mcp-sso init my-server && cd my-server && npm install && npm start
# → prints a one-time code; pair with: claude mcp add --transport http my-bridge http://127.0.0.1:3000/mcp

Generates package.json (exact-pinned deps, Node ≥24), server.ts (the recommended Origin-gate + console-pairing composition root), .gitignore, .npmrc (ignore-scripts=true), README.md. The bin is dep-free (node builtins only); fail-closed filesystem trust (atomic O_NOFOLLOW|O_EXCL|O_CREAT writes; target dir + ancestor chain validated no-follow).

Consumer-facing exports

NormRequest, NormResponse, assertCallbackPath, ensureStateDir (atomic — not the raw ensureGitignore), assertRealDir are now root-exported from mcp-sso — so a package consumer replicating the recommended patterns imports them instead of reimplementing them.

Fixes

  • destroySoon test-isolation flake (#66) — SDK /mcp calls in 3 test files switched from the inject-mock socket to a real loopback socket (the root cause, gone by construction).
  • CodeQL ReDoS hardening (#65) — two js/polynomial-redos regexes restructured; 15 js/missing-rate-limiting alerts triaged as false positives (the bridge rate-limits register/token via RateLimitPort/Bridge.guard).

Infrastructure

  • Renovate for github-actions updates — minimumReleaseAge: 15 days auto-enforced (the floor Dependabot can't do natively). Install the Renovate app to activate.
  • gitignore session-artifact dirs.

Full changelog: v0.2.2...v0.2.3

v0.2.2

Choose a tag to compare

@github-actions github-actions released this 11 Jul 08:47
Immutable release. Only release title and notes can be modified.
6c09205

v0.2.2

mcp-sso v0.2.2 brings the Google + generic-OIDC identity ports (live-verified), a security-hardening pass, the isMcpPath root-export, and live verification across three identity providers — plus an exchange-error diagnosability fix. Published from GitHub Actions via OIDC Trusted Publishing with Sigstore provenance — verify with npm audit signatures. No new runtime dependencies (still jose only).

New

  • Google + generic-OIDC identity portscreateGoogleRedirectIdentity and createGenericOidcRedirectIdentity (RedirectIdentityPorts, §17.6) for the upstream redirect orchestrator: discovery + manual endpoints, multi-audience id_token rejection, at_hash when present, iat required. The Google preset is pinned to https://accounts.google.com with hd (hosted-domain) gating checked against the signed hd claim (never the email domain) and email surfaced only when email_verified === true; the bridge subject is Google's stable numeric sub, never the email. Live-verified against Google sign-in (Claude Code + official SDK). (Shipped ahead of the earlier "v0.3" note.)
  • isMcpPath root-exportimport { isMcpPath } from "mcp-sso". The canonical /mcp Streamable-HTTP path check for the recommended onRequest Origin-gate (DNS-rebinding protection that runs before the bearer check, for every method). Handles the absolute-form request-target (POST http://host/mcp) that a raw === "/mcp" misses.

Hardened

  • Security hardening (two-pass assessment, no crit/high): the /mcp Origin-gate absolute-form bypass in fastify-sqlite → centralized isMcpPath; createBridgeConfig validate-then-spread TOCTOU/unknown-key leak → snapshot-once (#50); Cloudflare Access non-empty audience guard + token audit-after-mint ordering (#26).
  • Exchange-error diagnosability — the §17.11 upstream exchange-error cause (previously swallowed at a bare catch {}) is now logged operator-side on stderr (the client still gets generic server_error), via a hardened redactForStderr: never-throws, redacts-before-bounding, strips all line-breaking/terminal-control chars (C0, DEL, C1 incl. NEL/CSI, U+2028/U+2029), full credential-form redaction (Bearer, Authorization: scheme+creds, token=/secret=/code=/code_verifier=, opaque runs), and ReDoS-free.
  • Doc overclaims corrected (claims-vs-enforcement): access tokens are short-TTL ES256 valid until exp (not "single-use"); the api-key-gateway is a transparent proxy that can't stop a backend that echoes its own credential; the pairing code binds the session/operator; the JSONL audit sink doesn't fsync.

Live verification status (honest)

Production identity legs now live-verified: Cloudflare Access across five clients (Claude Code CLI, Codex CLI, claude.ai, ChatGPT, official SDK); Entra ID redirect flow (Claude Code, Claude Desktop); and Google sign-in (Claude Code + official SDK — bridge sub = Google's numeric sub; tokenless /mcp → 401 + WWW-Authenticate: resource_metadata; GOOGLE_HOSTED_DOMAIN outside-domain rejection → google_bad_hosted_domain, no token minted). Open owner-run rows (live Entra tenant deny-path, the gateway example against a real IdP, fresh-machine first-stranger run) are tracked in docs/live-verification.md. Not claimed: production-ready, audited, or a generic-OIDC second-provider live pass.

CI & supply chain

CodeQL SAST + Dependabot; OpenSSF Best Practices (passing) badge; repo onboarded to Engineering OS (tier S) with the process-guard artifact chain.

Moved to v0.3

GitHub identity preset · device authorization flow (RFC 8628) · CIMD (client_id_metadata_document — resequenced up: DCR is deprecated in the 2026-07-28 spec draft and the major clients already ship CIMD) · npx mcp-sso init.

Verify this release

npm i mcp-sso@0.2.2
npm audit signatures   # Sigstore provenance + registry signatures

(v0.2.2 supersedes v0.2.1 — same content plus the diagnosability fix; v0.2.1 published to npm fine but its GitHub Release page was lost to an immutable-releases tag conflict.)

Full changelog: v0.2.0...v0.2.2

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 12:16
Immutable release. Only release title and notes can be modified.
42bd8ad

v0.2.0 is the largest release since launch: eight feature sessions plus a security-hardening review cycle, every PR independently reviewed before merge. Published from GitHub Actions via OIDC Trusted Publishing with Sigstore provenance — verify with npm audit signatures.

New

  • client_credentials grant (the official MCP extension io.modelcontextprotocol/oauth-client-credentials) for headless / machine-to-machine callers: machine clients are provisioned out-of-band (provisionMachineClient — no HTTP provisioning surface by design), secrets stored as SHA-256 only and verified with uniform work, client_secret_basic + client_secret_post auth, no refresh tokens. The reserved mcc_ subject namespace is enforced across the whole token lifecycle — grant creation, code exchange, refresh, and verification (machine tokens mint a gty: "client_credentials" marker; the verifier requires sub == client_id and the marker). See the Machine-to-machine guide.
  • Upstream redirect orchestrator (createUpstreamRedirectFlow) — the full browser leg for redirect-based OIDC IdPs (Entra today): signed single-use flow cookie (__Host- profile), strict callback validation with fixed error mappings (IdP error text is never echoed), mandatory upstream PKCE, same-browser consent delivery. You no longer hand-write the riskiest OAuth code per deployment.
  • Entra group→scope authorization — map Entra group membership (GUID-keyed, display names rejected) to a per-user scope ceiling; group overage fails closed. The two-gate authorization model is documented in docs/authorization.md.
  • allowedScopes ceiling (IdP-agnostic) — identity-derived scope narrowing, intersected at consent preparation AND approval, so accumulated prior grants can never resurrect a revoked scope.
  • /store/mysql — pooled mysql2 store (row-locked rotation, fail-closed boot asserts for strict mode/collation/engine) and /rate-limit/redis (fixed-window, fail-open so a limiter outage never locks out auth). Both optional peer deps.
  • Audit reference sinksJsonlFileAudit (0600, append-only, log-injection-safe), https-only no-redirect WebhookAudit, combineAudit fan-out; nine new event names including failed-login visibility (identity.verify). Deployment guide: docs/audit-deployment.md.
  • Zero-setup quickstartloadOrCreateQuickstartSecrets auto-generates and persists signing material (0700/0600, fail-closed, never a silent ephemeral fallback) and console pairing (/identity/console-pairing) gives you real OAuth with no IdP: paste a one-time code from the server console. The old DEV_STUB_SUBJECT bypass is gone.
  • examples/api-key-gateway — a worked example of the most common production shape: SSO in front of a backend that only understands a static API key, with the key injected server-side and never visible to any MCP client. Rules documented in docs/gateway-deployment.md.

Hardened

  • Consent approval is fail-closed at both the adapter and the core: only an explicit approved=true approves — an absent or malformed field denies (#21, #23)
  • The hono adapter no longer reads X-Forwarded-For: a deployer-supplied clientIp extractor keys the rate limiter, so an attacker-chosen header can't select its own bucket (#21)
  • MemoryStore now matches sqlite/mysql on token-hash collisions (no silent overwrite), and the collision tests moved into the shared conformance suite all stores must pass (#21)
  • createBridgeConfig rejects unknown keys, so a secret parked on the config input can never reach the frozen public config (#13)
  • The example /mcp validates Origin pre-parse and method-agnostic (spec-MUST DNS-rebinding defense) (#15)
  • The identityHeader-mode nonce residual is now documented at every surface a deployer reads: in header mode the fronting proxy owns id_token replay protection (#22)

Live verification status (honest)

DCR/OAuth mechanics are verified against curl, the official MCP SDK client, Claude Code, and claude.ai. The production identity legs (live Entra tenant, real-browser redirect flow, the gateway example against a real IdP) are tracked as open owner-run checklists in docs/live-verification.md — rows flip only when actually run.

Moved to v0.3

Device authorization flow (RFC 8628), CIMD, generic-OIDC/GitHub/Google identity presets, npx mcp-sso init.

Verify this release

npm i mcp-sso@0.2.0
npm audit signatures   # Sigstore provenance + registry signatures

Full changelog: v0.1.1...v0.2.0

v0.1.1

Choose a tag to compare

@github-actions github-actions released this 04 Jul 20:30
Immutable release. Only release title and notes can be modified.

v0.1.1 — adapter identity-error-mapping hotfix

Patch release. No new features, no port or contract changes — this ships the
identity-error-mapping fix from #1
to npm users on 0.1.0.

What's in this release

When an identity port rejects a subject during /authorize (Entra / Cloudflare
Access allowlist miss, or any throw from identity resolution), the response is
now a spec-correct OAuth error across fastify, express, and hono:

  • Identity rejection ⇒ 401 access_denied with the §9.5 body (was a 500
    internal_error envelope on Express/Hono, and a 401 with a framework-shaped
    body on Fastify).
  • Non-OAuth throws ⇒ 500 with a non-leaking top-level error body. The
    thrown message is no longer echoed — a thrown Error("…") during identity
    resolution previously surfaced in the response body on Express/Fastify.
  • Identity-error redirects are ignored pre-validation — the response is
    delivered directly, with no Location header.

The shared adapter test matrix now covers all three cases (HF.1 rejected
identity, HF.2 OAuthError throw, HF.3 non-OAuth Error throw → non-leaking
500) across every framework. Full matrix documented in
docs/verification.md.

Should you upgrade?

Yes if any of your /authorize requests can be rejected by your identity port
(allowlists, Conditional Access, IdP-side gating). If identity resolution can
never throw in your deployment, behavior is unchanged. Contracts touched:
§9.3, §9.5, §9.6 in
docs/contracts.md.

npm i mcp-sso@0.1.1

Not in this release

Phase 5 (/store/mysql, Redis-backed RateLimitPort, Captatum dogfood) and the
v0.2 feature set (Entra groups, client_credentials, device flow, generic OIDC,
CIMD, audit sinks, console pairing) remain on the roadmap — see the
README.

Full changelog: v0.1.0...v0.1.1

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 04 Jul 09:58
Immutable release. Only release title and notes can be modified.

OAuth in your MCP server, instead of an API key in your client's config

First release. mcp-sso is a spec-correct OAuth 2.1 resource-server verifier plus a small AS-lite bridge for remote MCP servers: it speaks DCR + PKCE + consent to MCP clients (Claude Code, claude.ai, ChatGPT, Cursor) while your identity provider — Cloudflare Access, Microsoft Entra ID, or any OIDC provider — stays the identity source of truth. The bridge mints its own audience-bound tokens; upstream IdP tokens never pass through.

npm install mcp-sso

What's in v0.1.0

  • Resource-server verifier — RFC 9728 Protected Resource Metadata (root + path-inserted), WWW-Authenticate challenges, scope step-up, fail-closed audience validation.
  • AS-lite bridge — RFC 7591 DCR (stateless or stored-client mode), PKCE S256, consent (approve/deny), refresh-token rotation with family replay-detection, RFC 6749 §5.2 wire errors, RFC 9207 iss.
  • Identity ports — Cloudflare Access, Microsoft Entra ID (multi-tenant, nonce-bound), and a dev-only stub for local testing.
  • Framework adapters/fastify, /express, /hono.
  • Storesnode:sqlite (recommended zero-ops production default) and an in-memory store, sharing one conformance suite.
  • Supply chainjose is the only runtime dependency; every pin is ≥15 days old; CI actions are SHA-pinned; this release itself is published via npm Trusted Publishing (OIDC, no token) with --provenance.
  • A published threat model (docs/threat-model.md) and full contract surface (docs/contracts.md).
  • Verified end-to-end: the official MCP SDK client, Claude Code, and a claude.ai custom connector have all completed the full register → authorize → consent → token → call → refresh → revoke flow against the runnable example in examples/fastify-sqlite.

Not yet in this release

Console-pairing identity (zero-IdP-setup onboarding), GitHub/Google identity presets, quickstart auto-keygen, CIMD, and the client_credentials grant are tracked for a future release — see the Roadmap section in the README.

Docs

Full Changelog: https://github.com/acartag7/mcp-sso/commits/v0.1.0