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.
Report a bug
Something behaves differently from the documentation, or from what it obviously should do. Include what is on the checklist below and it will be reproducible.
github.com/baselyra/baselyra/issues
Ask a question
“How do I write this policy”, “is this the right shape”, “why does my realtime feed skip deletes”. Questions asked in the open help the next person.
Discussions
Request a feature
Say what you are trying to do rather than the API you imagined. A sign-in provider, an SMS back end, a PostgREST operator, a framework guide — all reasonable asks.
Open an issue
Send a patch
One logical change per pull request, present-tense subject, docs updated in the same change, and say what you ran. The layout and conventions are written down.
CONTRIBUTING.md
Fix the documentation
The docs are markdown in the same repository. A wrong flag, a stale route, a paragraph that only makes sense if you already knew the answer — all of it is a pull request.
docs/
See a running instance
A live Studio, so you can look at the real thing rather than the drawings of it on this site before deciding whether to install anything.
baselyra.sarimtools.com
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.
- 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.
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.
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.
# 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';
What you expected, and what happened
Both, separately. “It does not work” is the one report that cannot be acted on.
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.
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.
The error
code, not a screenshot of a toastEvery error is
{ "error": { "code", "message", "details" } }. The code is the searchable part.Redact your keys
The service key in a pasted
curlis 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.
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.
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.
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.