Security Model

August 16, 2026 · View on GitHub

dsh-shield is two layers that share one vocabulary.

                 DSH SHIELD

        ┌─────────────┴─────────────┐
        │                           │
        ↓                           ↓
 PREFLIGHT SECURITY            RUNTIME SECURITY
        │                           │
        ├─ Package Scanner          ├─ Tool Gate
        ├─ Source Scanner           ├─ MCP Gate
        ├─ Dependency Scanner       ├─ Egress Guard
        ├─ Script Scanner           ├─ Approval (official ask)
        ├─ Permission Inferencer    ├─ Sensitive Data
        ├─ Risk Engine              ├─ Injection Signals
        └─ Trust Manifest           └─ Audit Log

Shared: policy engine, risk model, finding model, trust manifest, security events, secret detector, redaction.

Decisions

DecisionMeaning
ALLOWExecute immediately
ASKOfficial PreToolDecision.askctx.approval.request. Missing approval denies.
DENYDo not execute. Re-asserted by ctx.tools.guard() so later hooks cannot restore ALLOW.

Risk engine

Deterministic. No LLM.

score = severityWeight[severity] * confidence * phaseWeight[phase]

severityWeight: info 0, low 1, medium 3, high 7, critical 12
phaseWeight:    install 1.4, runtime 1.0, unknown 1.1

critical if any finding is critical with confidence ≥ 0.7
else high    if any high finding with confidence ≥ 0.8, or max score ≥ 8
else medium  if max score ≥ 4
else low     if max score ≥ 1.5
else info

Incomplete scans never become an all-clear. Completeness is a separate field: complete | partial | failed.

Policy profiles

permissivebalanced (default)strictenterprise
local readallowallowallowallow
local writeallowaskaskask
destructiveaskdenydenydeny
external writeaskaskdenydeny
secret egressdenydenydenydeny
unknown MCP readallowaskaskdeny
unknown MCP writeaskaskdenydeny
unknown toolallowaskaskdeny

Profiles are different defaults, not aliases.

Invalid policy documents fail closed for high-risk decisions.

Secret handling

Detectors are regex + entropy heuristics. Matches are stored as redacted previews (sk-abc...xyz or [REDACTED]). Audit logs must not contain the raw value. Tests assert this with assertNoRawSecret.

Prompt injection

Detection + behavioral policy. We tag untrusted results (UNTRUSTED_WEB / UNTRUSTED_MCP) and raise the next dangerous call. We do not delete the original text. We do not claim prevention.

Local first

Scan, policy, and audit stay on disk. Source is never uploaded for "cloud analysis." There is no LLM in the security boundary.