Security

What protects your data, specifically.

Written from the code rather than from a checklist. Everything below can be verified against how the service actually behaves, and the things we do not have are named rather than omitted.

Message contents are never written to disk

A published message is delivered to connected clients and then it is gone. We count messages and bytes per app, per time bucket, to enforce quotas and draw usage charts. We do not record the payloads, and we do not record the channel names they went to. There is nowhere in the system a message body is stored, so there is nothing to leak, subpoena or lose.

Encryption in transit

Everything is TLS: https:// for the API and dashboard, wss:// for sockets. HSTS is set with a one-year max-age including subdomains, so a browser that has seen us once will refuse to downgrade.

Encryption at rest

The database is encrypted at rest by our provider. On top of that, the one secret the system must be able to recover — your app’s secret key, which is needed to verify a channel-authorization signature — is encrypted at the application layer with AES-256-GCM under a key held outside the database. A copy of the database on its own does not yield a working key.

How credentials are stored

  • Passwords — hashed with argon2id at the OWASP 2024 baseline (19 MiB memory, two passes). The parameters are compiled in rather than configurable, so weakening them needs a code review and not an environment variable.
  • API keys — only a SHA-256 hash is stored for verification. Public keys are public by design; secret keys additionally carry the encrypted copy above.
  • Session tokens and personal access tokens — hashed. The raw value exists once, in the response that created it, and is never recoverable.

Access control

  • Channels carry their own rule. A name beginning private- or presence- cannot be joined without a signature from your backend. There is no second permission model to fall out of step with the first.
  • Public keys are bound to origins. A browser connection is accepted only from hosts on your app’s allow-list, matched on host including the port.
  • Personal access tokens are scoped and expire. They reach an explicit allow-list of control-plane routes and nothing else, carry only the scopes chosen when they were minted, and require an expiry capped at 90 days.
  • Rate limits and quotas are enforced at the gateway, per app and per address, so one account cannot spend another’s capacity.

Infrastructure

The database runs on Amazon Web Services in US East. The gateway and its Redis run on Railway in US East. This website and the documentation are served by Vercel from edge locations close to the reader; your data is not stored in them. Redis holds counters and pub/sub fan-out — no customer data — and account data stays in one region.

Dependencies

Dependency and workflow updates are raised automatically, and security advisories against anything we depend on are reported to us as they are published. Every change runs through a suite that stands up a real database, a real Redis and the built server before it can merge.

What we do not have

No SOC 2 report, no third-party penetration test, and no 24/7 on-call rotation. Socketly is small and says so. If your procurement needs any of those, write before you depend on us and we will tell you honestly where we are.

Reporting something

Mail support@socketly.co with “security” in the subject and it gets read first. Tell us what you found and how to reproduce it; we will confirm we have read it and tell you what we intend to do. Please test against your own app rather than someone else’s — the free plan needs no card. More on the contact page.