Skip to content
Cybsis

Security & privacy

Open about everything except the keys.

A cryptosystem must be secure even if everything about it is known, except the key. Kerckhoffs wrote that in 1883; we agree. What follows is the implementation as it actually ships today — what's live, what isn't yet, and where to write if you find a gap we haven't.

01 — Authentication

Modern by default, government-grade where it matters.

Authentication is the first signal of how seriously the rest of the platform is taken. Cybsis treats it that way.

Passkeys (WebAuthn) — the default
Phishing-resistant cryptographic credentials, bound to the device. Hardware security keys like YubiKey are first-class citizens — the same flow handles them and platform authenticators (Touch ID, Windows Hello) interchangeably. @simplewebauthn/server v13
TARA — Estonian eID umbrella (public sector)
One OIDC flow against the Estonian state SSO covers every national eID scheme: ID-card, Mobile-ID, and Smart-ID. The user picks at the TARA portal; Cybsis receives a verified identity assertion back. TARA is a state-run service for authenticating to public-sector systems — private-sector deployments use Web eID below. openid-client v6
Active Directory / LDAP
Direct bind against the customer's AD or any LDAP-compatible directory. For enterprises that already centralise identity and don't want a second user store. Account lockout cooperates with the directory's own policy. ldapts v8 · integrationAD module
Web eID — ID-card for the private sector
Estonian ID-card authentication available to private-sector buyers (and to public-sector teams who'd rather not route through TARA). Browser-extension-driven, with OCSP certificate validation and nonce-bound challenge-response. Commercial Mobile-ID and Smart-ID via SK ID Solutions are supported as a paid integration module — included for existing customers, purchased separately for new private-sector deployments. @peculiar/x509 · OCSP-validated
Federation API keys
Machine-to-machine access between Cybsis instances. Bearer tokens with HMAC-SHA256 request signatures and identity-header role mapping; revocable at the issuing instance. federation module
Password (when nothing else fits)
Bcrypt-hashed, minimum length configurable, account lockout after a configurable number of failed attempts within a rolling 15-minute window. We'd rather you used passkeys. bcryptjs v3

Session model

Short-lived JWT access tokens (15 minutes, configurable) carried in httpOnly SameSite=Strict cookies, with audience and issuer validation. Refresh tokens are 48 random bytes, stored SHA-256-hashed at rest — the plaintext only ever exists in the browser cookie. Idle timeout configurable per instance; default 60 minutes. Per-route rate limits on every authentication endpoint (e.g. password: 10 requests / 15 minutes; passkey registration: 20 / 5 minutes).

02 — Authorization & isolation

One database, hard tenant boundaries.

RBAC with permission gating
Roles aggregate permissions; permissions are checked at the endpoint via middleware, not at the model layer. Endpoints that aren't permission-checked don't exist — adding one is a compile-step decision.
Row-level tenant isolation
Every operational entity carries an instanceId foreign key. Queries that forget it are dead-letter — every list endpoint scopes to the authenticated user's accessible instances.
Federation role mapping
When a federated instance calls in, the API key carries identity headers that map to a local role. The remote caller never gets blanket access — it gets the role the local administrator has assigned to that federation link.

03 — Encryption

Field-level secrets. Per-file content keys.

  • Sensitive config

    AI provider API keys, SMTP/IMAP credentials, and other secrets in the system configuration are encrypted with AES-256-GCM at the field level — 12-byte IV plus 16-byte authentication tag prepended to the ciphertext. RaulWalter staff cannot read them; the database row alone is not enough.

  • Uploaded files

    Each file gets its own derived key via HMAC-SHA256(master, "file:" + fileId) — HKDF construction. The master key encrypts nothing directly; compromising one file key compromises one file.

  • Passwords

    Bcrypt-hashed. The database stores hashes only; password resets generate short-lived signed tokens, never the plaintext.

  • Refresh tokens

    Stored as SHA-256 hashes. Even with full database access, an attacker cannot replay a session — they would need the plaintext from the user's browser cookie.

  • Master key

    Lives in the ENCRYPTION_KEY environment variable — 32 bytes, base64-encoded. On self-host and on-prem deployments the key never leaves the customer's infrastructure; RaulWalter has no copy. On RW Hosting the key lives in the customer's isolated AWS environment, never on developer laptops and never in version control.

  • In transit

    TLS terminates at the reverse proxy (nginx in the recommended deployment). Cybsis does not accept plaintext HTTP for authenticated traffic.

04 — Audit & accountability

Everything that happens, gets written down.

Activity log
Over 80 action types — logins, role changes, control edits, document lifecycle transitions, incident workflows, integration toggles, licence events. Searchable and exportable.
Login attempt log
Every authentication attempt — method, IP, user-agent, success or failure — with the user record (or the attempted username when it fails). Drives the account lockout logic and gives auditors a forensic trail.
AI usage log
Every AI call — which user, which feature, which provider, prompt and response payloads, input/output tokens, cost estimate, duration, status. The toggle to disable AI flips this off too; nothing leaves the platform invisibly.

05 — Deployment & data residency

Three trust boundaries. Pick yours.

RW Hosting

AWS eu-north-1 · €300/yr flat

Single-tenant per customer, isolated AWS account, encrypted at rest. RaulWalter operates the runtime — same-day updates, active support, telemetry visible to us to make support fast. The trade-off you pick if you don't want to run the infrastructure.

Your cloud

AWS · GCP · Azure · no extra charge

Docker image, deployment documentation, you run it. The encryption master key lives in your secret store; RaulWalter has no read access to your database, no shell on your instances. Licence checks against our licence server are the only outbound calls.

On-premise

Defence · intel · healthcare · no extra charge

Same Docker image, customer-installed. Air-gapped operation via the air-gapped licence path. Zero outbound. If the AI features are enabled with a self-hosted model provider, the entire stack runs inside the perimeter.

Database & backups

PostgreSQL 17 is the default and the database we test against. Because the data layer sits on Prisma with no PostgreSQL-specific column types, JSON operators, or extensions, MySQL and SQLite are supported provider targets at the schema level — viable when an organisation has standardised elsewhere and is willing to operate the deployment themselves. The schema discipline is deliberate, not accidental.

Built-in backup tooling runs pg_dump on a tiered schedule — hourly, daily, weekly — with configurable retention. On self-host you point the backup volume at your storage of choice; on RW Hosting backups land in customer-isolated S3. Non-Postgres deployments use the operator's own backup tooling.

06 — AI trust boundary

Off by default. Configurable. Logged.

AI is the only feature that can move data outside your trust boundary. So it's the one we treat with the most ceremony.

  • 01Off until enabled. A fresh install ships with ai_enabled = false. No sparkle buttons, no Ludwig entry point, no outbound calls. An administrator turns it on under Administration → AI Settings; the toggle is reversible.
  • 02Three provider modes. Bring your own key (Anthropic, OpenAI, Gemini, Azure OpenAI), point at a self-hosted OpenAI-compatible endpoint (Ollama, vLLM, any in-house LLM), or let RaulWalter supply the key. Full detail on the AI features page.
  • 03Provider config is encrypted. The API key field is AES-256-GCM-encrypted at rest. A database snapshot does not leak it; only the running process with the master key can decrypt.
  • 04Every call is logged. The AI usage log records the user, instance, provider, model, full prompt and response payloads, token counts, cost estimate, and duration. Auditable like any other activity.
  • 05No automatic redaction. Said plainly: Cybsis does not automatically strip PII or sensitive content from prompts before sending them to your chosen provider. The prompt you send is the prompt that hits the provider. For workloads where this matters, use mode 2 — a self-hosted LLM endpoint inside your perimeter — so no prompt ever leaves the network.

07 — What's on the security roadmap

What we haven't shipped yet.

Kerckhoffs's principle cuts both ways. If we expect you to trust the implementation, we owe you a list of the things that aren't in it yet.

  • TOTP as a second factor

    The platform encourages passkeys, which are stronger than password + TOTP for phishing-resistance. But environments that mandate TOTP — particularly public-sector procurement frameworks — need an explicit second factor on top of password. On the next minor release.

  • SAML SSO

    OIDC is already supported via the TARA integration; generic OIDC against any IdP is a small extension. SAML — for the enterprises whose IdP team only speaks SAML — is on the backlog and gated behind the first customer who actually requires it.

  • Tamper-evident audit log

    The audit log is comprehensive but the rows are mutable like any other database table — a database administrator with write access can edit history. A hash-chain or append-only-storage construction is the planned hardening; it matters most for regulated sectors where the auditor needs cryptographic non-repudiation.

  • Automated supply-chain scanning

    The lockfile is committed and reviewed on every release, but we don't yet run automated Dependabot or Renovate against the repo, and there's no published SBOM. Both are on the next-quarter list.

  • AI prompt PII redaction

    The platform-constructed portions of an AI prompt are already minimised — controlled fields with capped sample sizes, no credentials, no national identifiers. What doesn't yet exist is an automatic scrubbing layer over user-authored prompt content: a comment or freeform note typed into a sparkle-button input goes to the provider verbatim. A redaction pass — entity detection, configurable patterns, instance-level policy — is on the build list.

  • Bug bounty programme

    Coordinated disclosure via the email below is the contract today. A funded bounty programme — likely via a public platform — opens once we have enough installed base for it to be meaningful for researchers.

08 — Responsible disclosure

Found something? Tell us.

If you've found a security issue in Cybsis — in the product, the website, or any integration we publish — write to security@raulwalter.com. We acknowledge within 24 hours of receipt, every day of the year.

PGP — encrypt sensitive reports

Fingerprint: 3361 FEA1 BF78 5BDA A1BF 0385 860E 681F 87FF 816A
Key: /.well-known/security-raulwalter.asc · also referenced in /.well-known/security.txt

What we'll do

  • — Acknowledge your report within 24 hours.
  • — Tell you within 5 business days whether we can reproduce it.
  • — Keep you updated until the issue is closed.
  • — Credit you in the changelog when the fix ships, unless you ask us not to.
  • — Never threaten you for finding it.

What we ask you to do

  • — Give us a reasonable window to fix before public disclosure.
  • — Don't exfiltrate customer data, even to prove the bug works.
  • — Don't run automated scanners against production instances you don't own.
  • — Use a test instance or RW Hosting trial if you need to demonstrate.

For non-security questions about the product, use the quote form or write to sales@raulwalter.com. The security inbox is monitored separately and should be reserved for vulnerability reports.