Trust
Security
What we do not claim
Korps holds no SOC 2 report, no ISO 27001 certificate, no PCI DSS attestation and no HIPAA business associate agreement. We do not have an independent audit, and we will not say we do until one exists.
Do not put protected health information, payment card data or government identity documents into Korps.
The architecture is deliberately kept capable of private, isolated runtime and model deployments, which is a prerequisite for a future regulated configuration. That is a design property, not a compliance claim.
This page describes the build as inspected on the date above. It is a statement by the engineers who built it, not an independent assessment, and it says so wherever it matters.
This page describes controls that are actually implemented. Anything planned is labelled as planned.
1. Accounts and sessions
- Passwords are stored only as scrypt hashes with a per-account random salt and cost parameters N=16384, r=8, p=1. Plaintext passwords are never stored or logged.
- Password verification uses a constant-time comparison.
- Access tokens are HMAC-SHA256 signed and expire 15 minutes after issue.
- Refresh tokens are random 256-bit values, stored server side only as SHA-256 hashes, and expire after 30 days.
- Sessions belong to a family. Signing out revokes the family server side, so a copied token stops working rather than outliving the sign-out.
- Sign-out works even when the access token has already expired, using the refresh token as proof of the session.
- Account recovery uses one-time codes issued at signup, eight of them, shown once and stored only as SHA-256 hashes. Spending a code sets a new password and revokes every existing session, so recovering an account also evicts anyone already in it. Every failed attempt returns the same error and status, and does the same password hashing work whether or not the address has an account, so neither the response nor how long it takes reveals which addresses are registered. Sign-in behaves the same way. Both endpoints are rate limited with the other authentication routes.
2. Rate limiting and abuse controls
- Authentication routes, runtime claim and workspace claim are rate limited per source IP: 5 requests in a 60-second window, then HTTP 429.
- The marketing site's own measurement beacon (
POST /v1/telemetry/web) is limited separately at 60 requests per source IP in a 60-second window, so an office behind one address is not mistaken for an attack and is not dropped either. - Request bodies are capped at 256 KB. Oversized bodies are drained and rejected with HTTP 413 rather than dropping the connection.
- Malformed JSON is rejected with a specific error rather than a generic failure.
3. Tenant isolation
- Every workspace-scoped read and write is filtered by the caller's workspace membership on the server. The browser cannot ask for another workspace's records by changing an identifier.
- Usage attribution is checked against ownership: reporting usage for an agent or runtime that does not belong to your workspace returns a not-found error instead of writing a cross-tenant record.
- Avatar bytes are served only to members of the owning workspace, addressed by content hash.
- A tenancy test suite exists in the control plane. It requires a database to be supplied before it will run, and it is not yet part of a continuous integration gate, so treat the boundary as resting on the implementation rather than on a green test run.
4. Infrastructure pairing
- Attaching a server uses a one-time pairing code that expires 15 minutes after issue and is stored only as a SHA-256 hash.
- Pairing state is reported from the server's own view of the handshake, so the browser shows pending, claimed or expired rather than an indefinite spinner.
- Korps never asks for, copies or stores your private SSH keys as part of this flow.
5. Transport and hosting
- All public traffic is HTTPS, terminated by a reverse proxy with automatically renewed certificates. The control-plane API listens only on loopback behind that proxy.
- Marketing and API are on separate hostnames.
- The app, the API and the marketing pages load nothing from third parties: no scripts, no fonts, no trackers. The site ships its own fonts.
- App pages refuse to be framed by another site, so a sign-in form cannot be laid invisibly over a page you think you are clicking. The response carries
X-Frame-Options: DENYandContent-Security-Policy: frame-ancestors 'none', withX-Content-Type-Options: nosniffand a one-yearStrict-Transport-Securitybeside them. These headers come from the Caddy configuration kept in the repository and take effect at the next Caddy reload, so a deployment that has not reloaded Caddy is not yet sending them.
6. Provider credentials
- Korps does not store your model provider API keys. There is no column for one anywhere in the database, so there is nowhere for a key to land even by accident. On the routes that create and update a model connection, which is where somebody would try, the API refuses a request carrying a key outright rather than quietly ignoring the field. On other routes the field is ignored rather than refused: still never stored, but you would not get an error telling you so.
- A connection record holds the provider name, the kind of credential, and which of your servers holds it. The key itself stays on that server, which is also what makes the call to the provider.
- This means a breach of the Korps control plane does not expose your provider credentials, because they were never there.
- Provider credentials for agents on your connected machine stay on that machine. Credentials added through Korps Cloud compute connections are encrypted and stored by Korps: sealed in a vault under a separate key, held only by reference, never returned by any route, and refused outright if the vault is not configured.
7. Logging
- Request logs record method, path, status, duration and error code. Request bodies, tokens and passwords are not logged.
- Secrets are kept out of chat transcripts and command lines wherever a safer transport exists.
8. Usage limits as a safety control
Every workspace is metered against a token allowance for a rolling window. When the allowance is reached, metered work is refused rather than continuing silently. Metering stores token counts, provider and model names, not prompt content.
9. Agent authority
On desktop, Korps workers run under approval rules you set: approve once, approve for the session, trust similar actions, or enable scoped safe auto-approval for a trusted team or host. Force-push, history rewrite, destructive deletes, removing backups, moving secrets, privilege escalation and payment actions always require an explicit yes. Stop, Redirect and Pause are product controls, not labels.
The web control plane is the account, workspace and runtime door. Worker execution, approvals and reconnect of an external runtime (for example Code Assistant) happen in the Korps desktop and mobile apps. Korps does not store provider API keys in the control plane; the key stays on the runtime that makes the call.
10. Known gaps and what is planned
Stated plainly so nobody has to guess:
- Planned, not in place: email-based password reset. Recovery works today through one-time codes issued at signup, described in section 1. If you lose both your password and every code, we cannot restore the account for you.
- In place: self-serve workspace export and deletion. The owner can download everything the workspace holds as one document, and can schedule the workspace for deletion; it is removed after a 30-day grace period unless restored, and the audit of the deletion itself is kept. Account deletion outside a workspace is handled on request, as described in the Privacy Policy.
- In place: two-step sign-in. An account can require a code from an authenticator app after its password. The secret is sealed in the vault and referenced, never stored in the clear; a wrong code consumes the sign-in attempt.
- In place: an audit log of who changed what. Every privileged action records the account that took it, what was acted on, the outcome, and the time — the ones that succeeded as well as the ones that did not, because a log holding only failures cannot answer “who changed this”. Refused actions are recorded too, with the capability that was missing: an attempt somebody was not allowed to make is the entry an investigation most needs and the one that otherwise leaves no trace. A workspace owner or administrator can read their own workspace's log through the API; nobody can read another workspace's.Each request is logged as one line carrying a request id and the id of the account that made it, so a fault can be traced to a tenant; the line never carries an email address, a name, a request body or a token. What is not in place: a customer-facing export format and a defined retention period. Ask us for a copy today and we will run the query by hand.
- In place, Enterprise edition: single sign-on through an OpenID Connect identity provider, with the client secret in the vault, a nonce checked on the way back, and the person provisioned into the workspace with a default role; and SCIM, so a directory can create, update and deactivate people, with deactivation ending their sessions.
- Planned, not in place: independent penetration test and a published summary.
- Planned, not in place: formal, tested disaster-recovery objectives and a published status page.
- Planned, not in place: encryption of workspace records with customer-managed keys.
- Planned, not in place: a full Content Security Policy on the web app. The only directive in place is
frame-ancestors, described in section 5, which says who may frame the page and nothing about what the page may load. Everything the app inserts into the page is escaped, and that is checked, but a policy is the second line of defence for when escaping is wrong somewhere, and today there is no second line. Your access token is held in browser storage, so this is worth saying rather than leaving for you to discover in the response headers.
11. Reporting a vulnerability
Send findings to security@korps.ai. Please include steps to reproduce, the affected endpoint or page, and what you were able to access.
Good-faith safe harbour
If you follow these rules we will not pursue or support legal action against you for the research:
- test only against accounts and workspaces you control;
- do not access, modify or retain another customer's data, and stop as soon as you can confirm a boundary is crossed;
- no denial of service, spam or social engineering of our people;
- give us a reasonable chance to fix before publishing;
- stay within the law.
We aim to acknowledge a report within 3 business days and to give a remediation view within 14 days. Those are goals, not a contractual service level. We do not operate a paid bug bounty today.