Skip to content
DOCS — TRUST · PRIVACY & SECURITY

Privacy & Security

OpenMed is built for environments where operators need to see what the system is doing, where data is stored, and which external services are in the loop. This page describes the product as it exists today, not an idealized future control plane.

Runtime boundary

OpenMed itself runs locally. The TUI, session files, plans, cards, workflow artifacts, and local file operations all happen on your machine.

That does not mean every clinical capability is fully offline. Many medical functions depend on remote service boundaries:

  • The model or batch provider (openmed login / OPENAI_API_KEY / ANTHROPIC_API_KEY / OPENROUTER_API_KEY / MIMO_API_KEY / DOUBLEWORD_API_KEY, or a configured custom endpoint)
  • OpenMed's native medical service plane for extraction, PII, de-identification, terminology, education, HCC, and RAF tooling
  • User-added remote MCP endpoints

If you configure OpenRouter, prompts for general agent reasoning go to OpenRouter and on to whichever upstream provider serves the model you selected — one more hop than a direct OpenAI or Anthropic key. Review OpenRouter's privacy settings for how they handle and log your data. Provider credentials are never mixed: an OpenRouter key is only ever sent to OpenRouter, and an OpenAI or Anthropic key is never sent there.

With the MiMo provider, model requests go directly to https://token-plan-ams.xiaomimimo.com/v1 using your tp token-plan key. This is hosted inference; a token-plan subscription does not make the model local or offline. Workflow helper requests use the same provider and selected model. MiMo does not borrow another provider's credentials.

Doubleword real-time, Responses and Batch requests send their input to https://api.doubleword.ai/v1 and to the infrastructure serving the selected model. OpenMed stores the staged input and downloaded output/error JSONL under ~/.openmed/batches/ with owner-only permissions. It never stores the key in that job record. Individual Responses request/output snapshots are stored under ~/.openmed/responses/ with owner-only permissions. Direct JSON/JSONL input is not automatically de-identified, and TUI PHI mode does not transform it. Responses background jobs retain remote state for retrieval. See Doubleword before submitting sensitive data.

OpenMed does not assume every task belongs on the same remote boundary. General agent reasoning uses the configured model provider, while extraction, PII, de-identification, terminology, HCC, and RAF paths can run on dedicated protected medical-service planes. This split is designed to improve control, throughput, and cost efficiency for sensitive or high-volume clinical processing. The actual privacy and compliance posture still depends on where those services are hosted and governed.

Approval And Review Model

OpenMed does not stop for a modal approval before every tool call.

What happens today:

  • Deterministic workflows use a separate draft/finalize lifecycle, where final writes require an explicit host action plus a verified immutable draft snapshot
  • Final workflow bundles are staged privately and committed atomically only to a new, empty, or matching OpenMed-owned output directory; protected state and arbitrary nonempty directories fail closed
  • Approval dialogs for approval-gated tools such as edit_file are currently wired on the OpenAI SDK path
  • Read/search/extraction tools can run without a modal approval step, but their execution is still surfaced in the TUI with plans, tool-call messages, and results

If you need a stricter approval policy than that, the current docs should not imply you already have it.

Clinical file review

Start with the Clinical NLP guide for examples, redaction methods, language controls, PDF/image drafts and resumable batches.

For dedicated redaction, give deidentify_text the source file_path and requested output_path directly. The tool reads supported content internally, sends it to the configured NLP service, and returns counts, status and the output path. Reading the raw file into the conversation first can disclose it to the chat model.

File privacy is off by default. Select its mode with a host command:

Command Effect
/privacy-chat off Disable file privacy restrictions. Prompts do not turn them on.
/privacy-chat on Activate restrictions immediately. /privacy-chat is a shorthand.
/privacy-chat auto Clear any active restriction and wait for a recognized file privacy request.

You can change modes in the same session after the current turn finishes or stops. The command alone changes the setting without sending a model request. To also send a request, append it: /privacy-chat on Deidentify /path/note.txt. The older /privacy-chat Deidentify /path/note.txt form still enables privacy and sends the request. Attachments and file aliases are retained.

Only opt-in auto mode uses local phrase recognition. Familiar explicit prompts such as “Deidentify /path/note.txt” and “Mask personal info” with an attached file activate the restriction. Actions such as "extract" must directly refer to personal identifiers. Extracting clinical entities and mentioning patient identifiers elsewhere in a report request does not activate it. Recognition does not cover every language or wording; select on when it misses a request. Once triggered, auto stays active across follow-ups until you select off or reselect auto.

Once active, the host allows only inspect_file, deidentify_text, extract_pii, deidentify_batch and update_plan from its trusted built-in implementations. General readers, code execution, external tools and provider built-ins are blocked, including guessed tool calls and generic auto-approval. Attachments reach the chat model as paths only. The setting persists across follow-ups, model changes, session resume and forks, including whether auto has already activated. off restores the tools allowed by the other session controls; it does not change PHI or access mode. A fresh conversation with /clear starts with file privacy off. Ordinary model requests and SDK history resets cannot release an active restriction.

