Security & privacy

What protects your workspace, and what we have not built yet

Kharazm holds ordinary but sensitive material: who owns a program, what is behind, which risks are open, and what stakeholders were told. This page describes the controls enforced in code, where data is hosted, and the gaps we know about. It is written for a procurement reviewer, not only an engineer.

We hold no compliance certification and have not commissioned a third-party penetration test. We would rather tell you that here than let you discover it in a questionnaire.

scrypt Password hashing with a per-user random salt
SHA-256 Session tokens are stored only as a hash
4 Access levels, enforced on the server
0 Third-party analytics, trackers or ad tech

Identity and sessions

Signing in is the only way into a workspace. Everything below happens on the server; nothing about your identity is decided by the browser.

  • Passwords are hashed with scrypt using a 16-byte random salt generated per user. Verification is constant-time, so the comparison itself does not leak information about the stored value. Plaintext passwords are never stored and never written to logs.
  • Sessions use a 32-byte random opaque token. Only the SHA-256 hash of that token is kept in the database, so a database leak does not hand an attacker usable sessions. The token itself lives in a cookie that is httpOnly (unreadable from JavaScript), SameSite=Lax, and Secure in production.
  • Sessions expire after 14 days and are deleted server-side on sign-out, so signing out actually ends the session rather than just clearing a cookie.
  • Rate limiting is applied per IP address to authentication and high-impact write routes: sign-in (20 attempts / 5 minutes), registration (8 / 10 minutes), invitation acceptance (12 / 15 minutes), initial-operator bootstrap (5 / 15 minutes), forgot-password (6 / 15 minutes), reset-password (10 / 15 minutes), workspace creation (8 / hour), invitation creation (40 / hour), operator decisions (60 / 5 minutes), and general domain writes (300 / 5 minutes). The bounded limiter is instance-local, not a distributed edge control.
  • Password reset issues a 32-byte random token, stored only as a SHA-256 hash, valid for one hour and usable once. Completing a reset revokes every existing session for that account — the equivalent of "sign out everywhere". The forgot-password endpoint returns an identical response whether or not the address has an account, so it cannot be used to discover which staff are registered.
  • Invitations are email-bound and single-use. Only a SHA-256 token hash is stored. An invitation expires after seven days, can be revoked by an admin, and is consumed atomically with the profile, credential and membership changes needed to join. Existing accounts can accept an invitation to an additional workspace without creating another credential.
  • Bearer links use URL fragments. Invitation and password-reset tokens appear after #, so they are not sent in the HTTP request URL, and the application removes them from browser history as soon as it reads them.
  • Expired authentication records are cleaned up opportunistically. On API traffic, the process runs cleanup at most once an hour: expired sessions and reset records are removed, first-workspace requests older than 30 days are removed, and expired invitations are removed 30 days after expiry.

Authorization and tenant isolation

The organization is the intended security boundary. Server queries and writes are scoped to the organization in the authenticated session, and automated tests cover cross-tenant isolation.

  • Server-authoritative permissions. Every write passes through a single shared reducer whose capability check runs on the server, with the acting user taken from the session — never from the request body. A client cannot claim to be an admin. Permission checks in the interface exist to hide buttons that would fail; they are advisory, and the server decides.
  • Every request is scoped to the session's active organization. Cross-tenant isolation is covered by automated tests, so a regression that let one organization read another's programs would fail the build.
  • Per-organization audit log. Most actions that create, change or delete workspace records are logged with the actor, action, summary and time, and surfaced only to that organization's admins. Draft autosaves are not individual audit events, and the log is not a field-by-field version history.

The four access levels

Roles are assigned per person, per workspace, and are enforced on the server for every action.

What each Kharazm access level can do
Level What it can do
Admin Everything a manager can do, plus create and delete programs and manage the people in the workspace. Admins see the audit log.
Manager Create and delete tasks, and manage programs and milestones.
Member Edit tasks, change status, and comment.
Viewer Read-only. Useful for a sponsor or an oversight body that should see progress without being able to alter it.

A person can join an existing workspace only through an invitation with a role already assigned. A signed-out person's initial registration request enters an operator approval queue; an already signed-in user can create an additional workspace and becomes its admin without another review. A submitted email address never grants operator authority: the first configured operator must be provisioned through a deployment-controlled, one-time bootstrap secret. See access and pricing for the exact paths.

Transport and browser hardening

The headers below are set by the application, not left to a default configuration.

  • HTTPS is enforced in production, with HSTS asserted on TLS requests: max-age of two years, includeSubDomains, and preload.
  • A strict Content-Security-Policy with default-src 'self'. There are no third-party script or connect origins, frame-ancestors is 'none', and object-src is 'none'. The marketing site you are reading now runs under the same policy, which is why it loads no external fonts, scripts or images.
  • Supporting headers: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Referrer-Policy: same-origin, a Permissions-Policy that switches off camera, microphone and geolocation, and Cross-Origin-Opener-Policy: same-origin.
  • CSRF defense in depth: SameSite cookies plus a same-origin guard that rejects cross-origin requests using unsafe HTTP methods.
  • Schema validation covers authentication, bootstrap, workspace, invitation and operator-decision writes. All 27 supported domain operations use a strict discriminated Zod union with operation-specific ID formats, enums, ISO dates, text lengths and array limits; unknown keys are rejected at the envelope and payload levels. The domain reducer separately rechecks permissions and referential integrity.

