Skip to content

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