SDK applications select SDKConfig(file_privacy="off") (the default), SDKConfig(file_privacy="on") or SDKConfig(file_privacy="auto"). The legacy SDKConfig(file_privacy_mode=True) opt-in still means on. Existing saved sessions with an active legacy restriction reopen with it on; sessions without a setting start off. Unknown saved modes fall back to off; an actual legacy boolean true still restores the restriction. Malformed legacy flags do not enable privacy.

This restriction covers subsequent tool dispatch and attachment payloads. It does not scrub raw text pasted into a prompt, earlier conversation content or existing system instructions, and cannot undo earlier reads or tool side effects. A tool already running when the restriction activates has its later result, exception and progress withheld. Global FULL, DEID and STRICT modes remain separate controls. The dedicated privacy tools still send source content to the configured NLP service.

The v2 clinical profile accepts automatic or explicit language (de, DE, de-DE), patient/clinician roles, redaction categories and clinical preservation. It supports mask, remove, localized replacement, managed keyed hashing and explicit date shifting. The full date of birth is redacted. A higher detection threshold can leave more identifiers visible; it is not a general safety setting.

Unqualified model/language routes require explicit review_mode=true opt-in and return needs_review. These outputs are drafts for inspection, not clinically validated anonymization. Partial coverage and failed processing do not write an output. Writes are atomic and owner-only; source collisions and existing outputs are rejected unless a separate output is explicitly authorized for replacement.

In the TUI, /privacy opens a local review screen with language, method, role and category controls. It requires FULL mode and never changes PHI mode itself. Preview text stays outside the chat transcript and audit payload. “Save shown output” writes that exact preview, rejects a changed source and makes no second model call. Cancel closes an active preview request. The natural-language tool schema exposes these controls; a tool preview=true result is displayed in a transient local screen.

PDF, PNG and JPEG input is supported by the document preview endpoint when the configured service has document ingestion enabled. Files are limited to 8,000,000 bytes and eight pages; the service also enforces image-pixel, OCR-word and text limits. Set review_mode=true explicitly. The default output is .txt. The tool sends the file bytes directly to the configured NLP service without reading the file into the chat. It does not parse documents locally.

Default document output is an OCR text draft. OCR can omit or change identifiers and clinical text, including entire blank-recognition pages. Compare the draft with every source page before sharing. Document results retain complete=false, source_content_completeness=unverified and recognized_text_complete=true: the last flag describes processing of recognized text only. Failures or incomplete recognized-text processing produce no file. The original document is unchanged, including its metadata and text layers.

For a binary mask draft, use export_format="pdf" with PDF input and a .pdf output path, or export_format="png" with PNG/JPEG input and a .png output path. These exports require method="mask". The service burns padded whole-word masks into fresh page images and returns an image-only PDF or lossless PNG with no source metadata or searchable text layer. It verifies decoded pixels; the Agent checks the returned byte hash, format, page geometry and mask receipt against the OCR map before saving up to 32 MB atomically with owner-only access. These checks do not establish that OCR or identifier detection found everything.

Use ocr_languages=["de"], ["en"] or ["de", "en"] (the default) to select OCR packs. This is separate from language/lang, which controls privacy routing. The /privacy screen exposes both language controls and an output-format selector. Its text area is an OCR text preview, including when binary export is selected. “Save draft for review” writes the returned binary after checking the source path, bytes and format again, without another model call. “Open saved file” checks that the file still matches the saved hash and opens it in the system viewer. Inspect all exported pages alongside the source. Changing controls invalidates the preview. Tool preview=true saves no file and displays only OCR text, never the binary. Clinical/OCR qualification remains unfinished. These controls require a configured service with document previews enabled; the hosted preview supports them.

Both file review and normal privacy tools use hosted NLP when configured with a hosted service. This is distinct from chat-model disclosure and does not make the operation local or offline. The global preflight retains explicit mode selection and rejects review-required or incomplete v1 adapter results.

Resumable batch files

deidentify_batch and /privacy-batch process UTF-8 text, CSV or JSONL through the configured hosted NLP service. Choose the source, output, checkpoint, format and selected text column/field. The current preview supports up to 1,000 records, 20 MB per source and 100,000 characters per selected field. The TUI requires an explicit existing FULL mode; review mode starts unchecked.

For example: “Deidentify the clinical_text column of /path/notes.csv into /path/notes.masked.csv. Use /path/notes.batch.json as the checkpoint. Mask patient and clinician identifiers, language de. I accept an unqualified draft for review.” The agent passes file paths directly to the tool. Source text and transformed text do not appear in its summary.

Only the selected field is sent to NLP. Other fields remain local and are preserved in the output; they can still contain identifiers. Each row has a status. Pending and failed selected fields are blank. Plain-text output is written only when a complete usable result exists. Review-required results remain drafts, even when every row has finished processing.

New runs require new output and checkpoint paths. Both are written atomically with owner-only permissions on macOS/Linux. The checkpoint stores opaque row IDs, offsets, counts, hashes and job cursors; source/output text, keys and policy term values are excluded. A persistent .lock file holds only a fixed marker. Keep the original input, requested output and checkpoint together for resume.

