Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Threat Register

Status: Baseline 1.0 (2026-09-30), revised 2026-11-11 (RFC 022; earlier RFC 018; read with the threat model). A living document: it is reviewed at every milestone and whenever a data flow, an external integration or an authentication mechanism changes (project rule “Release Deliverables”).

Boundaries B1 to B6 are defined in requirements §3. Every threat names its controls as requirements and the tests that verify them.

IDThreatBoundaryImpactControlsVerified by
THR-01Indirect prompt injection: a page or snippet carries text meant to steer the modelB3, B4Unsafe agent actionsREQ-SEC-001, REQ-SEC-002, REQ-SEC-003, REQ-CTX-002, REQ-CTX-005, REQ-SEC-015REQ-TEST-007
THR-02Boundary forgery: external text imitates the envelope, a field, or a closing markerB4Injection appears as rypsok’s own statementREQ-SEC-002, REQ-CTX-003, REQ-SEC-016REQ-TEST-007
THR-03Hidden and invisible content: display:none, comments, zero-width and tag characters, bidirectional controlsB3Instructions invisible to a reviewerREQ-CTX-005, REQ-SEC-015REQ-TEST-007
THR-04Injection through the error path: provider or page text in an error, status or logB2, B3Injection bypasses the boundaryREQ-SEC-016, REQ-STATUS-002, REQ-ERR-004REQ-TEST-007
THR-05SSRF: a fetch reaches loopback, private, link-local, metadata or other internal destinations. The built-in refusal table follows the IANA IPv4 and IPv6 Special-Purpose Address Registries, read on 2026-11-03B3Internal network accessREQ-SEC-005, REQ-SEC-006, REQ-SEC-009REQ-TEST-005
THR-06Check-to-connect gap: the address validated is not the address connected to (DNS rebinding, address literals bypassing the resolver, environment proxies)B3SSRF despite validationREQ-SEC-007REQ-TEST-005
THR-07Redirect abuse: a public URL redirects to an internal destination or to a site the caller did not approveB3SSRF; bypass of a host’s own limitsREQ-SEC-008, REQ-FETCH-006REQ-TEST-005
THR-08Credential leakage on redirect: an engine’s key header sent to another originB2Key theftREQ-SEC-017REQ-TEST-015
THR-09Exfiltration through outbound parameters: a steered agent encodes secrets in a query or URLB1, B3Disclosure to a third partyREQ-PRIV-002, REQ-SEC-006 (operator lists), REQ-SEC-021 (strict mode), host expectation 4REQ-TEST-008, REQ-TEST-005
THR-10Accidental secret in a query or URLB1, B2Disclosure to a providerREQ-PRIV-002REQ-TEST-008
THR-11Resource bomb: oversized, compressed, deeply nested or slow responsesB2, B3Memory or CPU exhaustion, process deathREQ-PAGE-003, REQ-PAGE-006, REQ-PAGE-008, REQ-SEC-010, REQ-SEC-011, REQ-SEC-013, REQ-SEC-014REQ-TEST-006
THR-12Process death through parsing: panic, stack overflow, abort on panicB3Loss of service, and of the host if embeddedREQ-SEC-014, REQ-AGG-007, REQ-PAGE-006REQ-TEST-006
THR-13Denial of wallet and quota exhaustion: a looping agent burns a paid quota or triggers a banB1, B2Cost; loss of an engineREQ-MCP-010, REQ-CMP-002, REQ-RES-004REQ-TEST-016, REQ-TEST-017
THR-14Target-site abuse: rypsok used to flood or scan third-party sitesB3Harm to others; blocking of the operatorREQ-SEC-012, REQ-MCP-010, REQ-SEC-009REQ-TEST-006, REQ-TEST-016
THR-15Provider rate limiting, CAPTCHA and format driftB2Reduced coverageREQ-ENG-006, REQ-ENG-009, REQ-RES-002, REQ-RES-004, REQ-TEST-003REQ-TEST-002, REQ-TEST-003
THR-16Secret leakage through logs or debug outputB5Credential exposureREQ-PRIV-004, REQ-SEC-020, REQ-CFG-004REQ-TEST-008
THR-17Cache contamination: private or forbidden data served to another callerB4Disclosure; breach of provider termsREQ-CACHE-002, REQ-CACHE-003, REQ-CACHE-004, REQ-CMP-007REQ-TEST-010
THR-18Inbound DNS rebinding or CSRF against a local HTTP listenerB6A web page drives rypsokREQ-SEC-018REQ-TEST-014
THR-19Unauthorized network callerB6Resource consumption; data egress on someone else’s behalfREQ-SEC-018, REQ-SEC-019REQ-TEST-014
THR-20Provider impersonation or downgradeB2False resultsREQ-SEC-017 (HTTPS to configured hosts)REQ-TEST-015
THR-21Protocol corruption: a stray line on stdoutB1Loss of serviceREQ-MCP-002REQ-TEST-009
THR-22Supply chain: a vulnerable, license-incompatible or compromised dependency, including a CI action referenced by a moving tag—Any of the aboveREQ-SEC-020, REQ-TEST-012REQ-TEST-012
THR-23Non-determinism used to hide behavior or defeat tests—Untestable outputREQ-ARCH-004REQ-TEST-011
THR-24Misleading source metadata: homograph or confusable domains in a returned URLB4The caller trusts the wrong siteREQ-RANK-003 (hosts returned in ASCII form)REQ-TEST-007
THR-25A scraping driver runs against a provider’s terms, or imitates a browser to get throughB2The operator’s exposure; the project’s honestyREQ-ENG-013, REQ-ENG-014, REQ-CMP-004REQ-TEST-018
THR-26A slow or stream-flooding HTTP client exhausts the listener: a body sent a byte at a time, or one HTTP/2 connection opening many streamsB6Loss of service for other callersREQ-SEC-018, REQ-SEC-022REQ-TEST-014
THR-27Session exhaustion by legacy handshakes: one client opens handshakes until memory is goneB6Loss of service for other callersREQ-SEC-018, REQ-SEC-024REQ-TEST-014
THR-28The protocol library keeps state keyed by request content without a bound: from rmcp 3.0.0 to 3.5.x, StreamableHttpService cached every tools/call tool name, so that distinct names grew the process until it failed (RUSTSEC-2026-0461; rypsok 0.4.0 to 0.9.0 over HTTP)B6Loss of service for other callers; for any local process when no callers are configured, otherwise for an authenticated callerREQ-SEC-020 (the library no longer caches per request, since 3.6.0; advisories are checked by cargo deny on every push and before every release)REQ-TEST-012

