Plain-language policy
Privacy Policy
Version 1.1 · Effective October 21, 2026This policy explains how KJN and the KJN node you use handle information. Node settings can change storage and connection paths, so this page describes the settings of the node serving it. Questions or privacy requests can be sent to hello@kjn.app.
Information we handle
- Account and profile data: username, display name, avatar, salted password hashes, recovery-code hashes, session-token hashes, account tier, and account settings. If you add passkeys, KJN stores their credential identifiers, public keys, counters, and a random account handle; your authenticator keeps the private keys and biometric data. KJN does not store your raw password.
- Saved rooms and room history: If you're signed in, KJN keeps your pinned rooms and a list of rooms you've recently joined, and when (not who was there or what was said), so they follow you across devices. Rooms you pinned on a device before signing in are added to your account. Recent rooms are capped at 50 and drop off after 180 days. Disappearing rooms are never recorded, and guests have no saved rooms or history. You can clear recent rooms or remove any one of them anytime. "Remember rooms I visit," at the bottom of Settings, turns this off and deletes your recent rooms; pins stay until you remove them. For members under 18, it's off unless they turn it on.
- Age bracket: At signup KJN asks your date of birth to derive a coarse age bracket (13–15, 16–17, or adult) for legal compliance and child safety. KJN keeps only that bracket, not your birth date. KJN is for ages 13 and up and does not knowingly create accounts for children under 13. On supported platforms KJN uses the operating system's age-range signal as the primary indicator (California AB 1043); the signup question is the fallback.
- Content you submit: room chat, Wall posts and media, journal entries, suggestions, room details, and direct messages when this node has hub-stored DMs enabled. If you choose Report, this also includes the selected content, optional details, category, room, and packet receipt you send for private operator review.
- Connection and security data: IP address and connection metadata, device or browser details supplied by requests, room membership, SDP/ICE connection setup, cryptographic public keys, signatures, invites, access records, rate-limit events, and operational logs.
- Technical error reports: When a page error or call problem happens (for example, a microphone that stopped or a connection that failed), the app sends KJN an anonymous, content-free report for reliability: a fixed problem type, the error name and a scrubbed short error message, KJN code locations, the app build, and a coarse browser, operating-system, and phone-or-computer category. It contains no messages, names, usernames, room names, email addresses, or tokens and is stored without your account or IP address.
- Problem reports you send: When you use Report a problem, KJN stores the category you pick, what you write, an email address only if you give one, whether you were signed in (not who you are), and, only if you tick "include technical details", the app build, your browser description, screen size, the kind of room you were in (public, private, ephemeral, or none), the page path, and up to ten recent error lines. Room names, invite links, tokens and message text are not kept: links in what you write lose everything after the page path, and anything that looks like an invite or key is replaced with "[removed]". Screenshots are not accepted.
- Human check: To stop automated sign-ups, KJN may ask
you to complete a Cloudflare Turnstile check on a separate page
(
/verify) before you create an account or sign in with a password. Cloudflare, already KJN's network provider, processes technical signals from your browser to tell people from bots; KJN receives only a pass/fail result, never those signals. - Breached-password warning: When you create an account or change your password, KJN checks whether that password has appeared in known public data breaches, using the Have I Been Pwned "Pwned Passwords" service. KJN's server sends only the first five characters of a one-way hash of the password; your password, its full hash, your account name and your IP address are never sent, so the service cannot tell what was checked or for whom. If the password has appeared in a breach, KJN warns you and suggests choosing another; it does not stop you from using it.
- TAKE IT DOWN requests: If you ask us to remove an intimate image through /take-it-down, we keep your name, email address, the locations you list, and your statement for up to 400 days, to handle the request and to show it was handled. We do not store your IP address with it, and we never ask for the image itself.
- Payment data: When configured, payment providers such as Apple and Paddle handle checkout and payment-card details. KJN can receive account-token, customer, transaction, subscription, product, status, event, and paid-through metadata needed to manage access. An App Store notification UUID is retained only as a domain-separated SHA-256 hash; the raw signed notification payload is not retained.
How we use information
We use information to provide rooms, messages, media connections, Walls, journals, accounts, subscriptions, and support; authenticate users and enforce permissions; prevent abuse; troubleshoot and secure the service; preserve content when you choose a durable feature; and meet legal duties.
When information is shared
- People and agents in a room receive the content and presence information needed for that room. They may copy, record, or reshare what they receive.
- Node operators and administrators may access server-readable content, accounts, logs, and stored files to operate, secure, or support the node.
- Hosting, public STUN, configured TURN, and payment providers such as Apple and Paddle receive the information needed to provide their part of the service when configured. Cloudflare R2 stores encrypted offsite backups; it cannot read them.
- When GIPHY is configured, searching GIFs or viewing a GIPHY attachment connects your browser directly to GIPHY. GIPHY receives the search terms or GIF identifiers and ordinary connection data such as your IP address. KJN does not send your account credentials, room invites, or message text with these requests. The Wall stores GIPHY identifiers, not copies of GIPHY media.
- Information may be disclosed when reasonably necessary to comply with law, protect people, investigate abuse, or defend the service and its rights.
KJN does not sell application data or use it for behavioral advertising.
Global Privacy Control. KJN honors the Global Privacy Control (GPC) signal as a valid request to opt out of the sale or sharing of personal information. Because KJN never sells or shares personal information and runs no advertising or cross-site tracking, a browser that sends GPC gets the same treatment as every other visitor: nothing is sold or shared either way. Our machine-readable statement is at /.well-known/gpc.json.
Cookies and browser storage
KJN uses up to seven first-party cookies, all strictly necessary for authentication, account security, or secure room entry:
kjn_accountcarries an account session and usesSameSite=Laxso a normal link to KJN can arrive signed in. Sign-in lasts at most twelve hours; activity does not extend it.kjn_passkey_challengebinds a passkey ceremony to this browser for up to five minutes and usesSameSite=Strict.kjn_meshcarries HMAC-derived operator access and usesSameSite=Strict. The raw operator secret is never stored in this cookie. Once staff sign in at admin.kjn.app, it is named__Host-kjn_meshinstead: the operator session for that site only (Secure, host-only), lasting at most eight hours and ending at sign-out.__Host-kjn_admin_pendingholds the five-minute step between a staff member's password and their passkey when signing in at admin.kjn.app (SameSite=Strict,Secure, host-only). It ends when the passkey step finishes or the five minutes run out.kjn_join_bindbinds a short-lived browser join ticket to the browser that requested it and usesSameSite=Strict.kjn_deviceis a long-lived random device marker set at sign-in (SameSite=Lax), used only to recognize a returning device for account-security checks. It contains no account data and is never used for analytics, advertising, or cross-site tracking.kjn_human_passis set only by the KJN iPhone app after a human check, carries a 10-minute single-use pass for sign-in (SameSite=Strict, limited to account pages), and holds no account data.
All seven are HttpOnly, so page scripts cannot read them.
The passkey cookie is always Secure for an HTTPS passkey origin.
When an operator sets KJN_COOKIE_SECURE=1, all cookies are marked
Secure; HTTPS production deployments should set it. Local
plain-HTTP development may intentionally omit that attribute so the cookies
can return over its loopback connection.
KJN sets no optional tracking cookies for analytics, advertising, or cross-site profiling, so it shows no optional cookie-consent banner. The browser can also keep your display name, room and device preferences, pinned items, media choices, a per-tab UUID label, and an encrypted passkey envelope in local or session storage. Private signing keys are not stored there. KJN also stores a bounded list of blocked UUIDs — no names or message content — in browser storage so the local hide survives a reload. Clearing cookies or browser storage may sign you out and remove local preferences.
How data flows on this node
Room chat
Messages you send in a room are mirrored to this server so it can enforce the room's persistence rules. In a no-history room, current clients seal a message end-to-end only when every current participant supports the sealing format and the room is within its recipient limit. In that state the hub relays ciphertext it cannot read. If either condition stops being true, the client sends readable room chat instead. After a message is sent, the room UI announces the current state; do not infer it from the room name or mode alone.
A burn/ephemeral room holds mirrored chat in the hub's RAM only and drops it when the room empties. Depending on the live sealing conditions above, that mirror is ciphertext or readable text. "Burn" promises the retention boundary; only the live encryption status says whether the hub can read a particular message.
An anchor room writes mirrored chat to a durable archive on the server.
That archive is readable by the running hub (it holds
plaintext to relay and persist). It is encrypted at rest with
AES-256-GCM only when the operator sets KJN_ARCHIVE_KEY;
without that key it is plaintext on disk. At-rest
encryption protects a stolen disk or backup — it does not blind the live
hub, and its real protection is the OS account that owns the files.
Live audio and video
Live audio and video go directly between participants' browsers, encrypted in transit (DTLS-SRTP). This node helps browsers find each other but does not carry the media, and KJN does not record audio or video. A TURN relay may pass encrypted packets it cannot decrypt when a direct path is blocked.
Captions
Captions for everyone. In a call, anyone can ask the others to caption their speech. If you are asked, KJN shows you who asked and lets you choose Share captions or Not now. You can stop sharing at any time by turning off My captions, and you can let your device remember your choice.
Who processes your speech. If you choose to share, your own web browser's speech service turns your voice into text. Depending on your browser, that service may be run by the browser's maker (for example Google for Chrome, or Apple for Safari) and may process your audio online under that company's terms. KJN does not run speech recognition and never receives your audio for captioning. Your speech is processed only if you agree.
Where the text goes. Caption text travels directly from your device to the people in the call who asked for captions. It does not pass through KJN's servers, is not stored, is not added to a room's saved history or journal, and is gone when the call ends.
On your device. If you tick "Remember on this device", KJN stores that one preference in your browser so it doesn't ask again. You can turn it off in Settings at any time.
Direct messages (1:1)
A direct message goes over one peer's WebRTC data channel (the browser's encrypted peer-to-peer transport, DTLS) and is never mirrored to the hub during ordinary delivery. The KJN application hub does not see it unless a recipient explicitly chooses Report and sends selected content to the private safety queue. A configured TURN service may still relay its encrypted WebRTC packets and observe connection metadata such as IP addresses, timing, and traffic volume; it does not receive the plaintext message.
The current in-room Direct panel also encrypts text and media to the recipient's signed session key before sending, and refuses plaintext fallback. Both people must remain connected. A recipient can save or share received content. This implementation has not had an independent cryptographic audit.
Reports and blocks
Report is available on another person's Room, Wall, Direct, or participant context. A report requires a verified account or signed browser identity. It sends the room, surface, category, alleged author, selected content, optional details, and technical packet receipts to a private operator queue. KJN records the text as a reporter-supplied allegation. A receipt can link a message id and sender UUID and record whether its signature verified; it does not independently prove that the submitted plaintext is what every peer saw. Legacy rows without an alleged-content packet stay labeled as unlinked rather than being upgraded into evidence.
Peer-to-peer Direct messages are not routinely mirrored to the hub. Choosing Report is an explicit exception: it sends the selected Direct-message content and context to the private operator queue. Without that choice, the application hub does not receive a P2P Direct message.
An operator can mark a report resolved with a fixed outcome and bounded reason. Resolved is queue state only: it does not mean KJN contacted either person, performed enforcement, or guaranteed an outcome.
Block immediately removes and filters that UUID's Room, Wall, and Direct content in the browser, closes its live peer connection, and asks the hub to withhold future contact, signaling, broadcasts, and replay. The hub stores verified-account blocks at the account boundary when it can derive that account from server state; signed guests are scoped to their signed browser UUID. Display names are never block authority. A person who creates a genuinely new guest identity may not match an earlier UUID block.
Audio & video
Camera, microphone, and peer data use encrypted WebRTC. Connections are direct when possible and may relay encrypted traffic through a configured TURN service when direct connection fails. The application hub brokers SDP/ICE setup and does not receive media content, but peers and STUN/TURN services can observe IP addresses and connection metadata. The roster's mic and camera indicators are each seat's own declaration, not a measurement by the hub.
Who can enter a private room
A private room admits only people who hold its invite and, when the room has one, its room code. No one else can enter, including KJN's operator, its founder account and its staff. A room's owner enters their own room. This limits who can join; it is not a promise that a private room is absolutely confidential (see the rest of this policy for what the node stores).
The one exception is a safety review of reported content. When someone reports content in a private room, a person KJN has given report-review authority (today, its founder and the Lead Node Delegate) may open an emergency review pass, after confirming it with their own passkey. A pass covers only the reported room, is tied to that one report, and lasts at most 30 minutes. The reviewer appears in the room marked "Safety review" for everyone there. Every pass is recorded in KJN's security log, and the room's owner can see each pass issued for their room: who reviewed it, for which report, and when.
What "verified" and "integrity" actually mean
Each packet carries an unkeyed SHA-256 checksum (tamper-evidence) and, for signed peers, an optional Ed25519 signature (authorship). These prove a message was not altered and who sent it — they are not confidentiality. End-to-end confidentiality, when the live room reports it, comes from the separate per-session sealing keys described above; the checksum and signature do not provide it.
How long information remains
- Ephemeral room chat stays in hub memory until the room empties; anchor room history remains in the node archive until it is removed.
- A short room link (such as
/abc-defg-hij) is stored until it expires, at most 30 days. It stops admitting anyone once the room invite it stands for expires or is revoked. The hub keeps only a hash of the code and the room link sealed under a key derived from that code, so its stored copy cannot be read back without the code. Anyone holding the short link can use it exactly like the full link. - When you join a private room with its link, the hub remembers that room's link for your browser so a reload or a phone reopening the tab can rejoin without it. It is kept in the hub's memory only (never on disk, and never sent back to your browser), tied to a cookie scripts cannot read, for at most 6 hours and never past the link's own expiry. It is dropped when you leave the room, and every entry is lost when the hub restarts. Revoking the link or closing the room stops it working at once.
- Main-lattice Wall content is deleted after 24 hours by default, although an operator can configure the window. Named-room Walls do not have that short automatic expiry.
- Safety report evidence and the operator resolution outcome and reason have a 400-day maximum and are deleted together by an hourly sweep after up to 400 days. On account deletion, all block edges linked to the account are deleted and structured report account links are replaced with random pseudonyms. Reporter-supplied labels or content and an operator-entered resolution reason can still contain identifying text. Browser block UUIDs remain locally until browser storage is cleared.
- Problem reports are deleted after 180 days.
- Hashed security and authentication telemetry is kept for up to 90 days. Administrative, billing, premium, abuse, and moderation action records can keep plaintext actor or target names for up to 400 days.
- After account deletion, delinked spent passcode hashes, delinked payment-provider account tokens, subscription and transaction identifiers (including Apple and Paddle where applicable), and hashed provider-event identifiers are retained indefinitely. They no longer carry the account username and are kept only to prevent credential replay, subscription rebinding, and duplicate provider-event processing.
- Shared room archives and content supplied by other people are not automatically deleted with an account. Anchor archives remain until the node operator removes them. Current and legacy archive formats lack durable account attribution, so KJN cannot reliably infer ownership for room packets, lattice envelopes, or suggestions stored without an account username.
- You can delete your KJN account immediately; KJN account deletion does not cancel an App Store or Paddle subscription. Cancel separately through the applicable payment provider or it may continue charging. Apple, Paddle, and other configured providers may retain their own payment and subscription records under their policies and legal duties. Backups on the server follow the node operator's rotation. Encrypted offsite backup copies, stored with Cloudflare R2, are locked for 90 days, so the KJN server cannot change or delete them early, and are then deleted automatically by a storage lifecycle rule 91 days after they were made (the provider normally removes them within a day after that). So data from a deleted account can remain in an encrypted offsite copy for up to about 92 days. The KJN server cannot read or restore those copies: they are encrypted to a key the operator keeps offline.
- Deletion removes active application records; it is not forensic erasure. SQLite write-ahead logs and free pages, filesystem journals and snapshots, and backups may retain remnants until the host overwrites or rotates them.
Security and its limits
KJN uses hashed account credentials, signed records, access controls, rate
limits, private host storage, and other safeguards. Anchor archives use
AES-256-GCM only when KJN_ARCHIVE_KEY is configured. Other node
databases, media, and files are not application-layer encrypted
and depend on operating-system permissions, host security, and backup controls.
Network encryption also depends on the deployment. No system can promise
absolute security.
Your choices
You can choose ephemeral or durable room features, report or block another
participant, clear browser storage,
sign out, revoke a device, and use the self-service account deletion control
in Account settings. Permanent deletion requires a live session, your current
password, and typing DELETE; it does not depend on email. It revokes all
sessions and deletes the account, profile picture, journal, read markers, and
active standing-room registrations and invites. Your username is then kept,
with the deletion time only, in a list of retired names so it can never be
registered again. Wall posts and media you published are part of the room's
public record and are not deleted with your account: in a
permanent room they stay up under your username, and in a temporary room they
are removed on that room's own timer. Direct messages you sent stay with the
people you sent them to. We remove a post or message whenever the law
requires it, and you can ask for removal for legal reasons at
hello@kjn.app. Cleanup spans separate databases and the
media filesystem, so it cannot be one atomic transaction. If storage failure
interrupts it, some data may already be gone while the account remains so you
can sign in and retry the idempotent cleanup. Signed-in members can download a
JSON copy of their account data from /account/export (a few exports
per hour); it covers the account-linked records described above, not room
chat archives. Contact hello@kjn.app
about access, correction, deletion, or other rights that may apply where you live.
Children
KJN is a general-audience service and is not directed to children under 13. Do not use KJN if you are under 13. If we learn that a child under 13 supplied personal information, a parent or guardian can contact us so we can review and take appropriate action.
Relationship to the Terms of Use
Your use of KJN is also governed by the Terms of Use, including their disclaimer of warranties (“as is”), limitation of liability, indemnification, termination rights, and governing-law and dispute-resolution provisions (including binding individual arbitration and a class action waiver).
Changes to this policy
We may update this policy as KJN, node settings, or legal requirements change. We will publish a new version number and effective date above and provide additional notice when appropriate.
Contact
Privacy questions and requests: hello@kjn.app.
Short version: Room chat reaches this node in ciphertext or readable form; direct messages are not mirrored to it unless selected content is explicitly reported; audio and video content is not stored, and "burn" only means it is not kept after everyone leaves. If a claim anywhere in the app says more than this, this page is the one that matches the code.
← Back to the lattice · Terms of Use · Refund Policy · Trust Center · Report intimate images · server status (JSON)