Cancel saves completed rows and requests cancellation of active service work. Resume with the same paths and controls; only rows without a saved outcome are resubmitted after cancellation, job expiry or service restart. Resume rejects changed source/output bytes, owner, deployment, model, policy or hashing-key identity. A cooperating writer lock prevents simultaneous use of one checkpoint. Recovery reconciles interruptions between output and journal writes; it is not a transaction with unrelated programs editing the same files.

The remote job holds data in process memory until deletion or expiry (currently 15 minutes). The coordinator requests deletion after saving outputs; a lost connection can leave remote data until expiry. Managed authentication is refreshed between job requests. A timeout leaves the saved job identity available for an explicit resume. Bulk resume requires an attested service deployment and does not fall back to the legacy API. Neither hosted German qualification nor production promotion is implied by this workflow.

PHI Modes

OpenMed exposes three PHI modes in the CLI and TUI:

Mode Current meaning
full General-purpose clinical workflow context
deid Indicates a de-identification-first posture where the workflow/path supports it
strict Indicates a conservative handling posture for highly sensitive runs

Important caveat:

The current PHI mode setting is visible in the UI and persisted in session state, but it should not be treated as a universal enforcement layer by itself. Actual data handling depends on:

  • Which tool path or workflow you invoke
  • Whether that path explicitly calls deidentify_text or another de-identification step
  • Which remote boundaries are in use for model, native medical-service, or MCP access

In other words: treat PHI mode as operator-visible workflow context, not as a standalone compliance guarantee.

Local Storage

OpenMed writes local state to files such as:

  • ~/.openmed/sessions/ for persisted TUI sessions
  • ~/.openmed/sessions/<session>/draft_snapshots/ for private, immutable workflow drafts awaiting explicit finalization. The directory is owner-only, each snapshot expires after 24 hours by default (OPENMED_DRAFT_SNAPSHOT_TTL_SECONDS), and snapshots are removed after successful finalization, session clear/rollback, or session deletion. Non-session callers use the same default policy under ~/.openmed/draft_snapshots/
  • /tmp/openmed/artifacts/ and /tmp/openmed/cases/ by default for workflow outputs
  • ~/.config/openmed/ for config, MCP metadata, profiles, and user skills
  • ~/.openmed/auth.json for OAuth credentials
  • ~/.openmed/audit.json and ~/.openmed/traces/ only when optional audit traces are enabled or HF audit writes fall back locally

Optional Audit Trail

Audit traces are opt-in and off by default. When enabled, they write directly from the user's machine to the configured private destination:

  • private Hugging Face Dataset repo
  • private Hugging Face Storage Bucket
  • local-only trace directory

OpenMed does not send audit traces to OpenMed-owned infrastructure. Once audit is enabled, the default audit payload mode is payload, which stores the full private transcript and tool payloads in the configured destination. Use preview, fingerprint, or none when you need a smaller or less revealing trace.

phi_payload is separate from PHI mode:

  • PHI mode describes the operator posture for the run
  • phi_payload controls what the audit trace stores

Use openmed audit status and /audit to see the active audit posture. See Audit Trail for setup and trace contents.

Token Storage

openmed login stores credentials locally:

  • openmed login writes ~/.openmed/auth.json
  • Project-local ./auth.json is deprecated and ignored

The current implementation writes a normal local JSON file and sets restrictive file permissions where supported by the operating system. Teams with stricter requirements should still rely on OS-level access controls.

Network Access

OpenMed can access the network for:

  • Model traffic — prompts/responses with the configured LLM provider
  • OAuth and auth validation — browser login flow plus token validation/status checks when invoked
  • Native medical services — extraction, PII, de-identification, terminology, education, HCC, and RAF tooling
  • Optional audit writes — private HF dataset or bucket writes only if openmed audit enable has been configured
  • Remote MCP servers — only if you configure them
  • Self-update — release checks/downloads when you run openmed update
  • Connectivity checks — commands such as openmed mcp doctor

Outside those paths, the local runtime remains local.

See Native Medical Services for the deployment patterns behind those service planes.

No Telemetry

OpenMed Agent itself does not include in-product analytics, usage tracking, or background crash reporting. Public marketing and documentation pages may use lightweight site analytics to understand aggregate visitor traffic.

That statement does not cover third-party services you intentionally configure. Once you point OpenMed at a model provider, customer-managed native medical-service plane, or remote MCP server, the privacy and retention posture of that service becomes part of your real deployment boundary.

Practical Guidance

If you need the most defensible deployment story today:

  1. Keep sessions and artifacts on managed local storage
  2. Treat ~/.openmed/auth.json as the single OAuth credential file and protect the user account that owns it
  3. For customer-managed deployments, run native medical services on infrastructure you control or have vetted contractually
  4. Treat PHI mode as operator context, and verify the exact tool/data path for any sensitive workflow
  5. Use draft/finalize workflows so reviewers can inspect outputs before final writes