Security posture: mechanisms you can check
We describe what the code enforces. We claim no certifications.
Network surface
Exactly nine hosts are on the lookup allowlist, enforced in src/lib/net.ts before any request. DailyMed is link-only, the other eight are fetchable:
- eutils.ncbi.nlm.nih.gov — PubMed search + related via ELink
- pmc.ncbi.nlm.nih.gov — PMC ID conversion (PMID/PMCID/DOI)
- www.ebi.ac.uk — Europe PMC search + open-access fullTextXML sections
- api.fda.gov — openFDA label, FAERS adverse events, enforcement recalls, Drugs@FDA applications and counts
- rxnav.nlm.nih.gov — RxNorm normalization
- dailymed.nlm.nih.gov — DailyMed canonical link (no fetch, link only)
- connect.medlineplus.gov — MedlinePlus Connect (ICD-10CM/RxCUI handouts)
- clinicaltables.nlm.nih.gov — NLM Clinical Tables ICD-10CM resolution
- clinicaltrials.gov — ClinicalTrials.gov v2 (search, details, eligibility, investigators, endpoints)
Anything else throws before fetch. The PHI guard (dsh-medseek/guard) screens outbound arguments for high-confidence identifier patterns and denies or escalates per mode: block | ask | off.
Supply chain
- npm publishes via trusted publishing (GitHub OIDC): no long-lived tokens, SLSA provenance on releases.
- Lockfile committed; dependency audit runs in CI.
- Pinned upstream dependency line with compatibility checks per upstream tag.
Data handling in one paragraph
The plugin never receives PHI from anyone: it is source code an operator deploys inside their own dsh instance. Drafting/checklist/de-id tools make zero network calls. Audit receipts store digests only. dsh itself persists session logs under its home directory - treat that location per your organization's policy; the plugin's docs spell out where every byte goes.
Contracting notes (BAA, DPA, on-prem)
MedSeek is source code you deploy inside your own DeepSeek Harness instance, not a hosted service. There is no MedSeek service to sign a BAA with. The relevant BAA is between you and whoever operates your LLM endpoint and your hosting environment. Run against local weights or a BAA-covered endpoint; keep telemetry off; treat $DSH_HOME/sessions per your retention policy (session logs persist every tool argument and result — see Audit trail). For evaluators, the gap audit lists every outbound host and payload; the permissions page spells out every file write.
Need procurement language: copy the nine-host table above into your data-flow annex, cite src/lib/net.ts as the enforcement point, and attach docs/permissions-and-data.md + docs/feynman-gap-audit.md from the repo. No DPA is offered by the project — yours governs your deployment.
Deployment you can verify today
pnpm verify— typecheck, 173 tests (synthetic fixtures only, no outbound fixtures), bundle, declarations.pnpm test:mount— packs the tarball into a scratch dsh profile and asserts the plugin layer mounts, plus everylib/types/*.d.tsexists.pnpm test:persona— boots a real web session against a stub LLM and asserts the clinical persona arrives and the full 19-tool roster mounts.- Reproducible eval —
pnpm evalregenerateseval/REPORT.mdfrom the committed synthetic corpus.
Report a vulnerability
Private reports only via GitHub private vulnerability reporting on the repository. See SECURITY.md for scope and response expectations.
Threat model page: planned (see repository strategy/OPERATIONS.md gap list).