Contact

Everything happens in the repository.

There is no Discord, no forum, no mailing list and no support desk — not as a stance, but because a small project with three half-empty channels serves people worse than one place where questions get answered. Issues and discussions are the whole surface, with one deliberate exception for security.

Security

Please do not open a public issue

Report a vulnerability privately, with a description, an assessment of impact and a reproduction. You will get an acknowledgement, and either a fix or an explanation of why it is not one. GitHub’s private vulnerability reporting on the repository is the fastest route; the maintainer contact in CONTRIBUTING.md is the alternative.

especially welcomehigh impact
  • Anything that reads or writes rows RLS should have hidden.
  • Anything that lets a project user reach /admin/v1, or turns an application token into a platform one.
  • Path traversal or symlink escape in storage keys.
  • SQL injection through an identifier path — a column name, a table name, a sort column, a cast.
  • Token handling: reuse detection, session revocation, signature verification.
  • A credential appearing in a log, an audit row, an error message or an import progress stream.
Report a vulnerability privately
What is not a vulnerability. A table in public with no policies is readable by anyone holding the anon key — that is documented, intended and the first thing the row-level-security page tells you. So is the service key bypassing every policy: that is what it is for, and keeping it out of a browser is your side of the contract.

The security model, in full

Before you write

What turns a report into a fix

None of this is bureaucracy. Every line below is something that would otherwise be the first reply, costing you a day.

paste the output of these
# version, and whether the database is reachable
curl -s http://127.0.0.1:3130/health

# both containers, and whether they are healthy
docker compose ps

# the last hundred lines from the app, secrets already redacted
docker compose logs --tail=100 app

# and, for anything data-shaped, the table and its policies
#   \d+ public.your_table
#   select * from pg_policies where tablename = 'your_table';
  1. What you expected, and what happened

    Both, separately. “It does not work” is the one report that cannot be acted on.

  2. The smallest reproduction you can manage

    A table definition, a policy, and the one request. If it needs your whole application, it usually needs less.

  3. Which role the request ran as

    anon, authenticated, or the service key. Most surprising behaviour is a policy behaving exactly as written for a role you did not expect.

  4. The error code, not a screenshot of a toast

    Every error is { "error": { "code", "message", "details" } }. The code is the searchable part.

  5. Redact your keys

    The service key in a pasted curl is a full bypass of every policy you wrote. Logs are redacted for you; pasted commands are not.

Before you ask

The three questions that come up most

My table returns an empty array and there is no error. Why?

Row level security is on and no policy grants your role a select. RLS denies by default, and a denied read is an empty result rather than a 403 — that is Postgres behaviour, not a Baselyra decision. Write a policy, or check which role the request actually ran as.

Row level security

My realtime subscription connects and then goes quiet.

Two usual causes. The table does not have the NOTIFY trigger — enable it in Studio → Realtime, per table. Or a reverse proxy is not passing the WebSocket upgrade through; the self-hosting page has the exact nginx and Apache stanzas, and getting one line wrong there is the single most common deployment problem.

Realtime, including the proxy rule

I cannot sign in to the Studio with a user I created in the app.

Correct, and by design. No row in auth.users can ever open the Studio however it is configured — Studio tokens carry a typ: "platform" claim minted by exactly one endpoint, and Studio accounts live in a different database. Create an operator account instead.

Studio accounts and application users

One more thing

If the documentation was wrong, that is a bug too.

A page that only makes sense once you already know the answer is worth reporting. It is the cheapest fix in the project and the one that helps the most people.