Skip to main content
This page documents the security posture of the Profile MCP connector for developers, security reviewers, and compliance teams evaluating whether to approve Profile for use inside their organization.

Authentication

OAuth 2.1 with PKCE

All connector access uses OAuth 2.1 authorization code flow with PKCE (RFC 7636, S256 challenge method). No bearer tokens or API keys are exposed through the consent flow; only the user who signed in and consented can authorize access, and only the scopes they approved are attached to the issued token.

Dynamic Client Registration (DCR)

RFC 7591 Dynamic Client Registration is supported at the authorization server. MCP-compatible clients (Claude, ChatGPT, custom MCP servers) register themselves without out-of-band coordination. Registered clients receive their own client_id and are recorded as distinct connection grants so users can revoke them individually.

Identity provider

Authentication and token issuance are handled by Stytch Connected Apps. Profile does not implement its own OAuth authorization server; we act as the OAuth resource server, validating tokens issued by Stytch.

Discovery

Protected-resource metadata is served at /.well-known/oauth-protected-resource per RFC 9728. Authorization server metadata lives at the Stytch project domain per RFC 8414. On a 401 from a protected endpoint, clients receive a WWW-Authenticate: Bearer resource_metadata="..." header pointing at the discovery document.

Token lifecycle

  • Access tokens are signed JWTs with a one-hour expiry. The MCP server validates signature, expiry, issuer, and audience on every request using the JWKS published by Stytch.
  • Refresh tokens are issued alongside and can be exchanged for new access tokens without re-prompting the user, until the underlying grant is revoked.
  • Revocation is immediate on the Stytch side. Any attempt to refresh a revoked grant fails. Previously-issued access tokens remain technically valid until their one-hour natural expiry; see known limitations below.

Account isolation

Profile accounts map 1:1 to Stytch organizations. Every IDP-issued token carries the organization claim https://stytch.com/organization, and the Profile MCP server resolves the target account from that claim at request time. Concretely:
  • A token issued from a consent flow in Account A cannot read or mutate data in Account B, regardless of the IDs the caller supplies.
  • Tag and profile operations filter by the bound account at the database query layer, so cross-account access cannot be achieved by ID guessing.
  • Multi-account users must consent separately per account. One connection equals one account.

Scope enforcement

OAuth scopes are declared in the Stytch RBAC policy and carried on every issued token. The MCP server enforces scopes at the tool dispatch layer: each tool declares its required scope, and calls without the scope are rejected before any work is performed. The current scope set:
ScopeGrants
profiles:readRead profiles and behavioral summaries
profiles:writeCreate, update, delete profiles; send assessment invites
tags:manageFull CRUD and assignment on tags
account:readRead account metadata
account:writeModify account settings
Connected Apps issued through the MCP flow are capped at a manager-level role regardless of the consenting user’s Profile role. Admin-only operations are not exposed to connectors.

Billing enforcement

Requests from accounts with canceled, paused, or trial-expired billing status return 402 Payment Required at the middleware layer. This applies identically to connector access and the first-party web session.

Audit logging

Every mutating tool call (create, update, delete, assign, invite) writes to Profile’s standard audit log with the connector identified as the actor. Reads are not currently audited at the tool-call level but remain visible at the HTTP level in standard access logs.

Transport security

  • All traffic to the MCP endpoint uses HTTPS in production.
  • CORS on the /mcp and /.well-known/* endpoints is open (wildcard origin, no credentials) so browser-based MCP clients can reach them. All other credentialed endpoints restrict origins to the Profile web app.
  • The MCP endpoint does not use cookies; only Bearer tokens in the Authorization header.

Known limitations

Local token introspection and revocation latency

Access tokens are validated locally (signature, expiry, issuer, audience) rather than via a round-trip to Stytch. This is standard JWT practice and keeps latency low. The trade-off is that a revoked grant’s previously-issued access token remains technically valid until its natural expiry, up to one hour. Refresh tokens are blocked at revocation time, so the revoked connection cannot obtain a new access token once the current one expires. The one-hour window is the only gap. We have evaluated switching to network-backed introspection (which would be immediate) but the per-request Stytch API call adds measurable latency. For v1 the local-introspection tradeoff is documented and acceptable; we will revisit if customers require instant revocation for sensitive scopes.

Reporting a security issue

If you discover a security issue in the Profile MCP connector, email security@profilebehavior.com. Include reproduction steps and any relevant request IDs. We aim to acknowledge within one business day and provide a fix or mitigation plan within five business days for validated vulnerabilities. For general connector support and abuse reports, contact support@profilebehavior.com.

Standards referenced

  • OAuth 2.1 (draft) and OAuth 2.0 (RFC 6749)
  • PKCE (RFC 7636)
  • Dynamic Client Registration (RFC 7591)
  • OAuth 2.0 Authorization Server Metadata (RFC 8414)
  • OAuth 2.0 Protected Resource Metadata (RFC 9728)
  • JWT (RFC 7519) / JWS (RFC 7515)
  • Well-known URIs (RFC 8615)
  • Model Context Protocol specification