livqenoDocs

ResourcesSecurity

Security

The four credentials, why none can stand in for another, and how to report a vulnerability.

A credential is anything that proves who is making a request. Livqeno uses four kinds. Each has its own job, and none can create or pretend to be another. Knowing which is which is the key to keeping your app safe.

In a normal app, they flow like this:

  1. You log in to the dashboard (a dashboard session) and create an API key.
  2. Your backend stores the API key and uses it to make tokens.
  3. Your users' apps get only a chat token or an RTC token, for one user and a short time.
CredentialUsed byGives access to
Dashboard login (session)A developerTheir whole account
Project API keyYour backendOne project, in one environment
Chat tokenOne userChat, for a short time
RTC tokenOne participantOne room

Each one is signed or stored differently. Chat tokens also carry a fixed aud: "raven-chat", so a dashboard login can never be reused on chat.

Your app can't pretend to be another user

For every write, Livqeno takes the user's identity from the signed credential, never from the request body.

For example, alice opens her browser's dev tools and edits a chat request to send a message as bob:

  • If a browser sends senderId: 'someone-else', there's no error. The value is just ignored. The message is still saved as from alice, because her chat token says she is alice.
  • Your server (with the API key) can act for any user. That's how your backend posts on someone's behalf, and it's why the API key must never reach a browser. See Authentication.

Two checks on every request

When a user's app asks to do something in chat (like post in a conversation), both checks must pass:

  1. What the token allows. Its scopes come from a role and can only be made smaller, never bigger.
  2. What the user is a member of. Checked on the server every time. A list cached in the client is never trusted.

See Chat → Authorization and Roles & Permissions.

How secrets are stored

  • API key secrets are hashed, never stored as plain text, and can't be recovered. You see them once.
  • Webhook signing secrets and moderation-hook secrets are stored encrypted with AES-256-GCM (we need them to sign deliveries), and never shown again after you create them.
  • Dashboard passwords are hashed with bcrypt. Two-factor seeds are encrypted the same way as signing secrets, and recovery codes are stored only as hashes.
  • Server SDKs keep the API key in a private field. It never shows up in JSON.stringify(), repr(), toString(), var_dump(), logs, or error messages. See the TypeScript, Python, Go, Java and PHP SDKs.

Dashboard accounts

  • Two-factor authentication. Turn on an authenticator app under Settings → Security. Sign-in then asks for a 6-digit code (or one of ten single-use recovery codes) after your password or GitHub/Google sign-in. Each code is accepted once, and a sign-in attempt ends after five wrong codes. Turning two-factor off needs a current code and your password.

  • Require it per project. Owners and admins can turn on Require two-factor authentication in project settings. Members without it are refused on every project page and API route until they turn it on.

  • Every session ends when it should. Signing out ends that session. Resetting your password ends every session of the account. A suspended account loses its sessions and its projects' API keys at once.

  • Storage credentials never reach the browser. The browser gets a signed URL for one file, valid for a few minutes.

  • Files are stored under random names, never the name the user uploaded. This blocks path-traversal tricks.

See Attachments.

Known limitation: webhook URLs

A webhook URL is the address on your backend where Livqeno sends events.

Livqeno blocks webhook URLs that obviously point at internal addresses. But it does not look up DNS, so a hostname that points to a private IP still gets through. See Webhooks → Security.

Reporting a vulnerability

Email security@livqeno.com with what you found. It stays private between you and the Livqeno security team. We'll follow up with next steps, and thank you once a fix ships.

No reply within a couple of business days? Send a follow-up. Your first email probably didn't arrive.

Next steps