Early bird discounts live! Claim your offer

MCP Security

How OAuth connections and personal access tokens are scoped, revoked and audited, and what to do when a credential leaks.

Threat model

The MCP server accepts two credentials over HTTPS — an OAuth 2.1 access token the creator granted by signing in, or a personal access token — and runs the request inside the same tenancy boundary as the REST API. The most common risks are:

  1. A token leaking into LLM conversation logs — Claude, Cursor, and ChatGPT Desktop all log the session. A developer sharing a transcript can leak an Authorization header if the client logs it.
  2. Over-privileged credentials — minting a personal access token with every ability ticked, or connecting over OAuth from an account with more reach than the task needs, makes a leak costly.
  3. Accidental writes — an eager agent executing a tool that turns out to mutate state.

We design for the first two and accept the third as a prompt-engineering issue, with the server marking every tool that changes or deletes data as destructive so a client asks before running it. Below are the controls.

OAuth connections

  • Consent, not a pasted secret. The creator signs in to the dashboard, with two-factor and passkeys applying as usual, and reads a consent screen that names the client, the signed-in account, the reach of the connection and where they will be sent back to. Nothing is copied to disk.
  • Short-lived access. An access token lasts one hour. The refresh token lasts 30 days from its last use and is rotated on every renewal; presenting a spent one is refused, so a copied refresh token dies the moment the client renews.
  • Public clients with PKCE. Every client registers dynamically as a public client and must present an S256 code challenge; there is no client secret to leak.
  • One scope, the creator's own reach. The connection acts as the creator on the team they were working in, with every ability their role grants there, inside the same tenant boundary as the dashboard. A connection that should be narrower is a personal access token instead.
  • Disconnect ends it. Disconnecting the server inside the client discards its tokens; the access token expires within the hour and the refresh token cannot be renewed once discarded.

Personal access tokens

Prefix scanning

All tokens start with sbt_. GitHub's secret scanning treats this as a Subscriby-specific credential and alerts on push. If a token lands in a public repo, we usually find out before the creator does.

Mandatory team scope

Every token carries scope:team:<uuid> frozen at mint time. A leaked token is constrained to exactly one team — it can never pivot. Project-level scope:project:<uuid> tuples tighten this further.

Minimum-privilege defaults

The token-minting UI pre-selects no abilities and makes you opt into each. This is deliberate friction — most tokens only need two or three abilities.

Expiry

Personal access tokens do not expire automatically. Long-lived "production" tokens (Zapier, CI, ops dashboards) should be rotated manually on your own cadence — revoke the old token in the dashboard, mint a fresh one with the same abilities, and update the client config.

Revocation

Revoke a token from Settings → API Tokens → Revoke. Revocation is immediate; any client still holding the token gets AUTHENTICATION_REQUIRED on its next call.

Audit trail

Every MCP tool invocation is recorded in the activity log with the invoking user as the causer, the subject entity, and an actor_kind field that distinguishes MCP calls from dashboard and REST actions. Review what an agent did in Settings → Activity Log, or read the log over the API via the get_activity_log MCP tool or GET /v1/activity REST endpoint.

Leaked-credential playbook

For a personal access token:

  1. Revoke the token in Settings → API Tokens.
  2. Review the audit trail for the last 24 hours under that token's causer_id.
  3. If writes happened you didn't authorise, contact support with the token ID (not the secret).
  4. Mint a replacement token with the same abilities.
  5. Update the client config (Claude Desktop, Cursor, etc.) with the new token.

For an OAuth connection whose client or device you no longer trust: disconnect the server inside the client, change your Subscriby password (which signs out every browser session), and review the audit trail the same way. Access the connection still held expires within the hour.

How is this guide?

On this page

Subscriby is a product designed by you — for you.

No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request