Security at KODEO

Built to beattacked.

This is how KODEO is actually put together — every wall in the model is real code. Pick an attack below and watch where it’s stopped.

A normal request passes seven checks on its way in. Stopped at

Try to break in
7checks on every request
0secrets stored in plain text
15 minlife of an access token
2,447automated checks, all passing

What every request passes

Seven checks, in this order

  1. 1HTTPS only — HSTS for two years, including subdomains.
  2. 2A per-request nonce policy decides which scripts may run.
  3. 3A 15-minute token, from a session you can see and end.
  4. 4Changes must come from kodeo.website itself (Origin + Fetch-Metadata).
  5. 5Your session, re-checked — suspended accounts and ended sessions stop here.
  6. 6The body must match a strict schema, or it’s refused.
  7. 7Values reach Postgres as parameters, never as SQL.

Script injection

Stopped at the outer wall

Getting your browser to run someone else’s JavaScript on kodeo.website — to read the page or act as you.

  • Every page carries a Content-Security-Policy with a fresh random nonce per request: a script without it never runs, and `unsafe-eval` is not allowed anywhere.
  • Anything people write — names, comments, chat, Markdown, AI answers — is rendered as text or through our own parser, never as raw HTML.
  • Project files are only ever sent as downloads (`Content-Disposition: attachment`, `nosniff`, a sandbox CSP), so an uploaded .html or .svg can’t execute here.

Forged requests

Stopped at the first post in the courtyard

Another site making your browser send a request to KODEO — while you’re signed in — that you never meant to send.

  • Every request that changes something must come from our own origin: the `Origin` header is checked, and so is the browser’s `Sec-Fetch-Site`.
  • Bodies are JSON, which another site can’t send across origins without a preflight we never approve.
  • Sign-in cookies are `SameSite`, and the Console’s are `SameSite=Strict` with a custom header on every action.

Stolen session

Stopped at the second post

Taking a copy of your signed-in cookie and using it from somewhere else.

  • Session cookies are `httpOnly` and `__Host-` scoped: the page’s own scripts can’t read them (the check further down this page shows it).
  • The access token lives 15 minutes. The refresh token rotates on every use — replaying an old one is detected, and the whole session family is ended at once.
  • Every device is listed in Settings → Sessions with its full address; one tap ends it, and “This wasn’t me” ends all of them.

Password guessing

Stopped at the gatehouse

Trying leaked or common passwords against accounts, fast and at scale.

  • Passwords are stored only as Argon2id hashes (19 MiB memory, 2 passes) — slow and memory-hard by design.
  • Attempts are rate-limited per address and per account, with a temporary lock after repeated failures; staff can block an address outright.
  • Two-factor (an authenticator app or a passkey) means a right password alone still doesn’t open the account — and a new device is emailed to you.

Phishing page

Stopped at the gatehouse

A convincing copy of the sign-in page that collects what you type.

  • Passkeys are bound to kodeo.website by your device: a look-alike domain simply can’t ask for them.
  • Sensitive actions ask you to confirm it’s you again (“step-up”) — with two-factor on, an emailed code alone is never enough.
  • A sign-in from a new device sends you an alert with a one-tap “This wasn’t me”.

SQL injection

Stopped at the vault door

Smuggling database commands inside ordinary input — a search box, a name, a file path.

  • Every query is parameterised: values travel separately from the SQL text, so input can never become a command. Nothing is string-built.
  • Input is checked against a schema before it reaches a query, and file paths go through one validator that refuses traversal, control characters and reserved names.
  • Each change runs in a transaction with the right locks, so a half-applied write never exists.

Malicious project

Stopped at the moat

Code inside a project — yours, a teammate’s, or a cloned repository — trying to reach your KODEO account.

  • Code runs in your own browser tab (WebContainers), in a frame on a different origin — it can’t read KODEO’s cookies, pages or storage.
  • Only the editor is cross-origin isolated, and a running app is shown in a sandboxed frame; nothing a project prints is ever served from kodeo.website.
  • Files written by a run come back only through checks on the server: your role, the path validator, the plan’s limits, binary detection.

Token theft

Stopped at sealed inside the vault

Getting hold of your GitHub access, or the secret behind your two-factor codes.

  • GitHub tokens are encrypted with AES-256-GCM under their own key, bound to your account, and used only on the server — no route ever returns one.
  • Two-factor secrets are sealed the same way; backup codes, reset links and recovery codes are stored only as hashes.
  • Commits are scanned for secrets before they’re made, and exports never include tokens or other people’s email addresses.

Realtime server breach

Stopped at the broken bridge

Taking over the live-collaboration server and using it to reach the database.

  • The collaboration server holds no database credentials at all: every read and write goes through one HMAC-signed endpoint with a replay window.
  • Membership is re-checked on each call, and permissions are checked per message — a viewer’s edits are dropped on the server.
  • Removing someone from a workspace ends their live connection at once.

Rogue insider

Stopped at the watchtower

Someone with staff access abusing it — or someone who took over a staff account.

  • Staff need two locks — a staff record and an address on a list held outside the database — and a separate Console session that ends after 15 idle minutes.
  • Dangerous actions need a passkey from the last five minutes, and a key added in the last 24 hours can’t confirm them.
  • Everything staff do is written to an append-only, hash-chained audit log that the database itself refuses to edit. Personal details are masked by default.

Payment tampering

Stopped at the treasury

Faking a successful payment — or changing the amount — to unlock a paid plan.

  • A plan changes only when Cashfree’s signed webhook (or our own call to Cashfree) says so — never on a redirect or anything the browser sends.
  • Prices come from the server; amount or currency mismatches are never credited, and every transition is idempotent inside a transaction.
  • Card details are entered on Cashfree’s page. KODEO never sees them.

