C1 Identity & least privilege
Moderate 0.55 / 1.00
Jan runs as the desktop user and has no per-request authorization layer, but it deliberately narrows what its built-in tools can reach. The chat shell starts from an emptied environment with only a short allowlist of variables, and the user's home directory and the Jan data folder (settings, keys, models) are masked from it. Web search uses a keyless hosted provider by default, so no credentials are attached to built-in tools. MCP servers the user adds are the exception: they are started with the app's full inherited environment plus whatever keys the user configured for them.
C2 Approval gates
Moderate 0.57 / 1.00
Every MCP tool call asks the user first, unless they already trusted that tool or server. The prompt sits next to the full tool input and offers deny, allow once, allow for this chat, or always allow. Jan's own tools never prompt: web search and page fetches run unattended, and the shell runs without approval because it is confined to a disposable sandbox with no network. A single settings switch, off by default and clearly described, auto-approves every MCP call. 'Always allow' grants are stored in app settings with no screen to review or revoke them.
C3 Tool & action scoping
Minimal 0.45 / 1.00
Jan's file tools resolve and re-check paths against the workspace before writing, but the chat surface does not use them. Its default tools are general-purpose: a shell that takes any command string, and a web fetch that takes any URL. Both are bounded by other layers (the OS sandbox and a hosted fetch provider) rather than by argument validation. MCP tool arguments are passed through as given. Web access is on by default and can be switched off; the shell cannot be disabled on its own.
C4 Code-execution isolation
Strong 0.75 / 1.00
The chat shell runs inside an OS sandbox: bubblewrap on Linux, Seatbelt on macOS and AppContainer on Windows. Writes are limited to a per-conversation workspace, the home directory and Jan data folder are hidden, network is off, and the environment is emptied. If no sandbox backend is available the shell is not offered instead of running unconfined, and the desktop has no switch that runs it on the host. Two things limit it: the rest of the filesystem outside the home directory stays readable, and there are no CPU or memory limits. MCP servers the user adds run directly on the host.
C5 Untrusted input blast radius
Minimal 0.38 / 1.00
Jan does not separate untrusted content from instructions: web pages, search results, attached documents and MCP results enter the conversation as ordinary tool output. What limits a hijacked chat is that MCP actions always need a click and the shell has no network. But web search and page fetch run without approval and can request any URL, so injected text can send conversation content, attached documents or memory notes out through a fetched URL. Nothing irreversible can happen without a human in the default setup.
C6 Memory, context & configuration integrity
Moderate 0.57 / 1.00
Chat has one persistent store that reaches future conversations: memory notes, injected as background context into every chat. In the stable chat surface only the user writes them, by clicking Remember on a message or editing them in settings; the model has no memory-writing tool there. There are no workspace instruction files or project configs to auto-load. The concern is what happens once a note is poisoned: it has no expiry or provenance and is presented as the user's own notes in every later conversation, where it can steer tool use.
C7 Third-party extensions
Minimal 0.30 / 1.00
No third-party code runs by default: every MCP server in the shipped catalog is inactive, and adding one is an explicit user step. Once added, servers are launched as written, often through 'npx -y' with an unpinned or '@latest' package. Jan does not pin or verify them and does not prompt again when they change. They run as separate processes with the user's full environment. Model downloads are checked against a SHA-256 when one is known, and app updates are signed.
C8 Secrets & sensitive-data protection
Moderate 0.50 / 1.00
Provider and web-search API keys are kept in the OS keyring, with an encrypted owner-only file as a fallback, and are excluded from the settings file. Product analytics are opt-in, with autocapture and session recording off. The shell sees none of these keys because its environment is emptied and the data folder is hidden. Gaps: MCP server keys sit in plain text in the MCP config, MCP processes inherit the full environment, and nothing masks secrets in logs, transcripts or model-bound messages.
C9 Audit & traceability
Minimal 0.45 / 1.00
Every conversation is saved as a per-thread JSONL file in the Jan data folder, and each assistant message records its tool calls with their arguments and results. Denied calls are recorded as errors. Approvals and who gave them are not, and there is no audit trail separate from the editable chat history. Records are written by the app once a message completes, not as a durable per-action log.
C10 Limits & kill switch
Minimal 0.20 / 1.00
The chat tool loop has no step or token limit: it keeps calling the model as long as the model keeps asking for tools, until the user presses Stop. Individual calls are bounded. MCP calls time out after 30 seconds. Shell commands are moved to the background after 30 seconds (the model can choose a longer timeout), and Stop kills the conversation's shell process groups. The step and token budgets in the code apply only to the preview Cowork surface.