Enable client authorization

The default templates already enable the personal portal and automatically register mcphub-portal and MCPBridge clients. No separate identity service or manual registration is required. The custom registration requirements below apply to advanced external authentication; in built-in mode, configure explicit registrations only when changing client IDs, callbacks or resource URLs.

Enable client_authorization.enabled, configure its portal client_id, and enable the managed database. SQLite and a single MCPHub instance with PostgreSQL use the same authorization lifecycle. Fresh storage uses schema 10; retain the database and encryption key across restarts.

Register the portal callback https://hub.example.com/client-auth/auth/callback. The portal is served on the MCP gateway origin, separately from the administration listener. The CLI and portal must receive JWT access tokens for the full MCP resource URL with the same issuer + sub. Pairwise subjects from different OIDC clients require an identity-provider configuration that gives these clients a consistent subject; email matching is not used. An optional portal client secret stays on the server through client_secret_env.

This is a fragment to add at the root of an existing complete YAML file, not a replacement configuration. Set client_id to the registered portal client's ID.

client_authorization:
  enabled: true
  client_id: mcphub-portal
  require_client_grant: false
  max_grant_ttl: 8h

Restart a directly run binary. For Compose, add the fragment to the mounted deploy/config.remote-postgres.yaml, then run docker compose -f deploy/compose.postgres.yaml up -d --force-recreate mcphub in the original deployment environment. Register a separate public employee CLI client with the external OIDC requirements, including PKCE, callbacks and MCP audience. Publish one explicitly classified read tool and grant its required scopes before asking employees to run setup; empty backends: [] or published_tools: [] do not create selectable tools.

Set require_client_grant: true on selected backends or HTTP tool groups, or globally to require it everywhere. Global and endpoint requirements are combined with OR. Existing connections without --client retain access only to compatible endpoints; authenticated initialization does not expose strict endpoints. Global portal settings are static process configuration and require a restart. Endpoint settings use the existing managed configuration governance.

Users confirm their own grants in the portal. Administrators can inspect and revoke grants but cannot consent as another user. An external issuer also needs public OAuth client registration; with SSO bridging, register local public clients according to the SSO guide.

client_authorization

The user portal and client grants require admin.enabled: true and managed database storage. Every field in this section requires a restart. See the administrator workflow for registration and activation.

Field Default Description
enabled false Enables the user portal and client grants. Enabling admin alone does not enable this feature.
client_id none Required when enabled; the ordinary-user portal's OAuth client, separate from CLI/admin clients.
client_secret_env none Optional confidential-client secret variable name. With Hub SSO the portal is a public client and this must be unset.
require_client_grant false Global enforcement, ORed with the endpoint setting. Either being true requires this module to be enabled.
max_grant_ttl 8h Maximum user grant lifetime, from 1m to 8h.

Client credentials and connection boundaries

With strict client authorization, single Bridge/Broker grants use the user token plus an opaque MCPHub-Grant. Standard OAuth sessions bind internal service grants server-side and require only the bearer token. Effective scopes are their intersection. Issuer, user, resource, endpoint UID, expiry, tool publication, resource rules and live policy are checked on every request. Scope/target changes, disabled or recreated endpoints and changed HTTP tool execution semantics require fresh consent. New tools are never automatically added to an existing grant. No grant or user token is forwarded to upstream systems.

Private sockets/named pipes, OS peer checks and independent IPC credentials isolate paired entries from other OS users. They do not prove application identity or isolate hostile processes running under the same OS account. Release publishing requires the native Windows CLI test suite, including Broker IPC, on x64 and ARM64; macOS/Linux use Unix sockets with OS peer checks. See the design and validation record.

New deployment templates set client_authorization.require_client_grant: true: a user token identifies the user; business tools also require a browser-confirmed ClientGrant. The builtin issuer advertises device authorization metadata; its device_authorization_endpoint is not an upstream identity endpoint. See the user manual.

Register standard OAuth clients in Operations, or set require_consent: true and name under auth.sso.clients[]. See the administrator guide for multiple service grants, drafts and backup commands.

With the built-in issuer, user sign-in and client consent happen on one web page. Local, SSH and container Agents can use this flow without a browser callback to the Agent's machine. Run both commands under the same operating-system user and private MCPHUB_HOME directory:

mcpbridge pair start --server https://hub.example.com/mcp --profile work --name "Project Agent" --json
mcpbridge pair finish --request pr_example --wait --json
mcpbridge connect --profile work --client ci_example

Replace the request and client IDs with the actual results. Show the user verification_uri_complete and user_code. After comparing the code, the user signs in with local accounts, LDAP or OIDC, selects a service, tools, resource restrictions and duration, then approves. No tools are selected by default; write access is off. Without --wait, finish checks once. pending_user requires approval; ready means private credentials were saved and MCP connectivity was checked. The default requested maximum is 1 hour, capped by the gateway. Requests expire after 5 minutes and polling starts at 5 seconds. --ttl takes seconds (at least 60); narrow requests with --endpoint and repeated --tool / --scope.

For Agents without command execution, use these stdio arguments:

["connect", "--server", "https://hub.example.com/mcp", "--profile", "work", "--name", "Project Agent", "--interactive-auth"]

The session initializes immediately with only mcpbridge_auth_start and mcpbridge_auth_status. Start reuses the same unexpired request; status may collect and save credentials and check connectivity. Respect the returned interval. Refresh tools after ready. If the Agent does not support notifications/tools/list_changed, reconnect using the returned connect --profile … --client … command. Failed business calls are never queued or retried automatically. Reauthorization after expiry or revocation is explicit.

The pairing page preserves your service, tools, duration and resource restrictions when switching languages. Only eligible write access is shown. If a code is invalid or expired, start a fresh request in your Agent and enter its new code on the same page. Invalid resource restrictions do not end the request; correct the form and submit again.

Each pairing grants one service and tool capability; use existing setup for prompts, resource URIs or subscriptions. Current groups and the confirmed grant both restrict access, and new tools never expand old grants. Private credentials remain inside MCPBridge. Never copy tokens to an Agent. Failure preserves an existing working profile; choose a new profile for another user or server. Pure external issuers retain PKCE login and setup.