-
Notifications
You must be signed in to change notification settings - Fork 0
THREAT_MODEL
Sensitive assets are genealogy records, living-person status, notes, provider credentials, SQLCipher keys, prompts/responses, consent grants, and RootsMagic source files. Desktop assets additionally include opaque file grants, internal API bootstrap material, event streams, plugin packages, update metadata, release signatures, and support evidence. Data crosses boundaries at prompt-toolkit/Rich REPL input, one-shot CLI input, the sandboxed Electron renderer and preload bridge, the authenticated FastAPI sidecar, GEDCOM/RootsMagic parsing, the OS keyring, encrypted database, configured provider endpoints, and exported files.
The local operator is trusted to choose data and consent. The renderer, other local processes, imported genealogy content, file paths, plugins, packages, updates, retrieved text, and every model response are untrusted. The accepted desktop boundary and product decision are specified in ADR-0025.
untrusted GEDCOM / RootsMagic -> bounded parsers -> application services
|-> SQLCipher workspace <- OS keyring
|-> consent + minimization -> LLM HTTPS
+-> atomic local exports
The Top 10 is an awareness and prioritization baseline, not a proof of security. Each implementation issue must also select applicable, versioned OWASP ASVS 5.0.0 requirements and produce negative-test evidence. Controls remain planned—not effective—until that evidence passes.
| Risk | Applicability and controls | Verification |
|---|---|---|
| A01:2025 Broken Access Control | The app has no in-app user roles, but privileged operations still require narrow bridge methods, authenticated internal routes, scoped grants, capability gates, and immutable source policy (TM-I01, TM-A01, TM-F01). |
Sender/origin, unauthorized-route, disabled-capability, expired/cross-window grant, and traversal tests. |
| A02:2025 Security Misconfiguration | Secure Electron window defaults, restrictive CSP, denied permissions/navigation, loopback-only sidecar, packaged docs disabled, provider=none, restrictive permissions, and bounded limits (TM-R01, TM-R02, TM-A03). |
Clean-install, production-config, CSP, fuse, exact-host/header, console, and packaged-runtime assertions. |
| A03:2025 Software Supply Chain Failures | Locked Python and pnpm dependencies, minimal optional extras, pinned CI actions, Dependabot, audit, SBOM, signed packages, sidecar manifests, and provenance (TM-U01, TM-U02, TM-P02). |
Lockfile review, pip-audit, JavaScript audit, CodeQL, Semgrep, secret scan, CycloneDX SBOM, signature/provenance and revoked-artifact tests. |
| A04:2025 Cryptographic Failures | SQLCipher is required; high-entropy database/API material is never stored in renderer state; OS keyring, encrypted backups, signed packages, and expiring update metadata are the authority (TM-S01, TM-A01, TM-U02). |
Plaintext header, wrong-key, key-unavailable, bearer disclosure, signature, expiry, rollback, integrity, and backup tests. |
| A05:2025 Injection | SQL AST validation and authorizer, strict schemas, static IPC/endpoint allowlists, no generated command/code execution, raw-HTML denial, and untrusted prompt/model data (TM-I01, TM-L02, TM-P01). |
SQL/prompt/console/API/IPC/HTML/URI injection suites, schema fuzzing, and Semgrep/CodeQL. |
| A06:2025 Insecure Design | Renderer-compromise assumption, separated adapters/services, explicit consent, immutable inputs, opaque grants, abuse-case review, risk expiry, and Post-MVP gates apply before code (TM-R01, TM-F02, TM-L01, TM-C01). |
Architecture contract tests, threat-ledger review, source sentinels, offline tests, misuse cases, and G0-G4 exit evidence. |
| A07:2025 Authentication Failures | OS login is the no-auth product boundary; every sidecar route still uses a fresh per-launch bearer, pre-parse constant-time verification, exact host/version, and token-derived readiness (TM-A01, TM-A02, TM-A03). |
Missing/wrong/replayed token, startup race, timing, health/shutdown auth, wrong-host/version, and renderer-disclosure tests. |
| A08:2025 Software or Data Integrity Failures | Source hashes, SQLCipher integrity, validated DTOs/model output, atomic writes, sequenced events, signed packages/updates, and anti-rollback state (TM-F02, TM-E01, TM-U01, TM-U02). |
Hash, schema, sequence/gap, round-trip, partial-publication, tamper, wrong-platform, downgrade, rollback, and recovery tests. |
| A09:2025 Security Logging and Alerting Failures | Stable error codes and privacy-minimal structural evidence; payload/access logging is off; secrets, paths, genealogy data, prompts, responses, ports, and bearers are forbidden (TM-O01, TM-O02). |
Canary-secret scans across UI, API, stderr, logs, crash/support bundles, build artifacts, and release evidence. |
| A10:2025 Mishandling of Exceptional Conditions | Fail-closed provider/storage/API policy, typed error envelopes, timeouts, cancellation, bounded queues/reads, idempotent terminal states, atomic output, and safe rollback (TM-D01, TM-E01, TM-C01). |
Boundary/one-over, malformed input, disconnect/reload, worker death, keyring failure, disk-full, cancellation, restart, and rollback tests. |
| Risk | Controls and disposition |
|---|---|
| LLM01 Prompt Injection | Imported text is untrusted data; models receive no tools; generated SQL is parsed and authorizer-enforced. |
| LLM02 Sensitive Information Disclosure | Pre-render consent, minimal fields, living-person denial, OS keyring, encrypted optional retention. |
| LLM03 Supply Chain | Provider SDKs are optional and locked; dependency/SBOM/security scans gate release. |
| LLM04 Data and Model Poisoning | Retrieval is not implemented. Any future local index must fingerprint sources, preserve provenance, treat retrieved text as untrusted context, and detect stale/conflicting material before display or generation. |
| LLM05 Improper Output Handling | JSON Schema validation and length caps; output is never executable. |
| LLM06 Excessive Agency | No autonomous agents, tool calls, shell, interactive-console escape hatch, write-capable SQL, or automatic destructive decisions. |
| LLM07 System Prompt Leakage | Prompts contain no credentials; templates and untrusted content are separated; disclosure is treated as possible. |
| LLM08 Vector and Embedding Weaknesses | Embeddings/vector stores remain unimplemented. A future feature requires SQLCipher-local storage by default, workspace and consent partitioning, restricted-data exclusion, versioned invalidation, bounded retrieval, and explicit cloud-retention consent. |
| LLM09 Misinformation | Deterministic evidence remains authoritative; LLM adjudication is optional and cannot delete conflicts. |
| LLM10 Unbounded Consumption | Token, output, timeout, cost, model, purpose, and row caps are enforced. |
flowchart LR
User["Local operator"]
Renderer["Sandboxed React renderer\nuntrusted display and input"]
Preload["Static typed contextBridge"]
Main["Electron main BFF\nfile-grant broker"]
API["Authenticated FastAPI sidecar\n127.0.0.1 ephemeral port"]
Services["Existing Python services"]
Workers["Bounded parser and file workers"]
Files["Granted GEDCOM\nimmutable RootsMagic"]
Storage["SQLCipher workspace\nOS keyring"]
Providers["Explicit local or remote provider"]
PluginHost["Restricted Post-MVP WASI host"]
LocalProcess["Other local process\nuntrusted loopback client"]
Supply["Signed package and update channel"]
User --> Renderer
Renderer --> Preload --> Main --> API --> Services
Services --> Workers --> Files
Services <--> Storage
Services <--> Providers
API <--> PluginHost
LocalProcess -. "hostile probes" .-> API
Supply --> Main
| ID | Required control |
|---|---|
TM-R01 |
Renderer isolation: packaged local content only, contextIsolation: true, nodeIntegration: false, sandbox: true, global sandboxing, no <webview>, no remote code, and verified production fuses. |
TM-R02 |
Restrictive production CSP and app:// protocol: fixed asset/MIME manifest; no renderer network, frames, objects, forms, raw HTML, executable model output, service workers, or CSP bypass. |
TM-I01 |
Least-privilege IPC: frozen static asynchronous bridge methods, runtime schemas and size limits, main-frame sender/origin checks, listener cleanup, and no generic send/listen, dynamic channels, Electron objects, or synchronous IPC. |
TM-A01 |
Private internal API: loopback port 0, fresh 256-bit per-launch bearer through private stdin, exact host/version validation, no cookies/CORS/browser origins, and packaged docs disabled. |
TM-A02 |
Sidecar lifecycle: signed manifest-verified bundled executable, minimal environment, protocol/build handshake, one server worker, bounded restart, clean process-tree shutdown, and privacy-minimal stderr. |
TM-A03 |
Request integrity: authenticate every route before body parsing, compare credentials in constant time, reject proxy/origin/cookie headers and redirects, disable access logs, and require token-derived readiness proof. |
TM-S01 |
Secret boundary: Python SecretStore and the OS keyring are the only authority; renderer may set, delete, or check presence but can never read a value. |
TM-F01 |
Opaque file grants: native dialogs create high-entropy, window/operation-scoped, expiring, revocable grant IDs; renderer never supplies or receives unrestricted paths. |
TM-F02 |
Backend file safety: regular-file checks, realpath/fingerprint revalidation, ingress budgets, source/output non-aliasing, immutable inputs, app-owned scratch space, atomic outputs, and failure cleanup. |
TM-L01 |
Provider policy: explicit provider/profile/model/consent; HTTPS, DNS/private-address, proxy, TLS, host, and redirect validation; no ambient-key selection; provider=none remains network-free. |
TM-L02 |
Model-output safety: output is untrusted data, schema/length validated, rendered through an allowlist, and never executed as tools, SQL, Python, shell, HTML, or plugin code. |
TM-D01 |
Availability: bounded request/event/file sizes, queues, workers, memory/time/cost/token limits, cancellation, and deterministic overload errors. Public file boundaries use the typed limits and race checks in bounded file ingress. |
TM-P01 |
Plugin isolation: signed declarative manifests/UI, deny-by-default WASI host capabilities, and no renderer/main/native/Python plugin code. |
TM-P02 |
Plugin provenance: signatures cover the canonical package tree; publisher trust/revocation, safe extraction, compatibility, permission-diff approval, and restricted-host identity are verified before activation. |
TM-U01 |
Supply chain and updates: reviewed lockfiles, SBOM/provenance, signed/notarized packages, sidecar manifests, verified update metadata, ASAR integrity where supported, and tested rollback. |
TM-U02 |
Update freshness: signed expiring metadata binds platform, application/sidecar versions, hashes, sizes, key identity, and monotonic release state; downgrade and freeze attempts fail closed. |
TM-E01 |
Event integrity: bounded sequenced streams, acknowledgement/backpressure, gap handling, terminal-state idempotency, startup reconciliation, and no automatic replay of side-effecting work after output begins. |
TM-C01 |
Concurrency integrity: single-instance coordination, per-artifact output locks, optimistic revisions, and idempotency keys prevent duplicate mutations and concurrent publication. |
TM-O01 |
Privacy-minimal observability: allowlisted stable codes and hashes/counts only by default; no secrets, unrestricted paths, genealogy values, prompts, responses, or bootstrap material. |
TM-O02 |
Runtime evidence hygiene: access-log suppression, structural redacted stderr, crash-dump/support-bundle policy, canary scans, and development-tool restrictions prevent payload capture. |
Every row is an owned threat statement. "Negative" names the minimum planned adversarial test; the detailed test matrix belongs to Issue #131. A control is not considered effective until its named test and packaged evidence pass.
| Threat ID | STRIDE threat | Controls | Owner / gate | Planned negative test |
|---|---|---|---|---|
STR-R-S |
Spoofing: a forged child frame or origin invokes a privileged renderer bridge method. |
TM-R01, TM-I01
|
#100, #101 / G1 | Negative: wrong-frame, wrong-origin, destroyed-window, and navigation-race calls are denied. |
STR-R-T |
Tampering: malformed, oversized, or version-confused IPC changes privileged arguments. |
TM-I01, TM-D01
|
#101, #131 / G1 | Negative: schema fuzz, unknown-field, boundary/one-over, and prototype-pollution payloads fail closed. |
STR-R-R |
Repudiation: a privileged action or event cannot be correlated with its window, request, and terminal job state. |
TM-E01, TM-O01
|
#101, #104 / G1 | Negative: duplicate, gap, reload, cancellation, and terminal-state races remain attributable and idempotent. |
STR-R-I |
Information disclosure: bridge DTOs, errors, clipboard, or UI expose secrets, paths, provider payloads, or bootstrap material. |
TM-S01, TM-F01, TM-O01, TM-O02
|
#101, #105, #131 / G1 | Negative: canary values never appear in renderer globals, DTOs, errors, logs, crash/support artifacts, or snapshots. |
STR-R-D |
Denial of service: IPC or event flooding blocks main or exhausts renderer memory. |
TM-D01, TM-E01
|
#101, #104, #131 / G1 | Negative: rate, queue, payload, subscriber, reload, and stalled-ack limits return bounded coded errors. |
STR-R-E |
Elevation: generic IPC, Node objects, navigation, raw HTML, or weak fuses escape the renderer sandbox. |
TM-R01, TM-R02, TM-I01
|
#100, #101, #131 / G1 | Negative: absent-Node assertions, XSS payloads, unexpected navigation/windows, and packaged fuse inspection fail on any privilege. |
STR-A-S |
Spoofing: another local process races startup, replays a bearer, or impersonates the sidecar. |
TM-A01, TM-A02, TM-A03
|
#11, #102 / G1 | Negative: connect-first, missing/wrong/replayed bearer, false readiness, and wrong-binary tests fail closed. |
STR-A-T |
Tampering: host, version, proxy metadata, redirect, response, or build identity is confused in transit. |
TM-A02, TM-A03
|
#11, #102, #131 / G1 | Negative: wrong Host/version/content type/build, forwarding headers, redirect, malformed response, and port substitution are rejected. |
STR-A-R |
Repudiation: a sidecar request cannot be matched to a privacy-minimal result and terminal state. |
TM-E01, TM-O01
|
#11, #104 / G1 | Negative: duplicate idempotency keys, disconnect, cancellation, and restart retain one structural terminal outcome. |
STR-A-I |
Information disclosure: bearer, port, path, exception, request body, or response payload reaches renderer, process metadata, or logs. |
TM-A01, TM-O01, TM-O02
|
#11, #102, #131 / G1 | Negative: canary bootstrap/payload values are absent from arguments, environment, files, renderer, access logs, stderr, and support output. |
STR-A-D |
Denial of service: request, body, stream, readiness, restart, or shutdown storms exhaust the sidecar or app. |
TM-A02, TM-A03, TM-D01, TM-E01
|
#11, #102, #104 / G1 | Negative: pre-auth oversized bodies, slow clients, stream floods, restart loops, and shutdown races stay bounded. |
STR-A-E |
Elevation: arbitrary routes, commands, public binding, docs, CORS, or console dispatch make the sidecar a local privilege proxy. |
TM-A01, TM-A03, TM-I01
|
#11, #101 / G1 | Negative: non-loopback bind, unknown route/method, CLI name, docs/schema route, browser origin, and unmediated endpoint are unavailable. |
STR-F-S |
Spoofing: a symlink, replacement race, device, alias, or stale grant makes a different file appear selected. |
TM-F01, TM-F02
|
#103, #114, #131 / G1 | Negative: link/device, case/realpath alias, replace-after-grant, expired/cross-window grant, and fingerprint mismatch are rejected. |
STR-F-T |
Tampering: a source or existing output is overwritten, partially published, or changed during processing. |
TM-F02, TM-C01
|
#103, #114, #118 / G1 | Negative: source/output alias, concurrent writer, source-hash change, worker death, disk-full, and publish failure preserve sentinels. |
STR-F-R |
Repudiation: an import, export, backup, or mutation lacks source fingerprint and structural result evidence. |
TM-C01, TM-O01
|
#103, #123 / G1 | Negative: missing correlation/source hash, duplicate publish, and recovery paths cannot report an untraceable success. |
STR-F-I |
Information disclosure: records, notes, keys, paths, plaintext databases, scratch files, or backups escape. |
TM-S01, TM-F01, TM-F02, TM-O02
|
#103, #123, #131 / G1 | Negative: canaries are absent from DTOs/logs/temp remnants; plaintext, weak keyring fallback, broad permissions, and unencrypted backups fail. |
STR-F-D |
Denial of service: huge, recursive, corrupt, compressed, locked, or device-like input consumes memory, CPU, disk, or workers. |
TM-D01, TM-F02
|
#114, #118, #131 / G2 | Negative: boundary/one-over size/count/depth/ratio, parser complexity, cancellation, queue-full, and scratch-quota tests remain bounded. |
STR-F-E |
Elevation: parser features, SQLite extensions, path traversal, or inherited worker capabilities reach the host. |
TM-F02, TM-D01
|
#103, #114, #118 / G1 | Negative: traversal, extension loading, shell metacharacters, unexpected environment/socket/process access, and malformed native input fail closed. |
STR-L-S |
Spoofing: profile confusion, redirect, proxy, DNS rebinding, or ambient keys select an unapproved provider. |
TM-L01, TM-S01
|
#108, #110, #131 / G1 | Negative: absent consent, ambient-only key, redirect, changed DNS/private address, proxy, wrong TLS host, and profile/model mismatch are denied. |
STR-L-T |
Tampering: provider output, structured data, Markdown, usage, or finish state is malformed or adversarial. |
TM-L02, TM-E01
|
#110, #111, #112 / G2 | Negative: schema/length/sequence errors, raw HTML/SVG, unsafe URI/image, tool/code/SQL content, and usage mismatch remain inert. |
STR-L-R |
Repudiation: consent, provider/model identity, cancellation, usage, retention, or terminal status is not auditable. |
TM-E01, TM-O01
|
#108, #110, #111 / G2 | Negative: cancelled/disconnected/reloaded streams and provider errors produce one redacted terminal audit state. |
STR-L-I |
Information disclosure: living-person data, credentials, prompts, responses, or retained content reaches an unapproved endpoint or artifact. |
TM-S01, TM-L01, TM-O01, TM-O02
|
#108, #110, #131 / G2 | Negative: data-class/retention overreach, redirect, logging, crash, cache, and support-bundle canaries are denied or absent. |
STR-L-D |
Denial of service: token, retry, timeout, queue, stream, or cost exhaustion degrades the app. |
TM-D01, TM-E01
|
#104, #110, #111 / G2 | Negative: token/cost/time/retry/event bounds, stalled provider, stalled renderer, and cancellation return deterministic terminal errors. |
STR-L-E |
Elevation: model output gains tool, filesystem, SQL, Python, shell, HTML, or plugin authority. |
TM-L02, TM-P01, TM-I01
|
#110, #112, #125 / G2 | Negative: generated commands, tool calls, SQL, code fences, HTML, URIs, and plugin-like payloads remain display-only data. |
STR-U-S |
Spoofing: a plugin publisher, restricted host, package signer, update channel, or release identity is impersonated. |
TM-P02, TM-U01, TM-U02
|
#16, #125, #132 / G3-G4 | Negative: unknown/revoked key, wrong publisher/host/platform/version, and mismatched certificate/signature are rejected. |
STR-U-T |
Tampering: package tree, manifest, ASAR, sidecar, update metadata, or release artifact is modified. |
TM-P02, TM-U01, TM-U02
|
#16, #102, #132 / G3-G4 | Negative: unexpected file, tree/hash/size mismatch, post-sign mutation, expired metadata, and wrong sidecar fail offline verification. |
STR-U-R |
Repudiation: install, permission approval, enable, update, rollback, revoke, disable, or removal lacks evidence. |
TM-P02, TM-U02, TM-O01
|
#16, #126, #132 / G3-G4 | Negative: missing signer/version/permission diff/decision/release state prevents activation or an unverifiable success. |
STR-U-I |
Information disclosure: a plugin or updater receives undeclared data, secrets, paths, environment, network, or host resources. |
TM-P01, TM-S01, TM-O02
|
#16, #125, #131 / G3 | Negative: raw-secret, filesystem, environment, socket, clock, process, database, and provider access are absent unless a narrow declared host call allows it. |
STR-U-D |
Denial of service: archive bombs, plugin loops/event floods, updater failures, or rollback loops disable the app. |
TM-D01, TM-P02, TM-U02
|
#16, #125, #132 / G3-G4 | Negative: count/size/depth/ratio, CPU/memory/event quota, interrupted update, disk-full, and repeated rollback preserve the prior version. |
STR-U-E |
Elevation: scripts, eval, dynamic imports, native plugins, Python entry points, or unsigned updates execute with user rights. |
TM-P01, TM-P02, TM-U01
|
#16, #125, #131 / G3 | Negative: script/hooks/native code, WASI escape, renderer/preload/main imports, unsigned packages, and unapproved permission expansion cannot activate. |
An entry begins with inherent risk, before credit for controls. It may move to evidence-backed residual risk only after the linked negative tests, packaged assertions, and review evidence pass. A planned or implemented control without passing evidence does not reduce the risk rating. The evidence link, test environment, app/sidecar versions, reviewer, and date belong in the issue or release evidence, never private payloads.
| ID | Abuse case | Inherent risk | Controls, owner, gate, and planned negative test | Evidence-backed residual risk |
|---|---|---|---|---|
AB-01 |
A compromised renderer forges frames, invokes privileged IPC, or obtains Node/Electron objects. | Medium likelihood / Critical impact |
TM-R01, TM-R02, TM-I01; #100, #101, #131; G1/G2. Negative: sender/origin fuzz, absent-Node assertions, CSP/XSS suite, window inheritance, and packaged fuse inspection. |
Not reduced: implementation and packaged evidence pending. |
AB-02 |
Another local process races startup, probes loopback, replays credentials, or abuses health/shutdown. | Medium / Critical |
TM-A01, TM-A02, TM-A03; #11, #102, #131; G1/G2. Negative: private-stdin bootstrap, connect-first/replay/timing, token-derived readiness, pre-parse auth, exact-host, and process-tree cleanup. |
Not reduced: implementation and packaged evidence pending. |
AB-03 |
UI, generated contracts, logs, crash reports, backups, or support evidence disclose provider or SQLCipher material. | Medium / Critical |
TM-S01, TM-O01, TM-O02; #105, #123, #131; G1/G2. Negative: canary-secret scans across responses, storage, logs, crash/support artifacts, fixtures, and release evidence. |
Not reduced: implementation and packaged evidence pending. |
AB-04 |
A malicious or replaced GEDCOM exploits parser complexity, symlinks, aliasing, races, or partial publication. | High / High |
TM-F01, TM-F02, TM-D01, TM-C01; #103, #114, #118, #131; G1/G2. Negative: boundary/one-over, replacement races, worker failure, output locks, cancellation, and sentinel preservation. |
Not reduced: worker and packaged evidence pending. |
AB-05 |
Model Markdown uses HTML, SVG, handlers, schemes, images, links, or copied content to execute or exfiltrate. | High / Critical |
TM-R02, TM-L02; #112, #131; G2. Negative: AST allowlist tests for script, HTML, SVG, URI, image, copy, external-link, and CSP cases. |
Not reduced: renderer and packaged XSS evidence pending. |
AB-06 |
Provider/profile confusion, redirects, DNS changes, proxies, or ambient keys send living-person data to an unapproved endpoint. | Medium / Critical |
TM-L01, TM-S01, TM-O01; #108, #110, #131; G1/G2. Negative: explicit-profile/consent, redirect, TLS/host/DNS revalidation, proxy denial, and network instrumentation proving provider=none is offline. |
Not reduced: desktop contract and network evidence pending. |
AB-07 |
A provider or stalled renderer floods tokens, creates event gaps, prevents cancellation, or duplicates audit completion. | High / High |
TM-D01, TM-E01; #104, #111, #131; G1/G2. Negative: bounded queue/ACK, gap/duplicate/reload races, idempotent terminal transitions, startup reconciliation, and no post-output retry. |
Not reduced: streaming evidence pending. |
AB-08 |
A plugin impersonates a publisher, traverses extraction, expands permissions, or escapes into native/renderer execution. | Medium / Critical |
TM-P01, TM-P02; #16, #125, #131; G3. Negative: canonical signature, revocation, archive bomb/traversal/collision, permission diff, WASI escape, and restricted-host identity. |
Not reduced: Post-MVP feature disabled pending renewed review. |
AB-09 |
A compromised update channel serves a valid old release, wrong-platform sidecar, mutable artifact, or expired metadata. | Low / Critical |
TM-U01, TM-U02; #102, #131, #132; G4. Negative: offline signature, expiry, anti-rollback, hash/size/platform/version, revoked key, interruption, and recovery. |
Not reduced: distribution remains disabled pending evidence. |
AB-10 |
Two app instances or jobs publish the same output or repeat a mutation after a crash. | Medium / High |
TM-C01, TM-E01, TM-F02; #104, #117, #129, #131; G2/G3. Negative: single instance, idempotency, optimistic revision, artifact lock, crash recovery, and duplicate terminal state. |
Not reduced: concurrency and packaged evidence pending. |
- Critical or High residual risk cannot be accepted for an affected privileged, MVP, high-risk-capability, or distribution gate. It must be avoided or mitigated and verified.
- Medium residual risk may be accepted only by the repository maintainer and a security reviewer other than the implementer. Low residual risk still needs an accountable owner and recorded rationale when it affects a trust boundary.
- Every acceptance records the risk and evidence, rationale, compensating controls, accountable owner, independent reviewer, decision/review dates, and an expiry no later than the next release or 90 days.
- Expired exceptions fail the gate. Renewal requires current evidence and a new review; copying the old rationale is insufficient.
- False positives record the tool/rule/version, exact non-sensitive evidence, reviewer, and conditions that would invalidate the disposition.
- No finding is silently waived. The release rule is zero known untriaged Critical/High findings and zero expired risk acceptances.
The SSDF is outcome-based. This project uses its four practice groups as a continuous lifecycle, not a one-time compliance checklist.
| Practice group | AncestryLLM outcome and evidence |
|---|---|
PO |
Prepare the Organization: ADR-0025, this control/risk ledger, issue/path ownership, fictional-data policy, secure toolchain, review roles, severity/expiry rules, and G0-G4 criteria define the security requirements and development environment. |
PS |
Protect the Software: focused branches/worktrees, protected review, pinned CI actions, reviewed lockfiles, secret scanning, least-privilege CI, SBOM/provenance, signed immutable packages, and release access controls protect code and artifacts from tampering. |
PW |
Produce Well-Secured Software: threat modeling before code, strict types/schemas, narrow adapters, secure defaults, peer review, negative tests, SAST, dependency analysis, contract/fuzz/E2E tests, packaging assertions, and documented residual risk reduce introduced vulnerabilities. |
RV |
Respond to Vulnerabilities: SECURITY.md intake, SECURITY_RESPONSE.md, finding triage, owner/severity/expiry tracking, root-cause regression tests, revocation/emergency update plans, release evidence, and lessons fed back into controls address discovered vulnerabilities. |
Minimum pull-request evidence for desktop work includes:
- changed control, OWASP Top 10:2025, applicable OWASP ASVS 5.0.0, and NIST SP 800-218 mappings;
- positive, boundary, and negative tests with fictional canaries;
- formatting, lint, strict type checks, Python and JavaScript/TypeScript tests, Semgrep, CodeQL, secret scanning, dependency audit, and SBOM results as applicable;
- lockfile, generated-contract, build-output, source-map, remote-asset, CSP, Electron fuse/window, sidecar binding/auth, and package-signature evidence for affected boundaries; and
- every finding linked to a fix, evidence-backed false positive, or permitted time-bounded residual-risk decision.
| Gate | Exit evidence |
|---|---|
G0 — Architecture |
#98 records assets, actors, flows, STRIDE threats, AB-01 through AB-10, controls, risk owners, OWASP/NIST mappings, rejected designs, negative tests, and issue/path ownership. |
G1 — Privileged boundaries |
#11, #102, #100, #101, #103, #104, and #105 pass pre-parse authentication, exact-host/version, sender/origin, CSP/fuse, secret non-retrieval, grant/race, event/cancellation, redaction, and supervision tests. |
G2 — MVP candidate |
#118 and #131 provide packaged XSS, API/IPC fuzz, secret-leak, stream-race, GEDCOM, provider=none, accessibility, performance, SAST/dependency/SBOM, and three-OS evidence with no untriaged Critical/High risk. |
G3 — New high-risk capability |
#16/#125 plugins, #130 retrieval, #129 editing, and any new renderer network path remain disabled until renewed architecture review and all added control/negative-test evidence pass. |
G4 — Distribution and update |
#132 verifies app/sidecar integrity, signing/notarization, SBOM/provenance, update tamper/expiry/rollback/freeze handling, recovery, and emergency-response evidence on macOS, Windows, and Linux. |
Threat modeling repeats for a new boundary, endpoint, IPC method, provider, data class, parser/writer, plugin capability, updater, OS entitlement, remote-content path, cryptographic format, retention mode, diagnostic/export surface, or Critical/High incident; and before MVP or production release.
A release requires zero known untriaged Critical/High findings. Every relevant finding must link to a fix, accepted-risk rationale with owner/expiry, or false positive evidence. Manual Ancestry/Geni/MyHeritage import results and any control exceptions must be recorded in release notes. This model does not prove absence of vulnerabilities, and passing OWASP/NIST-mapped checks is not such a claim; it defines required evidence, accountability, repeatable validation, and fail-closed boundaries.
- Home
- CLI reference
- Interactive console guide
- Architecture ownership and dependency contracts
- Bounded file ingress
- Versioning and compatibility
- Continuous integration
- Release runbook
- Encrypted backup and recovery
- First-run storage diagnostics
- GEDCOM compatibility and release checks
- Built-in module authoring
- Privacy and consent
- Provider guide
- Local LLM benchmarks
- Local-first retrieval evaluation
- Wiki synchronization
- Wiki operations and recovery
- Security response checklist
- Electron and FastAPI desktop ADR
- Data-flow threat model and control matrix