Security
Demo-open by default. Locked down when it matters.
Yantrika ships demo-open on purpose — one shared Supabase project, one client-safe key, zero setup — so you can evaluate it in minutes. Two opt-in migrations take a real deployment to a hardened, then a fully role-based, posture.
The three modes
| Demo (default) | Hardened | Full RBAC | |
|---|---|---|---|
| Read/write policy | Anyone with the anon key can read and write every table | Authenticated sessions read-only; anon has no access | Reads scoped to a user's site + role; writes gated per role (see matrix below) |
| Login required? | No | Yes (or a read-only anon option) | Yes — a session and an assigned role (no role = sees nothing) |
| Writers (sim, detector, connector, ops) | Anon key | Server-side service key | Server-side service key |
| Command approval | Direct write from the console | No client write path at all | Dedicated database function, manager role or above |
| Best for | Demos, evaluation, throwaway data | Single-team read-only dashboards over real data | Real operations with per-person accountability |
Each mode is applied by running one SQL migration, and every migration carries a rollback block that restores the previous posture — moving to a stricter mode (or back) is never a one-way door.
The RBAC role hierarchy
Full RBAC mode introduces four roles, each including the capabilities of the ones below it: operator < engineer < manager < admin, assigned per person per site. An admin role at any single site is global — it grants read access to every site and role management everywhere.
| Capability | operator | engineer | manager | admin |
|---|---|---|---|---|
| View fleet data at own site | ✓ | ✓ | ✓ | ✓ (all sites) |
| Acknowledge alerts | ✓ | ✓ | ✓ | ✓ |
| Request commands (as themselves) | ✓ | ✓ | ✓ | ✓ |
| Connector management / telemetry export | — | ✓ | ✓ | ✓ |
| Approve / reject commands | — | — | ✓ | ✓ |
| Manage user roles | — | — | — | ✓ |
Most of this matrix is enforced in the database itself — Postgres row-level security policies and SECURITY DEFINER functions — so a hand-crafted API request cannot exceed a role's real capabilities. (The engineer tier for connector/telemetry tooling is enforced at the application layer instead; see docs/SECURITY.md for exactly which rows are which.)
Key separation, and an audit trail by default
The browser-safe anon/publishable key is only as dangerous as the active RLS policy allows — fully open in demo mode, nothing at all once hardened. The service-role key, which bypasses row-level security entirely, is never shipped to a browser — it is used only by server-side writers (the simulator, the detector, the connector, `yantraops`).
Independent of which mode is active: every alert acknowledgement, every command request, and every approve/reject decision is attributed to a named person with a timestamp — a full audit trail out of the box, not a bolt-on feature.