Security Considerations for MetaMCP's OIDC Implementation: A Complete Guide
MetaMCP enforces PKCE by default for all OIDC flows, uses auto-discovery to eliminate endpoint misconfiguration, and provides runtime feature flags to disable basic authentication and granularly control user registration, creating a defense-in-depth SSO architecture.
MetaMCP, the open-source AI tool management platform from metatool-ai/metamcp, integrates OpenID Connect (OIDC) as a first-class authentication provider using the better-auth library. Understanding the security considerations for MetaMCP's OIDC implementation is essential for administrators deploying single sign-on in production, as the platform combines modern OAuth 2.0 best practices with flexible runtime controls that adapt to varying threat models.
Core OIDC Security Architecture
PKCE Enforcement and Authorization Flow Protection
MetaMCP's OIDC implementation mandates Proof Key for Code Exchange (PKCE) to protect against authorization code interception attacks. In apps/backend/src/auth.ts, the pkce parameter defaults to true unless explicitly disabled via the OIDC_PKCE environment variable set to "false" (lines 44–45).
// apps/backend/src/auth.ts – PKCE configuration
pkce: process.env.OIDC_PKCE !== "false", // Defaults to true for security
This default behavior ensures that even if administrators omit PKCE configuration, the authorization code flow remains protected against malicious actors intercepting codes on public clients or compromised networks.
Auto-Discovery and Endpoint Validation
The implementation leverages OpenID Connect Discovery to automatically retrieve provider metadata, eliminating manual endpoint configuration errors. The discoveryUrl parameter reads from OIDC_DISCOVERY_URL (line 45), while the authorizationUrl explicitly uses OIDC_AUTHORIZATION_URL to work around a known limitation in better-auth (line 46).
// apps/backend/src/auth.ts – Endpoint configuration
discoveryUrl: process.env.OIDC_DISCOVERY_URL,
authorizationUrl: process.env.OIDC_AUTHORIZATION_URL, // Required by better-auth
By validating HTTPS-only discovery documents and enforcing explicit authorization endpoints, MetaMCP prevents man-in-the-middle attacks that could redirect authentication flows to attacker-controlled servers.
Scope Restriction and Minimal Data Access
MetaMCP follows the principle of least privilege by requesting only essential scopes. The default scopes array includes openid, email, and profile (line 43), providing sufficient identity information without requesting unnecessary permissions that could expand the attack surface in case of token leakage.
// apps/backend/src/auth.ts – Scope configuration
scopes: (process.env.OIDC_SCOPES || "openid email profile").split(" "),
Runtime Security Controls and Configuration
Disabling Basic Authentication
Administrators can enforce OIDC-only authentication by disabling basic email/password login. The DISABLE_BASIC_AUTH flag in apps/backend/src/lib/config.service.ts (lines 36–44) blocks traditional authentication routes when enabled, preventing fallback to weaker credential-based authentication in SSO-mandated environments.
Fine-Grained Sign-Up Restrictions
MetaMCP provides distinct controls for user registration through config.service.ts:
DISABLE_SIGNUP: Blocks all UI-driven account creation (lines 5–12)DISABLE_SSO_SIGNUP: Specifically prevents new account creation via OIDC/OAuth while allowing existing users to authenticate (lines 21–28)
The authentication middleware in apps/backend/src/auth.ts implements these checks in user creation hooks (lines 35–57), throwing explicit errors when registration attempts violate the current policy:
// apps/backend/src/auth.ts – Registration guard implementation
const isSsoRegistration =
context?.path?.includes("/callback/") ||
context?.path?.includes("/oauth/") ||
context?.path?.includes("/oidc/");
if (isSsoRegistration) {
if (isSsoSignupDisabled) {
throw new Error("New user registration via SSO/OAuth is currently disabled.");
}
} else {
if (isSignupDisabled) {
throw new Error("New user registration is currently disabled.");
}
}
Environment Variable Hygiene
All OIDC credentials load exclusively from environment variables at runtime. The configuration in auth.ts (lines 38–51) conditionally registers the OIDC provider only when both OIDC_CLIENT_ID and OIDC_CLIENT_SECRET are present, preventing partial configuration that could lead to authentication bypasses.
Required environment variables include:
OIDC_CLIENT_IDOIDC_CLIENT_SECRETOIDC_DISCOVERY_URLOIDC_AUTHORIZATION_URL
Source: README.md OIDC configuration section (lines 62–73) and example.env.
Session Management and Cookie Security
MetaMCP configures better-auth with security-focused session parameters in apps/backend/src/auth.ts:
- Session Expiry: Tokens expire after 7 days (
session.expiresIn, line 112) - Token Rotation: Sessions refresh daily (
session.updateAge, line 113) - Cross-Subdomain Support: Cookies work across subdomains when enabled (
crossSubDomainCookies.enabled, lines 124–126)
These settings limit the window for session hijacking while maintaining usability in multi-subdomain deployments.
Configuration Examples for Secure Deployment
Enabling OIDC with PKCE
# .env configuration
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_DISCOVERY_URL=https://auth.example.com/.well-known/openid-configuration
OIDC_AUTHORIZATION_URL=https://auth.example.com/oauth2/authorize
OIDC_PKCE=true
OIDC_SCOPES=openid email profile
Locking Down Registration
# Disable all sign-ups except existing OIDC users
DISABLE_SIGNUP=true
DISABLE_SSO_SIGNUP=false
DISABLE_BASIC_AUTH=true
Summary
MetaMCP's OIDC implementation provides enterprise-grade security through multiple defensive layers:
- PKCE enforcement protects authorization codes from interception attacks by default
- Auto-discovery with HTTPS validation prevents endpoint misconfiguration and man-in-the-middle attacks
- Runtime feature flags allow administrators to disable basic auth, UI sign-up, or SSO registration without code changes
- Secure session management with 7-day expiry and daily rotation limits exposure from stolen tokens
- Environment-only secrets ensure credentials never leak through source control
By leveraging these controls in apps/backend/src/auth.ts and apps/backend/src/lib/config.service.ts, operators can deploy OIDC authentication that aligns with zero-trust principles while maintaining flexibility for diverse organizational requirements.
Frequently Asked Questions
Is PKCE mandatory in MetaMCP's OIDC implementation?
PKCE is enabled by default and effectively mandatory for secure deployments. While the OIDC_PKCE environment variable can explicitly disable it by setting the value to "false", the default configuration in apps/backend/src/auth.ts (line 44) sets pkce: process.env.OIDC_PKCE !== "false", ensuring protection against authorization code interception attacks unless an administrator explicitly opts out.
How can I disable basic authentication when using OIDC?
Set the DISABLE_BASIC_AUTH environment variable or use the configuration service to enable this flag. When active, MetaMCP blocks all email and password authentication routes, forcing users to authenticate exclusively through the configured OIDC provider. This prevents fallback attacks where users might bypass SSO using local credentials. The check occurs in the authentication middleware defined in apps/backend/src/auth.ts.
What environment variables are required for secure OIDC configuration?
At minimum, you must provide OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_DISCOVERY_URL, and OIDC_AUTHORIZATION_URL. Optional but recommended variables include OIDC_PKCE (set to true), OIDC_SCOPES (defaults to openid email profile), and OIDC_PROVIDER_ID (defaults to oidc). These are loaded at runtime from apps/backend/src/auth.ts and should never be committed to source control, as demonstrated in the example.env template.
Can I prevent new user registration while keeping OIDC login active for existing users?
Yes, by setting DISABLE_SSO_SIGNUP to true while keeping DISABLE_SIGNUP and DISABLE_BASIC_AUTH configured according to your needs. This configuration allows existing users to authenticate via OIDC but blocks the creation of new accounts through SSO, effectively enforcing a closed user base. The registration guard in apps/backend/src/auth.ts (lines 35-57) distinguishes between SSO and UI registration attempts to enforce these policies independently.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →