Security at Surgemesh
Surgemesh encrypts channel credentials at rest and never returns them, shows API keys only once, gives every key explicit scopes and optional brand restrictions and expiry, and rate limits requests per IP, per key and at the edge.
Summary
| Control | Status |
|---|---|
| Channel credentials encrypted at rest, never returned | Live |
| Disconnecting a channel erases its credentials | Live |
| API keys shown once; listings show only a prefix | Live |
| Scoped keys (read, write, admin) with brand restrictions and expiry | Live |
| Immediate key revocation | Live |
| Rate limits per IP, per key and at the edge | Live |
| Public-HTTPS-only media URLs | Live |
| Cancel queued deliveries with automatic refund | Live |
| Signed webhooks (HMAC-SHA256, 5-minute replay window) | Coming |
Channel credentials
The Meta access tokens and page or Instagram user ids you send in credentials are encrypted at rest and never returned by the API. GET /v1/channels shows only metadata such as network, label and connected. DELETE /v1/channels/{id} disconnects the channel and erases its stored credentials. Connecting and disconnecting channels requires the admin scope.
API keys
- Shown once: the full key appears only in the response that creates it.
GET /v1/keysreturns aprefix, never the key, so a lost key must be replaced. - Scoped: each key carries a list of scopes from
read,writeandadmin. - Brand-restricted: a key can be limited to specific brands, so an agent working for one client cannot touch another. A brand-restricted key cannot mint an all-brands (
"*") key. - Expiring: set
expires_at; expired keys get401 key_expired. - Revocable:
DELETE /v1/keys/{id}revokes a key. - Bounded: at most 50 active keys per account.
Tenant and brand boundaries
Each account is a separate tenant with its own brands, channels, keys and usage. Every post must target channels that belong to its brand_id. Keys used outside their brands receive 403 brand_not_allowed, and ids that do not resolve return 404 (brand_not_found, channel_not_found or not_found).
Input validation
Every request is validated. Bodies must be JSON (415 json_required otherwise) and within size limits (413 payload_too_large). Media must be referenced by public HTTPS URLs; other URLs are rejected with 422 invalid_media_url. Invalid fields return 400 invalid_field naming the field.
Rate limits and abuse controls
The API allows 60 requests per minute per IP address and 120 per minute per key, plus a burst limit at the edge. Signup is limited to 3 per IP address per day. Exceeded limits return 429 with a Retry-After header. Combined with required idempotency keys on post creation and optional max_price_usd ceilings, a runaway agent loop cannot multiply posts or overspend on surges.
Operator control
Queued deliveries can be cancelled with DELETE /v1/posts/{id} before they publish, and the cancelled amount is refunded. GET /v1/usage exposes a ledger of every topup, charge, refund and grant, so operators can audit what agents spent.
Webhooks (coming)
Signed webhooks are coming and are not available in the beta. Payloads will be signed with HMAC-SHA256 and carry a 5-minute replay window.
Payments
Payments are not enabled during the beta. When they are, credit top-ups use x402 with USDC on Base. Surgemesh verifies and settles each payment through an x402 facilitator into Stripe custody, and each settled on-chain transaction can credit only once, so a retried top-up cannot buy a pack twice. Card payments are coming soon.