Authentication modes
The --auth-mode flag controls whether nanosync enforces authentication and RBAC. It has exactly two values.
--auth-mode=none (default)
Every request runs as a synthetic SystemRoot principal. Every API call is allowed; no login screen is shown; no audit actor is captured beyond "system".
This is the default because:
- Existing single-binary deployments keep working unchanged after upgrade.
- CI pipelines and dev laptops don’t need user accounts.
- The trade-off (no per-user enforcement, no audit trail) is explicit and operator-controlled.
A startup warning is logged on every boot so this state is never silent:
WARN authentication disabled — all requests run as system root
--auth-mode=enabled
Every request must carry one of:
- Session cookie (
nanosync_session=…) issued byPOST /v1/auth/passwordor an SSO callback. - Bearer token (
Authorization: Bearer ns_<prefix>_<secret>) minted byns token create.
Anonymous requests return 401 Unauthorized. Authenticated requests run through rbac.Enforce on every mutation, and 9 read endpoints filter their result set by the principal’s active project.
The first time you flip this flag on a fresh database, you must bootstrap an admin user — otherwise the only entry point is the bootstrap endpoint itself. See Bootstrap the first admin.
Choosing between them
| Question | none | enabled |
|---|---|---|
| More than one human runs commands? | not great | ✅ |
| API exposed beyond a trusted network? | dangerous | ✅ |
| Need an audit trail of who did what? | partial (no actor) | ✅ |
| Single operator, trusted box, dev workflow? | ✅ | overkill |
| Want SSO with your IdP? | n/a | ✅ |
| Run on a laptop for development? | ✅ | overkill |
| Want zero-config bring-up? | ✅ | requires bootstrap |
You can flip between modes by restarting with the other flag. The data tables (users, sessions, role bindings) persist across mode changes — the flag only controls whether the auth middleware is wired in.
What runs differently between the two
| Subsystem | none | enabled |
|---|---|---|
| HTTP auth middleware | injects SystemRoot principal | validates session cookie / bearer token |
rbac.Enforce | always returns nil | walks bindings, returns ErrForbidden when denied |
Audit Actor field | {type: "system"} | {type: "user" | "service_account" | "token", id: …} |
| List endpoints (pipelines, connections) | return everything | filtered to active project |
| Single-resource Get | always returns the row | returns 404 if row is in a different project |
Login routes (/v1/auth/*) | unused | active |
POST /v1/admin/bootstrap | always available | always available (gated by IsAdminBound) |
Setting the flag
The flag is also a YAML config field for operators who manage the server via config files:
auth:
mode: enabled # or "none" (default)
master_key_file: /etc/nanosync/master.key
session_ttl: 12h # web session lifetime; default 12h
Command-line flag overrides config:
nanosync start --auth-mode=enabled --master-key-file=/etc/nanosync/master.key
See Bootstrap the first admin for the master-key setup.
Backward compatibility
- All existing single-tenant deployments continue working in
--auth-mode=none. - Migrations create the auth tables and seed the default tenant — but nothing reads them until you opt in.
- Existing pipelines and connections are backfilled to the seeded default project, so when you do flip to
enabledthey’re already scoped. - See Migration guide for the recommended upgrade steps.