Privacy posture

The browser loads Kharazm from one origin and makes no direct connection to analytics, advertising or other third-party services. The server does use the infrastructure and optional email subprocessors described below.

  • No analytics, no trackers, no ad tech, no session recording. The CSP's connect-src 'self' forbids them at the browser level, so this is enforced rather than promised.
  • The web font is self-hosted and served from the same origin. No font CDN sees your users' IP addresses.
  • Data minimization. We store an account email, a display name, organization membership and role, and the program data your team creates. Plaintext passwords, message bodies, recipient addresses, reset/invitation tokens and actionable links are not written to production application logs.
  • The application is login-walled, and robots.txt keeps crawlers away from the API surface.
  • No built-in accounts or demo workspace. The product ships no seeded credentials or sample content. Initial registration is operator-reviewed, while additional workspaces created by signed-in users are not separately reviewed.
  • No AI or agentic processing today. Those capabilities are a plan for the next product workstream, not a current feature. Kharazm does not currently send workspace content to a model provider or use it to train models.
  • Secrets stay out of the repository. The database URL is injected as a platform secret and is never committed; local state directories are excluded from both the repository and the container image.

Full detail on what we collect and why is in the privacy policy.

Email

Kharazm uses transactional email for password resets, workspace invitations, and new-workspace approval notices. Messages are delivered through Resend using a server-side HTTPS request, with no third-party SDK or script embedded in the browser.

If no Resend API key is configured, an administrator can still copy the shareable invitation link returned in the interface. Password-reset and approval emails cannot be delivered, so a production deployment should configure email before accepting accounts.

Where your data lives

The hosted deployment at kharazm.org runs on Fly.io; the application configuration currently selects San Jose. Managed PostgreSQL is provided by Neon, and the database connection requires TLS. The repository does not prove the managed database's live region, so request written confirmation before relying on a data-residency commitment.

The application does not intentionally send workspace content to another service. There is no data warehouse, analytics pipeline, product integration or model provider. Routine storage, logs and backups remain within the disclosed hosting and database providers, and Resend receives only transactional-email data when delivery is configured.

Kharazm is self-contained and can be deployed for a single organization if your policy requires the data to sit somewhere specific. Write to hello@bakaroart.com and describe the constraint you are working under.

What we have not done yet

This section exists because a security page without one is not worth reading. These are real, tracked gaps, stated plainly.

  • No third-party penetration test or security audit. No independent firm has tested Kharazm. The controls above are implemented and tested by us; they have not been attacked by a specialist.
  • No compliance certification of any kind. We are not SOC 2 audited, not FedRAMP authorized, and we make no HIPAA or GDPR compliance claim. If your procurement process requires one of those, Kharazm does not meet it today, and we will not tell you otherwise.
  • No self-serve account or organization deletion in the interface. Right-to-erasure requests are honored, but removal currently happens at the database level after you email us, rather than through a button you press yourself. This is on the list to build.
  • Off-box and point-in-time backups depend on the database plan. Backup and recovery guarantees come from the underlying PostgreSQL plan rather than from anything Kharazm adds on top. If a specific recovery objective matters to you, ask us before you commit and we will tell you exactly what the current plan provides.
  • No configurable workspace-content retention or legal hold. The server cleans up limited authentication records on the schedule described above, but program content and audit history otherwise remain until the workspace or relevant record is deleted.
  • No formal incident-response commitment. There is no contractual notification window today. If we learn of a breach affecting your workspace, we will contact the workspace admins directly; we are not going to dress that up as a certified process.
  • Rate limiting is application-instance local. Sensitive endpoints are throttled, but the current limiter is not a distributed edge control. A larger or higher-risk deployment should add platform-level abuse protection.

If any of these is a blocker for your organization, say so. Knowing which gap actually stops a team from adopting the product is more useful to us than a guess.

Responsible disclosure

If you find a vulnerability, please email hello@bakaroart.com with enough detail to reproduce it — the affected URL or endpoint, the steps you took, and what you observed.

Please do not open a public issue for a security report. Give us a reasonable window to fix the problem before disclosing it publicly. We do not currently run a paid bug bounty, and we will not pretend otherwise, but we will acknowledge your report, keep you updated on the fix, and credit you if you would like to be credited.

We ask that you avoid testing that degrades service for other users, and that you do not access, modify or retain data belonging to an organization that is not yours. If you access someone else's data accidentally while investigating, stop, tell us, and delete it.

Why it is built this way

Boring controls, honestly described

Any team responsible for sensitive program data should be able to account for the tools it uses. The three ideas below are what we would want to defend in that conversation.

Enforced, not documented

Every control on this page is implemented in the application, and the ones that matter most — tenant isolation, role checks — are covered by automated tests that run before anything ships.

No third-party browser traffic

No analytics, trackers, external font or script host run in the browser. Server-side hosting, database and optional email providers are disclosed above rather than hidden behind that browser claim.

Gaps stated up front

No certification, no third-party pen test, no self-serve deletion yet. You should hear that from us at evaluation time, not from a security questionnaire three months in.

Questions your security review needs answered?

Send the questionnaire, the specific control, or the constraint you are working under. We will answer directly, including where the answer is "not yet".