Residual risks, accepted

RiskWhy acceptedOwner of the residual
A host that passes external text to its model as an instructionrypsok cannot control the host; it marks and documentsHost (external design §1.2)
A deliberate exfiltration that encodes a secret so that no pattern matchesPattern detection catches accidents, not adversariesHost: approve what leaves
Results poisoned by search-engine optimizationInherent to searchCaller
A caller times web_fetch to tell a name the policy refused from one that does not resolve (THR-05)The two answers are identical (unavailable, network), but their latency is not equalised: a refused name answers as soon as the resolver has judged it. Equalising it would add a delay to every failure; the policy’s purpose is met by the identical objectOperator
The session bound turns memory exhaustion into slot exhaustion (THR-27)One caller that passes the gate can hold every slot for the 300 s idle expiry of the SDK. Per-caller session quotas and a shorter expiry are deferred to the audit (M8)Operator
The SDK writes one ERROR log line per refused handshake, at a rate the caller sets (THR-27)Log amplification by a caller that passes the gate; filtering that log target is an M8 candidateOperator
The SDK writes the rejected Host or Origin value to the log at warn, up to the header bound LIM-H7 (16 KiB). It needs a local process (loopback, no callers) or an authenticated caller: in network mode an unauthenticated request gets 401 first (THR-27)The value is Debug-escaped, carries no query, path, content or secret, and the gate’s own event does not repeat it. Filtering or capping the SDK’s log targets is an M8 candidateOperator
Loss of health state at restartState is not retained by designOperator
Queries retained in memory for LIM-K2 while the cache is onA cache keyed by query is retention of queries; the configuration page says so next to the switch (REQ-CACHE-007)Operator
At most 200 characters of a provider’s error body in a debug log lineA driver’s author needs the provider’s words to classify a new failure; debug is explicit and the bound is a constant (external design §16 I5)Operator who enables debug

Review log

DateTriggerChange
2026-09-30BaselineRegister created from the draft threat lists, the startup findings and the consumer analysis
2026-10-20M1Controls verified by the M1 tests; THR-16 reviewed against the Secret wrapper and the log filter
2026-10-24M2THR-13 and THR-15 tied to the circuit breaker (REQ-RES-004)
2026-10-27M3THR-05 to THR-07, THR-11, THR-12 and THR-14 reviewed against the fetch pipeline and the egress policy
2026-10-27M4THR-18 and THR-19 added for the listener
2026-10-27M5THR-17 reviewed against the cache; the scraping threat added (as THR-20, renumbered THR-25 on 2026-10-27)
2026-10-27M7Revision against the delivered system (RFC 018): THR-22 extended to CI actions, THR-26 added, two residual risks recorded, the threat model page added
2026-10-29RFC 019THR-27 added (session exhaustion by legacy handshakes) with REQ-SEC-024 and LIM-H6; three residual risks recorded (slot exhaustion, SDK error lines, SDK warning with the caller’s Host or Origin)
2026-11-03RFC 020 (handoff 020h)THR-05: the built-in refusal table completed against the IANA special-purpose registries (six blocks added, special_purpose.csv as independent test data); THR-07: the target of every redirect hop is checked against robots.txt, the same host included
2026-11-11RFC 022 (022a)THR-28 added (an unbounded cache in the protocol library, RUSTSEC-2026-0461); rmcp 3.9.0. A gate check for unknown tool names was considered and withdrawn: it would have meant parsing request bodies and copying the library’s matching, against a flaw removed at its source; the guard against a regression is cargo deny