Security model
Nuvora is an evaluation release. This page says what it enforces and what it doesn't.
Enforced
- Tenant isolation. Every query is scoped by tenant, so an ID alone never grants access.
- Roles. The four roles (
viewer,developer,approver,admin) are checked by the API on every request. - Sessions.
- Cookies are HttpOnly and
SameSite=Strict, and Secure over TLS. - Mutations need a CSRF token and pass Origin validation.
- Bearer tokens are scoped and stored only as digests. Owners and admins can list and revoke them, and demotion below developer revokes them.
- Changing your password signs out your other sessions.
- Cookies are HttpOnly and
- Single sign-on.
- OIDC sign-in uses the code flow with PKCE and a signed, short-lived state cookie. The ID token's issuer, audience, expiry and nonce are checked.
- Bearer JWTs are signature-verified against the issuer's JWKS, with asymmetric algorithms only.
- SSO users can't use or change a password, and an SSO sign-in never takes over a local account.
- Passwords.
- Passwords need 12–256 characters and are stored as PBKDF2-SHA256 hashes.
- The only exception is the deploy demo password for the bootstrap administrator, and only when it's explicitly allowed.
- The console never stores passwords in the browser. Playground conversations are kept in local storage, per workspace and user.
- Outbound calls.
- Calls go only to hosts on an exact allow-list, over HTTPS for remote hosts. Redirects are refused.
- Credentials are environment references, never stored values.
- Separation of duties. Consequential actions need a different person's approval, bound to an exact fingerprint.
- Streaming. Streamed answers pass the output guardrails at sentence boundaries before any text reaches the browser.
- Evidence. The audit log is hash-chained, and
scripts/verify-evidence.pychecks an export offline. - Transport. Remote binds require direct TLS or an explicitly trusted TLS proxy. The content security policy is
script-src 'self'.
Not enforced
- The host is trusted. A host administrator can read or change the database. The audit chain is unsigned, so anchor chain tips externally if you need independent proof.
- Guardrails are pattern-based. They block configured topics and some instruction-override patterns and redact emails and account numbers. They aren't robust jailbreak prevention.
- Code runs only in Keep. The server itself isn't an isolated agent runtime.
run_codeexists only when Keep is configured, runs in a FluxVM sandbox without network, and needs a different person's approval of the exact code. There are no browser tools. - Your providers see your data. External model providers receive whatever content is sent to them, under their own terms.
- No encryption at rest. Neither SQLite nor PostgreSQL data is encrypted by Nuvora. Use an encrypted volume or database encryption, and
sslmode=requirefor PostgreSQL. - Per-process limits. With several replicas, the four-concurrent-calls limit and in-flight budget reservations apply per replica.
Reporting
Report vulnerabilities privately to the maintainers, not in a public issue. Don't include credentials or confidential documents.