Distinguish login clients and upstream credentials

Each client_id belongs to a different authentication flow; register and configure them separately. Replace these example domains. Hub user tokens target the full server.public_url; administrator tokens target admin.public_url. They are not interchangeable.

Purpose Configuration Example callback registration
Employee CLI login to Hub CLI --client-id http://127.0.0.1:PORT/oauth/callback
Ordinary-user portal client_authorization.client_id https://hub.example.com/client-auth/auth/callback
Administrator browser login admin.client_id https://admin.example.com/auth/callback
Hub verifies identity with enterprise SSO auth.sso.upstream.client_id https://hub.example.com/sso/callback
User connects a business account backends[].credentials.oauth.client_id https://hub.example.com/client-auth/api/accounts/callback

backends[].oauth is Hub's service-account OAuth client_credentials, without a browser callback; credentials.oauth is personal user authorization. They cannot coexist. Hub required_scopes and upstream oauth.scopes are interpreted by their respective identity services and never automatically map or grant each other.

auth

Default built-in deployments configure LDAP and OIDC on the console’s Identity services page. Secrets are encrypted in managed storage and saving applies immediately. After the first UI save, database connection settings take precedence over auth.sso.upstream; YAML identity settings remain static and require restart.

Field Default / requirement Meaning
mode builtin in default templates Built-in accounts, with optional enterprise login. Advanced external verification uses external.
issuer Derived in built-in mode HTTPS origin of server.public_url plus /sso; no issuer environment variable. External mode requires a HTTPS issuer.
sso Optional Add an enterprise upstream or extra public clients. MCPBridge, portal and console registrations are provided by default. See built-in accounts and SSO.
enterprise_membership_max_age 24h Maximum age of verified enterprise membership, accepting 1m–720h. Expired membership requires sign-in or directory synchronization. Local accounts are unaffected.

Permission groups in managed storage use mcphub:permissions; source_groups maps stable LDAP/OIDC organization IDs. The permission-group API's permissions.scope_mode: derived compiles a selected-capability scope snapshot when saved; explicit retains manual scopes. Manage these permissions through the console or API rather than adding user grants to startup YAML. See groups and permissions.

Built-in mode requires managed storage. Hub checks user permissions and sessions; password resets, disabling and MFA enrollment revoke credentials. Ordinary password authentication has no MFA marker. The following discovery/JWKS requirements apply to external verification.

JWT requirements are: the issuer and signature must validate against this issuer; aud must contain the complete server.public_url including its path—when aud is a string it must equal public_url, and when aud is an array it must include public_url; sub must be non-empty; and exp must be present. nbf, when present, is checked too. Expiry, activation, and OIDC time comparisons allow 30 seconds of clock skew. The verifier becomes ready only after OIDC discovery succeeds, jwks_uri is an absolute HTTPS URL, and a reachable JWKS response contains at least one parseable, valid, asymmetric public verification key; symmetric oct keys and invalid or empty keys do not satisfy this condition. Before that first successful refresh, the MCP endpoint returns 503; after it is ready, a temporary discovery or JWKS refresh failure retains the last-known-good verifier. OIDC discovery and JWKS responses are each capped at 1 MiB.

For JWKS readiness, a usable key has no use or use: sig; if key_ops is present it includes verify; and an explicit alg matches a supported RSA, EC, or Ed25519 JWS algorithm declared by OIDC discovery. If discovery omits id_token_signing_alg_values_supported, RS256 is assumed. Unsupported or malformed keys in the same JWKS do not hide another usable key.

Scopes are read from both JWT scope and scp claims. scope accepts only a space-delimited string (including an empty string or JSON null); scp accepts a space-delimited string or a string array. The two claims are merged and deduplicated; array entries may not contain whitespace. Backend access uses all-of semantics: required_scopes: [a, b] requires the token to contain both a and b. If either is missing, that backend is absent from the token's catalog view and an identified direct call returns 403 insufficient_scope. A backend with no required_scopes is not scope-gated. Protected Resource Metadata reports the deduplicated union of all backend required scopes in scopes_supported.

External OIDC registration for the user CLI

These requirements apply when using an external issuer directly. With auth.sso, register public clients with MCPHub as described in the SSO guide. Give users the MCP URL, client ID and any required fixed callback port.

Register a public native OAuth client at that issuer with authorization-code and refresh-token grants, PKCE S256, and token-endpoint authentication method none. Allow the callback http://127.0.0.1:<port>/oauth/callback; use an arbitrary loopback port when the provider supports native clients, or register a fixed port and pass --callback-port 8765. Discovery must advertise PKCE S256. The issuer must issue a signed JWT access token with an audience containing the exact MCPHub public URL, including /mcp, plus sub, exp, and the required scopes. No client secret is needed on the user's machine.