Where it all lives

Four places.One direction.

Your data moves one way: from your browser, through the app, into the database. The live-collaboration server sits beside that path, never on it.

Your browser

Your code runs here

Run, the terminal and Python execute in your own tab, in a frame on another origin.

  • Nothing you run executes on KODEO’s servers
  • Previews are sandboxed frames
  • Your dependency cache stays on this device
Singapore · Vercel

The app

Every page and API call, next to the database — HTTPS only, a fresh CSP nonce per page.

  • Functions pinned to one region (sin1)
  • Every change checked for origin, session and schema
  • No card details — ever
Singapore · Neon Postgres

Your data

Files, Git history, accounts and billing, in Postgres — reached only through parameterised SQL.

  • Encrypted at rest by the provider
  • Secrets sealed again with AES-256-GCM
  • Passwords only as Argon2id hashes
Mumbai · Oracle Cloud

Live collaboration

The server that carries cursors and edits between people — with no way into the database.

  • No database credentials at all
  • Every call to the app HMAC-signed
  • Terminal output never stored

The services we rely on — Vercel, Neon, Oracle Cloud, Cashfree, our email provider, and DeepSeek for KODEO Assist — and exactly what each receives are listed in the Privacy Policy.

Don’t take our word for it

Check ityourself.

Your browser just received this page. Here is what came with it — read live, in your browser, right now. Anyone can run the same check with their browser’s developer tools.

Reading this page’s headers…nothing leaves your browser

Every part, a layer

Security wasn’tadded later.

KODEO is built in numbered parts, and each one shipped with its own defences — and the tests that prove them.

  1. Part 1

    Accounts built to be attacked

    Argon2id passwords (19 MiB, 2 passes), 15-minute tokens, rotating refresh tokens with reuse detection, one-time email codes, a per-request nonce CSP.

  2. Part 3

    Money only on the processor’s word

    Signed Cashfree webhooks, idempotent state changes, prices decided on the server, no card data on KODEO.

  3. Part 4

    One door for every path and every download

    A single path validator; files leave only as attachments with a sandbox CSP, so uploads can’t run here.

  4. Part 5

    A realtime server that can’t touch the data

    HMAC-signed calls, per-message permission checks, and no database credentials on that machine.

  5. Part 6

    Your code, off our origin

    Runs in your tab inside a frame on another origin; only the editor is cross-origin isolated.

  6. Part 8

    Git and GitHub, keys kept server-side

    GitHub tokens AES-256-GCM encrypted and never sent to the browser; commits scanned for secrets.

  7. Part 8.3

    Passkeys, two-factor and a history you can read

    Passkeys, authenticator codes, backup codes, new-device alerts, “This wasn’t me”, sign-out reasons, browser push.

  8. Part 8.4

    Staff held to a higher bar than users

    A separate Console: two locks, passkey step-up, 24-hour probation for new keys, a hash-chained audit log.

  9. Part 8.5

    An AI that never sees your code

    KODEO Assist scrubs personal details, filters its own output, and reads your account only with consent.

  10. Part 8.6

    This page, and security.txt

    A public account of how it all works, checks you can run yourself, and a clear way to report a problem.

Responsible disclosure

Found a crack?Tell us first.

In scope

  • www.kodeo.website — the app, its API and the Console at /admin
  • collab.kodeo.website — the live-collaboration server
  • How KODEO handles your data, tokens, sessions, files and payments

Please don’t

  • Access, change or delete anyone else’s data — use your own accounts and workspaces to test
  • Run denial-of-service, load or spam tests, or brute-force sign-in beyond what shows a rate limit works
  • Social-engineer staff or users, or test physical security
  • Test the services we use (Vercel, Neon, Oracle, Cashfree, GitHub, DeepSeek) — report to them directly

What we promise

  • A human reply within 48 hours, and updates until it’s fixed
  • Public credit for a confirmed issue, if you’d like it
  • That we won’t pursue legal action for research done in good faith and within these rules
  • That you can publish 90 days after we confirm the report — sooner once it’s fixed

A good report has

  • What you found and where — the page or the API route
  • Steps to reproduce it, and what an attacker could do with it
  • Your account’s email (never your password), so we can match what we see

Questions

Asked, andanswered plainly.

Can KODEO staff open my code?
The Console — the only place staff work — has no way to open your files or your editor. What it does show (your plan, your usage, your sign-in methods) is masked by default, revealing an email address needs a written reason, and every action is written to an audit log that can’t be edited. Direct access to the database is limited to the owner’s own credentials; like any service, that is the one place trust sits, which is why it is kept that narrow.
Is my code used to train AI?
No. KODEO Assist never receives your files, code, errors or terminal output — in the editor it’s given state only (which panel is open, whether a run is going). Questions are cleaned of email addresses, phone numbers, codes and anything shaped like a secret before they’re sent.
My laptop was stolen. What do I do?
Sign in from another device and open Settings → Sessions: end that device’s session, or tap “This wasn’t me” to sign every device out and start a password reset. If you had passkeys on it, remove them in Settings → Security.
How are passwords stored?
Only as Argon2id hashes (19 MiB of memory, 2 passes, parallelism 1) — a deliberately slow, memory-hard function, so a copy of the database doesn’t turn into a list of passwords. Better still, use a passkey: then there’s no password to steal.
Does KODEO store my card?
No. You pay on Cashfree’s own page; KODEO receives only the outcome, and a plan changes only when Cashfree’s signed message says so.
What happens to my data if I delete my account?
Recurring payments are cancelled first, then your account, the workspaces you own and their files are deleted in one transaction. Workspaces you were only a member of stay with their owners.

Ready whenyou are.

A workspace, a project and a live editor in under a minute. Free, no card.