SECURITY
On Belay is the governance layer between your team and every integration Claude can access. Credentials are encrypted at rest, decrypted only at the moment of a proxied call, and never exposed to the AI itself.
Every API key and OAuth token your organization connects — Shopify, HubSpot, Stripe, Slack, and 80+ others — is encrypted before it touches the database.
Encryption uses XSalsa20-Poly1305 (libsodium secretbox), a widely trusted authenticated cipher used in financial and security applications. The process works in three layers:
A 32-byte (256-bit) master encryption key lives in the server environment. It never touches the database and is never committed to code.
From the master key, a unique sub-key is derived for each organization using HKDF-SHA256. A breach of one org's data does not help decrypt another's.
Each credential is encrypted with the org-specific key plus a random one-time nonce. Even two identical API keys produce different encrypted blobs.
When Claude needs data from a third-party tool, it doesn't call that tool directly. It calls On Belay's proxy. On Belay checks permissions, retrieves and decrypts the credential, forwards the request, and returns the response. Claude only knows the operation name and path — never the raw API key.
Proxy call flow
Bearer token verified (JWT, PAT, or fieldset token)
Subscription status checked — lapsed orgs are blocked
Rate limits enforced per user and per org
Group access verified — integration + operation scope
Enforce mode validates exact operation against permit list
Credential decrypted; expiring OAuth tokens refreshed silently
Response cache checked before hitting live API
Request forwarded with correct auth headers (30s timeout)
Response returned to Claude
Full call logged to immutable audit trail
OAuth 2.0 redirect flow. No password stored. Name and profile photo pulled from Google automatically.
Passwords are run through bcrypt — a one-way mathematical scramble — before storage. Even database access can't reverse them.
After sign-in, a signed JWT is issued and carried silently on every request. Contains only your user ID. Invalidated on sign-out.
Users can generate PATs to connect Claude or other AI tools without the browser OAuth flow. PATs are stored as one-way SHA-256 hashes — the raw token is shown exactly once at creation. If lost, it cannot be recovered; a new one must be generated.
Connecting an integration makes it available. Access is granted per group, with two enforcement modes.
The group can use the integration. All operations are allowed. Best for trusted roles like org owners.
The group can only perform specific listed operations from a catalog of 1,282 pre-defined actions. Any unlisted call is blocked and logged. Method and path are validated exactly — a read-operation name cannot slip through a destructive write.
If a user belongs to multiple groups and at least one enforces, enforce mode applies. Permitted operations become the intersection of the enforcing groups — only what every enforcing group allows. The most restrictive configuration always wins.
When Claude encounters a request it classifies as medium or high risk, it pauses and submits an approval request rather than acting. Admins review, approve, or deny each request — including risk level and a suggested permission change.
1
Claude logs what was asked, who asked, and the risk level.
2
Admins see pending requests in the dashboard or Slack with a red badge.
3
Approved, denied, or escalated — every decision is logged immutably.
Every meaningful action writes an immutable record: timestamp, org, user, action type, target, metadata, and session ID. Nothing is deleted or overwritten.
Event
proxy.call
Event
proxy.blocked
Event
approval.requested
Event
integration.connect
Every record captures: who made the call, what operation was requested, which integration, response status, and a link to the Claude session. Use the Activity page to trace root cause — blocked calls show the exact reason, rate-limit events identify which user or pipeline hit the ceiling.
Layered rate limits prevent runaway usage at the user, org, and pipeline level.
Proxy — per user
300 req / minute
Proxy — per org
1,500 req / 5 minutes
Fieldset — per 5 minutes
400 req / 5 minutes
MCP tools — per user
300 req / minute
MCP tools — per org
2,000 req / hour
Invites — per org
10 / hour
When a limit is hit, On Belay returns HTTP 429 with a Retry-After header. Every limit hit is written to the audit log. The rate limiter uses Redis as its primary store; if Redis is unavailable it falls back to Postgres. If both fail, the system fails open — calls are allowed rather than blocked — so a database hiccup never takes down a live workflow.
A short-lived state token (15-minute expiry) is created before every OAuth redirect and verified on return — prevents attackers from injecting false approvals.
Shopify connections verify a cryptographic signature on the callback, ensuring the response hasn't been tampered with.
Salesforce, Acumatica, and NetSuite instance URLs are validated before the redirect to prevent open-redirect attacks.
Expiring tokens are refreshed silently before each proxy call. If refresh fails (token revoked at source), the integration is flagged and blocked until reconnected.
On Belay acts as an MCP (Model Context Protocol) server. When Claude connects, it gains a structured understanding of who the user is, what teams they belong to, and what tools they are permitted to use — nothing more.
The access token issued to Claude is stored as a one-way hash — the raw token cannot be extracted from the database. Claude only sees data for the authenticated user's organization.
Every MCP tool call is scoped to the requesting user's organization. Cross-org data access is architecturally impossible through the MCP interface.
We're happy to walk through our architecture, provide additional documentation, or discuss specific compliance requirements.
hello@onbelay.ai