SafetyCard Request a review

InkOS

Story-creation AI agent (Studio web app, CLI and TUI) for novels, short fiction, scripts, interactive fiction and translation.

github.com/narcooo/inkos · 2026-10-04 · 8fc2ae5

Defense-in-depth score

5.2 / 10

InkOS has no shell or code execution and routes every tool through one harness that logs each call before it runs and hides destructive deletion from the model. The main risk: a prompt-injected session can read the project's plaintext API-key file and send it to any URL through the material-ingestion tool, with no approval, because outbound fetches and all non-destructive writes run unattended. There are also no turn or spend limits.

Safest setup

InkOS gives the model no shell, logs every tool call before it runs and keeps deletion out of the model's reach. As shipped, writes and URL fetches run without asking, provider keys sit in plaintext inside the project, and nothing caps turns or spend, so the safest setup turns on confirmation for the model's own writes and builds limits around the process.

SetupHowWhat it gives you
Dedicated, low-limit keysGive InkOS its own provider keys, each with a spending limit set at the providerA key that leaves the project, or a session that loops, costs only what you allowed C8
Confirmation for model writesCopy the Profile you use into .inkos/profiles with inferredMutation set to confirmWrites and URL ingestion the model starts from chat wait for you to request them C2
Project-scoped readsKeep INKOS_AGENT_ALLOW_SYSTEM_READ unsetThe read tool's scope stays the project rather than your whole filesystem C1
Reviewed project skillsOpen projects whose skills and .agents/skills folders hold only SKILL.md files you have readProfiles activate the skills InkOS ships, not ones a project replaced C6
Its own container or VMRun InkOS in a container or VM whose network reaches only your model provider and the sources you researchAn outer boundary that narrows where fetched pages and data can go C3
A copy of the ledgerCopy .inkos/harness.sqlite and .inkos/sessions regularly to storage the InkOS process can't writeA record of every tool call that outlives the project folder C9

Approving with confidence

  • A new-work card shows a model-written title and summary; read its structured details before clicking.
  • Nothing ends a session on its own, so stop it from Studio once it runs past what the task needs.

Handling data

  • Studio saves provider keys in plaintext in .inkos/secrets.json with default file permissions; keep the project folder readable only by you and out of shared sync.
  • Session transcripts and the ledger keep tool parameters unredacted; store them like the manuscripts they cover.

Key gaps (1)

  1. Unattended exfiltration chain: the read tool can open .inkos/secrets.json and ingest_material will GET any attacker URL without confirmation. C5 · Untrusted input blast radius

Criteria

C1 Identity & least privilege

0.57 / 1.00

InkOS runs as the local OS user but gives the model no shell and no generic file access: every tool goes through one harness runtime that checks the active Profile's capability list and each action's risk class before running it. File tools are confined to the project directory by a path-containment helper. The weak spot is that the project directory itself holds the Studio API keys in plaintext (.inkos/secrets.json), and the model's read tool is allowed to read any file under the project root, so the agent's own credentials are within its reach.

C2 Approval gates

0.42 / 1.00

InkOS has a real host-side confirmation path: creating new works goes through a propose_action card that the user must click in Studio (or a slash command), and the one destructive tool (delete latest chapter) is hidden from the model entirely. But the shipped Profiles set every recoverable write to execute without asking, and the URL-fetching ingest tool is classed as an ordinary recoverable write, so outbound requests and all edits to manuscripts and story state happen unattended. The approval card shows a model-written title and summary alongside the structured payload.

C3 Tool & action scoping

0.45 / 1.00

The tool set is narrow by design: no shell, no generic HTTP client with methods, no SQL; tools are book-, chapter- and artifact-specific. File paths go through a containment check that is not a strict boundary. The URL ingestion tool accepts any http(s) URL with no host allowlist or block on localhost or cloud metadata addresses, which gives a hijacked agent an outbound GET channel and an SSRF primitive.

C4 Code-execution isolation

N/A · full credit 1.00 / 1.00

No model-reachable path executes code or shell commands. The core agent package contains no process-spawning or eval calls outside tests, and the spawn calls in the Studio and CLI packages only launch the Studio server, open a browser, build the frontend, or run the user-invoked 'inkos update' command.

C5 Untrusted input blast radius

0.05 / 1.00

InkOS reads plenty of content its user did not write: fetched web pages and PDFs, Tavily search results, uploaded files, imported chapters and canon. Nothing distinguishes that content from instructions once it is in context; tool descriptions merely say materials are 'reference only'. A hijacked session can, without any approval, read the project's stored API keys with the read tool and send them out in the query string of an ingest_material URL fetch. It cannot take destructive actions unattended, because deletion is hidden from the model and other writes are revisioned.

C6 Memory, context & configuration integrity

0.38 / 1.00

InkOS is built around persistent story state: truth files, summaries, materials, a retrieval index and session transcripts are written by model-driven tools and re-injected into later sessions. Work artifacts are revisioned, so poisoned state can be inspected and rolled back, and project Profile files cannot loosen the destructive-action rule. However, SKILL.md instruction files in the project's skills/ and .agents/skills folders load silently and can replace built-in skills that Profiles activate automatically, and restored transcript system messages are re-inserted into the system prompt. In CLI mode, project-scoped configuration is additionally not integrity-protected; Studio, the scored mode, is not affected.

C7 Third-party extensions

N/A · full credit 1.00 / 1.00

InkOS loads no third-party code at runtime: there is no MCP client, no plugin system that runs code, and no model-file loading. Skills are plain Markdown instructions (scored under C6). The only package install is the user-run 'inkos update' command for InkOS itself.

C8 Secrets & sensitive-data protection

0.30 / 1.00

Provider API keys entered in Studio are saved in plaintext JSON inside the project at .inkos/secrets.json, written with default file permissions. The Studio API only returns whether a key exists, which is the single masking path. There is no redaction anywhere and the model's read tool can open the secrets file, so a key can end up in model context, transcripts and outbound requests. No telemetry SDK is present.

C9 Audit & traceability

0.68 / 1.00

Every tool call passes through the harness runtime, which writes an 'action-started' event with the parameters, risk class and request source to a SQLite episode ledger before the tool runs, then a completed, failed or cancelled event, plus an event whenever confirmation is required. A JSONL session transcript is kept as well. The ledger lives in the project's .inkos folder with no tamper protection, but the model has no tool that can write there.

C10 Limits & kill switch

0.33 / 1.00

Each LLM request has a 5-minute deadline plus stream-idle deadlines, URL fetches time out after 15-20 seconds, and the user can abort a session, which propagates an abort signal into pipeline work. There is, however, no cap on agent turns, tool calls, tokens or cost per session, so a looping agent keeps running and spending until a human stops it.