# Security Policy ## Supported versions Security fixes target the latest maintained release. Older versions may require an upgrade; see [published releases](https://github.com/GreenLv/dsh-session-insights/releases). ## Reporting a vulnerability Do not open a public issue for a suspected secret leak, unsafe installer behavior, or report-data exposure. Use GitHub's private vulnerability reporting for this repository when it is enabled. Until then, contact the maintainer through the private contact method on their GitHub profile and include only synthetic reproduction data. Never attach real DSH sessions, reports, caches, credentials, or semantic work directories. State the affected version, platform, DSH version, privacy mode, and a minimal synthetic reproduction. ## Native runtime permissions (0.7.0) Version 0.7.0 requires DSH `>=0.2.1-rc.2` and accepts only V4 input. Raw logs remain read-only; unsupported generations require upstream migration. Query leases are released before Worker analysis, and plugin disposal cancels and awaits owned work — including queued analysis: at most two runs analyze concurrently per plugin instance and a bounded queue of eight holds the rest, so slash-command and tool calls cannot multiply Workers without bound. The 64 MiB detached-snapshot bound does not limit the host query service's peak memory while opening a large log, and the per-Worker `maxOldGenerationSizeMb` limit caps one Worker's V8 old space, not host RSS. Official host recovery results (`TOOL_OUTCOME_UNKNOWN`, `TOOL_NOT_STARTED`) are classified as uncertainty records with side-effect caveats; they are never reported as confirmed failures or successful executions. RC.2 scheduled prompts, asynchronous question replies, subagent settlement notices and Team relay messages are counted as injected context and never treated as user work or authorization. Background-job settlements and delegation dispatches are registry/producer records, not user-task completion or resource-release proof. Working-directory changes are reported as project labels only in redacted/metrics modes; raw paths are not added to those reports. Resume binds an explicit run and its recorded selection scope: a resume cannot select another project or a wider privacy range, and ambiguous multi-run requests are refused with the candidate paths. The Bundle uses a Node.js worker for cancellable snapshot analysis. It does not launch Python, a shell or another executable. The worker receives an empty environment and an empty `execArgv`; interpreter discovery, inherited `PYTHONPATH`, Python startup hooks and forwarding of host credentials have been removed from the native path. The host still runs with DSH's OS permissions; a worker is not an OS security sandbox. - **Files and sessions:** reads selected `sessionQuery` snapshots in memory. Reports, bounded semantic evidence and validated outputs live in marked direct children of `$DSH_HOME/insights/runs`. The configured home may be an alias, but links below it, hard-linked files and special files are rejected on every artifact operation. Batch identifiers must occur in the run manifest. Artifacts use bounded reads and atomic replacement; new POSIX directories/files use `0700`/`0600`. Windows permissions follow the parent ACL, so use a private DSH home. These checks do not defend against an actively hostile process with the same OS account changing ancestors between filesystem calls. - **Credentials:** native analysis needs no separate API key and does not call an OS credential store. The host reads `DSH_HOME` or uses the OS home directory; the analysis worker receives no host environment. Session text may contain credentials. Redaction is defense in depth, not a guarantee that arbitrary input is safe to disclose. - **Network:** deterministic analysis has no upload channel. The default semantic workflow queues the current DSH agent to process bounded, sanitized evidence using its configured model provider. Provider credentials, retention, network access and charges follow that DSH configuration. `--deterministic` skips model analysis. Historical text remains untrusted data. - **Retention:** no shared native semantic cache is written. Each run keeps its reports and evidence for explicit resumption. `session_insights_cleanup(workdir)` previews a marked run; deletion additionally requires a one-shot human approval through the host approval service (`allowed-once` for exactly that call) — a model-supplied `confirm: true` alone never deletes anything, and hosts without an approval service fail closed. Typing the DSH command `/session-insights --cleanup --confirm` is the direct human entry. Cleanup refuses links, special files and unmarked legacy directories. It does not erase source logs, other runs or CLI caches. Deletion is not secure erasure and does not remove copies in backups or model-provider history. ## Known upstream dependency gap Six official DSH packages (`dsh-commands`, `dsh-llm`, `dsh-sandbox-policy`, `dsh-session-projection`, `dsh-session-title`, `dsh-tool-todo`) pin `zod@4.4.3` exactly, from `0.2.1-rc.2` through `0.2.1-rc.5`. [GHSA-mrhx-c7xc-m3w5 / CVE-2023-54404](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5) rates the affected versions high severity; the patched Zod version is 4.6.6. Session Insights does not fix that upstream pin. The advisory describes excessive memory allocation when a large array reaches a vulnerable schema-validation path and many elements fail validation. We have not established a reachable DSH exploit path or measured everyday trigger probability. Passing functional tests, bounded snapshot analysis and Worker limits do not prove that the host's schema-validation paths are protected. In the rc.5 dependency closure the picture is mixed: the full `@deepseek-ai/dsh` host tree resolves its top-level `zod` to the patched 4.6.7, while every exact-pinned consumer above still resolves 4.4.3, and this project's own DSH peer closure (rc.5) resolves `zod@4.4.3`. A host-level fix therefore does not remove the pinned copies. **0.6.1 (historical).** On 2026-10-26 the maintainer accepted this specific unresolved risk for the 0.6.1 release with the rc.2/rc.3 dependency cohort; the [exception recorded at v0.6.1](https://github.com/GreenLv/dsh-session-insights/blob/v0.6.1/config/dependency-audit-exceptions.json) names only that advisory, package and version. That grant expired by its own terms when the release version and reviewed dependency cohort changed: it has been removed from the current candidate and is not carried forward. **0.7.0 candidate (accepted known upstream risk).** On 2026-11-03 the maintainer accepted this unresolved risk for 0.7.0 only, scoped to the reviewed rc.2/rc.5 dependency, version, manifest, lock and host-queue identities and the two reviewed vulnerability graph variants. The corresponding exact-cohort policy is implemented in `config/dependency-audit-exceptions.json`. In local source checks, fresh production and full npm scans each reported 23 affected package entries under the single advisory and exited 1; the policy-aware assessment classified both as `accepted_known_risk`. The separately reviewed 24-entry report variant was also classified as `accepted_known_risk`. These are local results, not exact-commit CI results. This is a new decision, not a renewal of the 0.6.1 grant, and it does not mean the vulnerability is fixed, unreachable or absent from the audit. The 2026-11-02 rc.5 production and full scans reported the single direct Zod advisory with 23–24 affected package entries depending on the resolving npm version (one resolution includes `@deepseek-ai/dsh-typert-protocol`, whose `zod@^4.4.3` declaration locks the still-vulnerable 4.4.3). The decision is event-bound, has no calendar expiry or automatic monitoring, and ceases to apply upon a product version, bound dependency or host identity, or host-queue change; an advisory change, a graph outside the reviewed variants, or a clean patched closure also ends this decision and requires reassessment. New advisories, graph or dependency drift, missing scopes, invalid inventories, scanner or receipt failures must not inherit acceptance. A clean outcome requires a valid non-empty inventory; an accepted known risk remains distinct from a clean scan. The [upstream report](https://github.com/deepseek-ai/deepseek-harness/discussions/10847) tracks the pinned dependency problem. ## Dependencies and failures The Bundle requires Node.js `^22.19.0 || >=24.0.0` and DSH's `commands`, `tools` and `sessionQuery` services. Exact DSH peers remain in `package.json`. There are no additional npm runtime dependencies or install/build lifecycle scripts. The optional Python CLI is maintained separately from the native Bundle. Missing services, worker failure, unsafe filesystem targets and oversized input stop the affected operation. The native selection limit is 2,000 snapshots / 64 MiB serialized input, with at most two analyses running concurrently per instance; reduce the time window or filter by project rather than silently dropping sessions. JSON artifact reads and submitted model payloads are capped at 16 MiB. Model outputs are validated in memory before writing, including evidence ownership, enum values, privacy and prohibited completion fields. A rejected replacement preserves the prior validated output. Structured tool failures cannot be overridden by success-looking output text. Explicit fallback keeps a deterministic report marked as degraded. Failures may leave a marked partial run that can be previewed and cleaned up. The optional Python CLI bounds each session log read by decoded bytes, line count and single-line size; a log exceeding a budget is refused with an explicit `resource_limited_files` coverage count and is never silently truncated or replaced by an older generation. Zstandard blocks are decoded incrementally (at most 128 KiB of new output per call), and decoder windows are limited to 64 MiB. Truncated zstd frames, corrupt UTF-8 and oversized header frames are detected instead of silently dropping the tail. Native manifests are distinct from legacy Python manifests. Resume only accepts native manifests that record a selection scope matching the request; use the CLI to finish a legacy run or start a new native run. Shared CLI caches are neither imported nor removed. The optional disk-log CLI still requires Python 3.11+ and `zstandard>=0.23,<1`; `jsonschema>=4.23,<5`, `tzdata>=2024.1` (portable IANA calendar test data), and `semver>=7.7,<8` are development-test dependencies. The retained CLI's own Python processes and installer have the separate boundaries below. ## Optional CLI and installer These capabilities are separate from native Bundle installation: - The CLI reads on-disk logs under the selected DSH home and writes deterministic caches under its `insights/cache` directory (new POSIX directories/files use `0700`/`0600`; Windows uses ACLs (parent inheritance or private ACLs created by the Python runtime) and needs a private DSH home; a bounded header read gates scope, so out-of-scope logs are never parsed or cached; cache entries hold only a whitelisted, pre-projected session projection). Legacy cache versions from earlier releases are ignored, not imported; `dsh-session-insights cache` previews them and `--delete` removes only confirmed cache roots. Default reports use `insights/reports`; explicit output and semantic work-directory options can select other locations. Auto-created semantic work directories may be removed after finalization unless retained explicitly. The CLI can open a report with the system browser when requested. - `scripts/bootstrap.py install` creates a Python environment and runs pip, which may contact the configured package index. It installs under `$DSH_HOME/tools/dsh-session-insights` and `$DSH_HOME/skills/dsh-session-insights`. Replacement and uninstall require managed markers and reject symbolic-link targets. Uninstall can start a delayed Python cleanup process to remove the managed runtime. These guards do not create an OS sandbox or erase generated reports and caches. ## DSH STORE review [Issue #965](https://github.com/AI-Scarlett/DSH-Store/issues/965) reports file, command and credential permission signals. File access remains necessary. The 0.4.0 native implementation removes Python child processes and environment forwarding; the optional Python CLI remains in the repository. The STORE's [source scanner](https://github.com/AI-Scarlett/DSH-Store/blob/079faa9233570d671e0d83d688edfa2407a0d7c6/src/automation-source-policy.mjs) also treats `process.env` and credential-related keywords as credential signals; a signal alone does not establish credential theft. At the policy revision reviewed on 2026-09-20, [automatic approval](https://github.com/AI-Scarlett/DSH-Store/blob/079faa9233570d671e0d83d688edfa2407a0d7c6/registry/automation-policy.json) rejects these signals. Native hardening reduces real runtime capabilities but does not grant automatic approval; repository-wide scanning can still match the retained CLI, development scripts and credential-redaction vocabulary. The plugin may remain blocked until the STORE accepts a reviewed installation path or changes its policy. Source checks and CI do not establish STORE approval, installation in a real DSH Profile, or native runtime acceptance.