Skip to content

Security: SagarFieldElevate/Supaledger

Security

SECURITY.md

SupaLedger MCP Server — Security Overview

This document describes the security architecture of the SupaLedger MCP server. For questions or to report a vulnerability, contact teams@fieldelevate.com.


Table of Contents

  1. Authentication (OAuth 2.0)
  2. Authorization (Row-Level Security)
  3. Audit Logging
  4. Rate Limiting
  5. HIPAA Exclusion
  6. Data Minimization
  7. CORS Policy
  8. Transport Security
  9. Error Handling
  10. Responsible Disclosure

1. Authentication (OAuth 2.0)

The SupaLedger MCP server authenticates every request via OAuth 2.0 tokens issued by Supabase Auth.

Auth Flow

1. Claude redirects the user to SupaLedger's authorization endpoint
2. User signs in with their SupaLedger credentials
3. User selects an organization and reviews permissions on the consent screen
4. User clicks "Allow"
5. SupaLedger issues an authorization code
6. Claude exchanges the code for an access token (PKCE-protected)
7. All subsequent MCP tool calls include the access token in the Authorization header
8. When the token expires, Claude automatically refreshes it using the refresh token

Key Properties

Property Details
Protocol OAuth 2.0 with PKCE (Proof Key for Code Exchange)
Token type JWT (JSON Web Token)
Token lifetime 1 hour (auto-refresh)
Scope read:platform, read:accounting, read:crm (default for new connections)
Token storage Managed by the Claude client — not stored by SupaLedger
Password exposure Claude never sees the user's password — authentication happens on SupaLedger's hosted consent page

Custom Access Token Hook

A custom JWT hook injects the user's org_id into the token claims. This ensures that every database query is automatically scoped to the authorized organization, even if the Edge Function code has a bug.


2. Authorization (Row-Level Security)

SupaLedger uses PostgreSQL Row-Level Security (RLS) to enforce multi-tenant data isolation at the database level.

How It Works

  • Every table in the SupaLedger database has an org_id column.
  • RLS policies restrict all SELECT, INSERT, UPDATE, and DELETE operations to rows matching the authenticated user's organization.
  • The MCP server creates a Supabase client using the user's OAuth token, which carries the user's identity and org membership.
  • Even if the Edge Function code were compromised, RLS prevents cross-tenant data access.

Isolation Guarantees

Layer Protection
Application Edge Function validates org_id parameter against JWT claims
Database RLS policies enforce org isolation on every query
Auth context AsyncLocalStorage ensures no cross-request auth leakage in the Edge Function runtime

The MCP server uses AsyncLocalStorage (not module-level variables) to store the authenticated user's context. This prevents a timing vulnerability where one user's auth context could leak into a concurrent request.


3. Audit Logging

Every MCP tool call is logged to platform.mcp_audit_log.

What Is Logged

Field Description
tool_name Which tool was called (e.g., accounting_get_trial_balance)
org_id The organization the call was made against
user_id The authenticated user who made the call
timestamp When the call was made (UTC)
duration_ms How long the call took
success Whether the call succeeded or failed
error_code The SL-* error code, if the call failed

What Is NOT Logged

  • The actual data returned in tool responses
  • The user's prompt or Claude's response
  • Raw request/response payloads

Access Controls

  • The mcp_audit_log table is append-only: authenticated users can INSERT and SELECT their own logs, but cannot UPDATE or DELETE.
  • The anon role has no SELECT access to the audit log.
  • Organization admins can review their own organization's audit log.

4. Rate Limiting

Rate limits protect the SupaLedger database from excessive load and prevent abuse.

Scope Limit Window
Per user (all tools) 60 requests 1 minute
Per organization (all tools) 200 requests 1 minute

Behavior When Exceeded

When a rate limit is hit, the server returns:

{
  "content": [
    {
      "type": "text",
      "text": "Rate limit exceeded. Please wait a moment before making more requests."
    }
  ],
  "isError": true
}

Rate limits are enforced using counters derived from the mcp_audit_log table, ensuring accurate per-user and per-org tracking without additional infrastructure.


5. HIPAA Exclusion

Organizations flagged as HIPAA-regulated in SupaLedger are automatically excluded from MCP access.

Why

  • HIPAA requires a Business Associate Agreement (BAA) with any service that processes Protected Health Information (PHI).
  • When you use the MCP connector, your business data passes through Anthropic's infrastructure.
  • Anthropic does not currently offer a public BAA for Claude conversations.
  • To protect HIPAA-regulated organizations, SupaLedger blocks MCP access at the authorization level.

How

The verifyOrgAccess() function checks the organization's HIPAA flag before any tool executes. If the organization is HIPAA-flagged, the request is rejected with error code SL-AUTH-605 before any data is queried.


6. Data Minimization

All tools default to summary mode, which returns aggregated totals instead of individual records.

Mode What Is Returned PII Included
Summary (default) Totals by account type, bucket totals, contact name and type only No
Detail (on request) Individual accounts, invoices, bills, full contact records Yes (email, phone, address)

Summary Mode Protections

  • Financial reports: Totals by account type (e.g., "Total assets: $28,500"). No individual account names or transaction details.
  • Aging reports: Bucket totals (e.g., "2 invoices, $3,200 total"). No individual customer names or invoice numbers.
  • Contacts: Name, type, and company flag only. No email, phone, address, tax IDs, or notes.

Users must explicitly request detail mode to receive individual records. This ensures that the minimum necessary data passes through Anthropic's infrastructure for any given query.


7. CORS Policy

The MCP server restricts cross-origin requests to authorized domains.

Allowed Origins

Origin Purpose
https://claude.ai Claude web application
https://claude.com Claude web application (alternate domain)
http://localhost:6274 Claude Desktop local proxy

All other origins are rejected. Preflight OPTIONS requests return appropriate CORS headers for the allowed origins only.


8. Transport Security

Property Details
Protocol HTTPS (TLS 1.2+) — all traffic is encrypted in transit
Transport Streamable HTTP (MCP specification 2025-03-26)
Hosting Supabase Edge Functions (Deno runtime, isolated per invocation)
Service key protection Constant-time comparison (timingSafeEqual) prevents timing attacks

Protected Resource Metadata

The server exposes a /.well-known/oauth-protected-resource endpoint per RFC 9728, allowing MCP clients to discover the authorization server and required scopes before initiating the auth flow.


9. Error Handling

Error responses are designed to be informative for users without leaking internal details.

What Errors Include

  • A human-readable message explaining what went wrong
  • An SL-* error code for traceability and support
  • Suggested next steps when applicable

What Errors Never Include

  • Raw SQL errors or database error messages
  • Stack traces or file paths
  • Internal table names or column names
  • Other users' data or organization details

All errors are returned as successful MCP responses with isError: true, ensuring the Claude client can relay the message to the user gracefully.


10. Responsible Disclosure

If you discover a security vulnerability in the SupaLedger MCP server, please report it privately.

Email: teams@fieldelevate.com

Please include:

  • A description of the vulnerability
  • Steps to reproduce
  • The potential impact
  • Your contact information (optional, for follow-up)

We will acknowledge receipt within 48 hours and work to resolve confirmed vulnerabilities promptly. We will not take legal action against researchers who report vulnerabilities in good faith.

Do not publicly disclose vulnerabilities before we have had a chance to investigate and remediate.

There aren't any published security advisories