A ChatGPT-like AI chat app that implements unlinkable inference — AI inference where every request is verifiably decoupled from each other, and from your identity. Built by The Open Anonymity Project.
The web app runs entirely in the browser. Each session uses a fresh ephemeral access key obtained via blind signatures, so no party — including the OA system and the inference provider — can link your identity to your inference activity or link sessions to each other.
For Open WebUI and other OpenAI-compatible clients, the Go command-line daemon provides a local streaming API with ticket and zkAPI access, funding by Ethereum address, and Homebrew/systemd service packages. See its validation notes for current staging verifier, relay, and zkAPI settlement prerequisites.
The CLI has two commands: config for setup and changes, and serve
for inference. Install or update the 0.4.1 prerelease:
curl -fsSL https://github.com/OpenAnonymity/oa-chat/releases/download/daemon-v0.4.1/install.sh | bashThen configure and run:
PATH="$HOME/.local/bin:$PATH" oa-chat config
PATH="$HOME/.local/bin:$PATH" oa-chat serveIn current source, config shows status and checks setup immediately. Missing
profiles default to zkAPI on Mainnet with direct HTTPS. If funding is needed,
it displays a recommended $20 deposit, its ETH payment address and amount,
and a terminal QR code. config --network sepolia selects test ETH;
config --backend ticket selects tickets. Use config --edit for settings or
config --menu for wallet management. Sepolia asks for its shared access
password with input hidden before funding; Mainnet and ticket mode are
unaffected. Existing settings and wallet state are preserved. These streamlined
defaults and QR are newer than the published 0.4.1 installer above, which
still asks initial setup questions.
If funding is needed, approve the displayed principal and maximum fee, then
send ETH on the selected network to the displayed address. Configuration waits
for the funds, deposits automatically, waits for finality, and exits. serve
then runs the local inference API; missing prerequisites point back to config.
Stop the daemon before upgrading or editing configuration. Installation updates both binaries and preserves private state. See the CLI guide and installer options.
- Unlinkable inference: Every session uses an ephemeral, blind-signature-backed access key. The inference provider sees anonymous requests with no way to identify the user behind them or link them across sessions.
- Standalone: Pure ES modules loaded in the browser; no server required.
- Local-only storage: Sessions, messages, and settings are stored locally in IndexedDB. Network logs are memory-only (per tab). You have the only copy of your activity history.
- Streaming UX: Incremental token updates with reliable auto-scroll.
- Markdown + LaTeX: Rendered with Marked and KaTeX (self-hosted vendor assets).
- Model picker: Fuzzy search, pinned models, and per-session selection.
- Multimodal: Images, PDFs, Word documents (
.docx), and audio attachments. - Right panel: Ticket registration, access issuance/expiry, and an activity timeline (logs are memory-only per tab).
- Clone the repo.
- Install dependencies:
npm install
- Serve from the repo root:
npm run dev # visit http://localhost:8080npm run devnow initializes thenanomemsubmodule first, so a clone without--recurse-submodulesfails fast instead of serving a browser-sideGET /nanomem/browser.js 404.
Production build + preview:
npm run build
npm run preview
# visit http://localhost:8080Select oa-org at build time without changing source code:
OA_ORG_ORIGIN=https://org.staging.openanonymity.ai npm run buildOA_ORG_ORIGIN must be an exact HTTPS origin (HTTP is accepted only for
loopback development). If it is omitted, the build uses production oa-org.
index.htmlbootstraps Tailwind, Marked, KaTeX, then loads ES modules.app.jscoordinates state, components, streaming, and CRUD throughchatDB.services/inference/selects the inference backend;api.jshandles OpenRouter calls (fetch models, stream completions).db.jsprovides an IndexedDB wrapper for sessions/messages/settings (exported aschatDB).components/contain UI pieces (sidebar, chat area, input, model picker, right panel, templates, message navigation).services/provide logging, key storage, file utilities, ticket/key flows, provider icons, and theme management.local_inference/,embeddings/, andvector/are standalone modules for local/auxiliary inference and memory search (in development).chat/vendor/privacypass-ts/privacypass-ts.min.jsprovides blind signature operations via@cloudflare/privacypass-ts(open-source, Apache-2.0).
For a deeper breakdown, see AGENTS.md.
Unlinkable inference: No party — including the OA system and the inference provider — can link a user's identity to their inference activity. Blind signatures ensure the station cannot correlate ticket issuance (blind signing) to ticket redemption (ephemeral API key request). The ephemeral API key carries no user identity — the model provider sees anonymous inference from an ephemeral key with no way to identify the user behind it. Each session uses a different ephemeral key, so sessions cannot be linked to each other.
This is much stronger than pseudonymity — there is no stable alias on your data. The adversary observing requests cannot tell if 100 requests came from 100 people with 1 request each, or 1 person with 100 requests, or anything in between.
What OA does NOT claim: OA does not claim that prompts are hidden from the inference provider. Prompts must reach the model for inference to work. The claim is that prompts are unlinkable to your identity and to each other — the provider sees anonymous requests from ephemeral keys with no way to know who sent them or link them across sessions.
Zero trust on OA infrastructure: Users need not trust any OA-operated component (org, stations, verifier operators). The verifier runs in a hardware-attested enclave (AMD SEV-SNP) with open-source auditable code. Station compliance (privacy toggles, key ownership) is enforced using the provider's own APIs as evidence. Even a compromised OA operator cannot deanonymize users because no OA component possesses user identity in the first place.
For the detailed privacy model, see docs/PRIVACY_MODEL.md and the blog post Unlinkable Inference as a User Privacy Architecture.
- Keep devtools open — console warnings surface integration issues early.
- Source modules live in
chat/and can be served directly in dev; production builds bundle and minify output intodist/. - Debug logging is enabled on localhost and disabled in production builds (see
DEBUGflag inchat/config.js).
This project is licensed under the MIT License.