Skip to content

Latest commit

 

History

History
135 lines (92 loc) · 19.5 KB

File metadata and controls

135 lines (92 loc) · 19.5 KB

Security and trust model

The toolkit bridges repository/forge content, OCR and its LLM/MCP providers, CI/operator configuration and secrets, and provider APIs. No input becomes safe merely because a trusted pipeline acquired it. This document distinguishes the current runtime from planned controls explicitly.

Threat model

Assets

Current assets include immutable base, source, reviewed-head, protected-target, and release identities; review integrity and coverage; private evidence, OCR results and session transcripts; configuration and receipts; CI, forge, LLM, registry, and MCP credentials; published packages and provider state.

Planned M5 assets, currently absent, add external-object confidentiality and integrity; provider-declared author/account classes; immutable context/DLP policy; bounded context records and completeness; opaque run-bound handles; retrieval, model-egress, publication, and retention projections; and context receipts.

Actors and attacker capabilities

A merge-request contributor can choose repository paths, blobs, title, description, labels, source branch, and text resembling reviewer/tool instructions. Repository content, OCR/LLM/MCP output, provider responses, inherited process state, and persisted artifacts are untrusted even when the toolkit produced an earlier copy. An operator controls CI configuration, direct MCP servers, commands, endpoints, setup, and credentials; a direct MCP server controls its tool descriptions, schemas, and responses. A compromised runner or same-owner process is stronger than an ordinary contributor and remains a host-level residual risk.

The planned M5 model also assumes mutable forge discussions, edits/reordering, automation or service-account impersonation, crafted references, externally controlled issue/page text, compromised adapter/MCP responses, cross-tenant identifiers, replay, and timing races. These planned inputs are not collected today.

Current trust transitions

  1. Repository paths and immutable Git blobs enter bounded collection and parsing.
  2. Provider MR metadata enters closed invocation normalization; target-derived policy comes only from the captured protected-target SHA.
  3. Persisted evidence, results, OCR configuration, sessions, and receipts re-enter hostile parsing or external retention boundaries.
  4. Typed evidence crosses into the compact bootstrap and mandatory read-only evidence MCP.
  5. Operator-configured direct MCP command/endpoint/setup/credentials cross into OCR; server-authored descriptions and schemas cross into plan and main model context; model-generated arguments cross to allowed tools; textual responses cross back to the model and OCR session.
  6. OCR findings and coverage cross into deterministic GitLab publication, suppression, and approval policy.
  7. A release candidate crosses protected-base authorization, publication, provenance, and live readback.

Security objectives

  • Repository and provider-controlled content remains data. It cannot promote itself into policy, tools, permissions, suppression, posting, approval, or release authority.
  • Every security-relevant claim remains bound to immutable identity, provenance, trust class, scope, and semantic applicability.
  • Bounds apply while data is acquired and emitted; malformed or exhausted domains degrade visibly without suppressing unrelated evidence.
  • Persisted state is accepted only through closed schemas whose related snapshots, indexes, deltas, and receipts agree atomically.
  • Model-selected tool arguments receive deterministic authorization and validation in application or server code; names, prompts, and schemas are not resource authorization.
  • Direct MCP credentials, tools, and content remain least-privilege and acceptable for both model egress and OCR-session retention.
  • Provider mutations bind reviewed identity where supported; ambiguous non-idempotent writes preserve prior state.
  • Secrets remain outside repository-controlled context, public notes, fixtures, and release artifacts.

Current generic external-MCP boundary (M3 established)

BL-011 used the production ocr-ci review path, official checksum-verified OCR 1.9.5, a disposable synthetic Git repository, owner-only isolated homes, a local OpenAI-compatible peer, and a real stdio MCP protocol peer. The qualification observed, rather than inferred from mocks:

  • toolkit configuration allowed only tenant_read and tenant_fail; the peer also advertised hidden_write and reserved file_read, but neither appeared as an external model tool, while toolkit reserved names and cross-server collisions failed before OCR;
  • a synthetic cross-tenant identifier generated by the model was forwarded unchanged to the allowed tool: the allowlist authorized only the tool name, not its arguments or object;
  • hostile server-authored description and schema markers entered the plan prompt and main tool definitions;
  • the same external tools appeared in plan and main phases; OCR has no toolkit-controlled phase-specific external policy;
  • a bounded high-volume text result was returned completely to the next model request, with no toolkit-configurable response byte/character boundary;
  • OCR's mode-0600 session JSONL retained prompts, responses, external arguments, tool results, and both plan_task and main_task records;
  • an MCP isError result remained model-visible and review continued; an unavailable optional server emitted a warning, review continued with mandatory evidence, and the receipt omitted the unavailable server;
  • _ocr_toolkit.mcp_usage counted one mandatory evidence call and two known external calls, but contained no arguments, results, completeness, content-safety, or model-correctness proof.

These observations establish the current safe-use envelope, not the safety of arbitrary direct providers. Generic external MCP is privileged operator-configured composition, not author-triggered reference resolution. Each direct server must independently authorize tenant, canonical object, fields, and operation for every request. Use only reviewed narrow read-only tools, dedicated least-privilege credentials, bounded responses, and content permissible to send to the LLM and retain in OCR sessions. Do not expose generic search, arbitrary URL/ID fetch, traversal, writes, or broad service credentials to merge-request-selected references. Every direct tool must be safe in both OCR phases.

Server command, endpoint, setup, schemas, descriptions, arguments, and responses cross separate executable or untrusted boundaries. setup is operator-owned shell configuration executed in the analyzed repository; keep it empty unless explicitly reviewed. Raw endpoint, setup, and credential values are not safe diagnostic material. Toolkit diagnostics avoid them, but OCR may emit operator-owned setup or transport details; keep those values non-sensitive and retain OCR stderr privately. Managed OAuth authenticates a client but does not authorize an object and remains conditional.

The direct MCP receipt proves only positive calls attributed from known tool names. It is operational attribution, not security evidence for resource authorization, completeness, response safety, actual semantic use, or model output. Security severity still depends on demonstrated reachability and impact: prompt-like or Markdown text is not code execution without a privileged action path, and same-owner artifact tampering is not an ordinary-contributor escalation without a lower-privilege writer.

Preserved current safety properties

  • Repository reads are bounded, rooted, symlink-aware, immutable-object reads that exclude common dependency/build trees and never execute repository content.
  • Review-invocation metadata admits only complete bounded title, description, labels, optional source branch, and source SHA. Unknown fields, URLs, profiles, comments, linked bodies, tokens, and arbitrary environment values are not collected. Invocation evidence cannot select authority and blocks automatic approval when admitted.
  • Generated Markdown neutralizes controls and GitLab quick actions. Actionable suggestions require exact reviewed-head proof; unverifiable replacements retain prose only.
  • Result and provider reads have byte limits; notes enforce character and UTF-8 byte limits; non-idempotent writes are not blindly retried.
  • Automatic approval binds the exact synchronized reviewed head and never removes an existing approval. Partial, warning, legacy, omitted, or mutable-context runs are ineligible.
  • Human replies are ownership boundaries. Merge-request source SHA, protected-target policy SHA, and merge-result SHA remain distinct.
  • The evidence engine stores recursively redacted typed facts/deltas in owner-only files and serves a closed bounded network-independent MCP. Absence supports a negative claim only for applicable complete scope.
  • OCR rules, decisions, and guidance come only from captured protected-target blobs; source changes cannot create policy. Full guidance remains untrusted context, not authority.
  • External finding images are disabled by default and, when enabled, use closed normalized display metadata only.
  • Markers, fingerprints, snapshots, and rollback logic constrain repeated runs. Secrets and credential-shaped values are redacted before operational output.

The evidence engine reads exact base/head Git objects without checkout, refuses symlinks and submodules, and separates collection, normalization, owner-only atomic persistence, hostile readback, and bounded MCP projection. Snapshot indexes must agree with admitted records; deltas are recursively re-redacted and re-bounded before IDs or responses are derived; colliding facts retain source paths; normalized mapping-key collisions fail instead of dropping a value.

Repository-owned OCR rules, accepted decisions, and root or nested AGENTS.md/CLAUDE.md guidance come only from immutable target blobs at the captured protected-target SHA while code deltas retain the forge diff base. Guidance changed on either side is excluded; source/head content never becomes policy evidence; applicable guidance is selected before blob reads and domain-isolated admission. Structured policy values are bounded before storage, after redaction, and on hostile load. Schema-v4 binds policy provenance to the policy snapshot and applicability to atomic base/head changed paths; older schemas retain explicit historical semantics. The bootstrap contains only bounded refs, counts, coverage, summaries, paths, diagnostics, and MCP instructions; full text remains untrusted evidence in the private store.

Ansible Galaxy requirements use the same immutable-object boundary. Relative includes resolve only to YAML blobs inside the authenticated tree; absolute, home-relative, escaping, symlink, and submodule targets fail. Independent depth, file, edge, item, and diagnostic limits keep degradation visible and bounded.

Planned and disabled M5 boundary

M5 bounded review-context enrichment is planned; no current release implements this section. .opencodereview/review-context-policy.json is not read today, discussions and references are not acquired, no context broker/store/handles exist, and context_list/context_get are unavailable. The following are requirements for future BL-023 implementation, planned / not proven until runtime and release qualification.

Planned data flow and trust transitions

  1. A forge adapter acquires bounded discussion snapshots and reference-bearing text before OCR.
  2. An immutable policy read only from the captured protected-target SHA decides admitted fields, provider-declared author classes, origins, tenant/resource classes, projections, budgets, and retention. Missing policy means disabled.
  3. A deterministic recognizer emits a candidate; reference presence is never authorization.
  4. An adapter performs object-level authorization and bounded version-aware retrieval.
  5. Allowed projections are normalized, DLP-filtered, and atomically stored in a run-local context store.
  6. Only successful storage mints an opaque unguessable run-bound handle binding adapter, tenant, canonical object, projection, version/ETag or digest, policy version, expiry, and run without exposing the upstream identifier.
  7. During OCR, the model may list/read only minted handles through fixed toolkit-authored closed-schema context_list and context_get tools in the existing toolkit MCP process. No upstream search, arbitrary ID/URL, external schema, redirect, traversal, write, or external network access exists in the model loop.
  8. After OCR, deterministic publication validation/DLP and retention are decided independently.

Planned control ownership

  • Forge adapters own discussion snapshots and provider-declared account classes.
  • The protected-policy loader owns admission and independent retrieval, model-egress, publication, and retention decisions.
  • Recognizers own syntax only; adapters own resource authorization and bounded acquisition; the context store owns atomic records and handle binding.
  • The existing toolkit MCP owns fixed context projections; OCR owns the model loop and session persistence; toolkit review/post owners enforce cleanup, approval ineligibility, and publication validation.

Planned controls and abuse cases

  • BOLA/confused deputy and credential mismatch: authorize exact tenant, object, operation, and fields in adapter/application code; use dedicated AI-readable corpora and least-privilege credentials. Host allowlisting and successful authentication are insufficient.
  • Prompt and indirect injection/data poisoning: keep external text non-authoritative; use fixed toolkit schemas; prevent content from changing tools, policy, permissions, lifecycle commands, suppression, posting, or approval.
  • SSRF/traversal/broad agency: recognizers cannot fetch; the broker accepts only minted handles; generic search, URL fetch, redirects, recursion, and writes are absent.
  • Oversize/denial of wallet/selective omission: enforce acquisition-time character, UTF-8 byte, record, thread, age, count, time, and aggregate budgets independent of repository evidence; expose partial, mutated, unavailable, and omitted states.
  • Identity spoofing and privacy: represent authors by provider-declared class plus run-local pseudonym; omit name, email, avatar, and profile URL. Unknown classification fails closed.
  • TOCTOU/replay/cache poisoning: bind snapshots and handles to version/ETag or digest, policy version, run, and expiry; use atomic store commits and uniform unavailable outcomes.
  • PII/secret bypass and output laundering: make retrieval, model egress, publication, and retention separate decisions. Minimize before model egress; publication DLP cannot undo prior disclosure. Uncertainty blocks the affected projection.
  • Approval/suppression manipulation: any admitted mutable discussion/external context blocks automatic approval; partial context cannot prove absence or restore eligibility. Existing suppression, /ocr commands, and discussion ownership remain separate consumers.
  • Persistent-session leakage: run OCR under an isolated owner-only home and clean session artifacts deterministically. Containment/cleanup failure blocks publication unless an explicit secure-debug mode was agreed before execution.
  • Second-review-engine drift: OCR remains the sole review engine. If contextual adjudication needs a separate model phase, depend on a native structured OCR API rather than merge two toolkit-driven reviews.

Planned deployment assumptions and residual risks

Operators must maintain a dedicated AI-readable corpus and credentials whose service identity cannot read broader material than policy permits. Provider account classifications may be incomplete; unknowns remain unavailable. Model inference after egress cannot be reversed. OCR version/capability dependencies must be exact and fail closed. Even with bounds and DLP, admitted untrusted text can influence model judgment; deterministic publication checks contain authority but do not make model reasoning deterministic. A host-level compromise can read same-owner artifacts. These residuals remain visible in deployment guidance and qualification claims.

Deployment guidance

Use a dedicated bot and least-privilege forge token. Protect/mask credentials; do not expose secrets to untrusted forks. Begin with manual execution for trusted contributors and enable posting/approval only after accepting this threat model. OCR_AUTO_APPROVE=false keeps the bot comment-only; forge approval rules and protected branches remain authoritative.

Pin the exact recommended Open Code Review release from the compatibility manifest and verify its checksum. Pin Python and Actions dependencies. Follow the M3 direct-MCP safe-use envelope above and the exact public configuration contract.

Optional remote finding images add a third-party rendering boundary. External finding images are disabled by default. Finding badges are presentation-only; keep text mode when a third-party image request is unacceptable. Enabling Shields.io does not send finding prose, repository paths, project identifiers, or arbitrary OCR metadata in the image URL, but ordinary viewer, proxy, and network metadata can reach that service. Toolkit-owned Git ignores process/global/system/repository/object-store overrides and replacement refs. Existing OCR configuration is hostile persisted input and is descriptor-read, regular-file and single-link checked, byte-bounded, JSON-object validated, and atomically replaced with owner-only permissions before/after update.

The OCR compatibility policy requires double-source asset digest verification, bounded downloads, executed contract probes, and protected PR/release gates; automation never promotes ambiguous releases or writes directly to main. Remote MCP is HTTPS-only, forbids userinfo/fragments, and keeps secret headers environment-backed.

Release authorization executes from protected-base code predating the candidate. GitHub reads use a closed endpoint allowlist, HTTPS-only redirect policy, redirect-safe authentication, bounded transfer, atomic replacement, and exact receipt schemas. Bandit scans runtime source at medium-or-higher severity/confidence; narrow # nosec B108 temporary-path suppressions require adjacent containment rationale.

Standards and guidance

The M3 current boundary and planned M5 controls align with MCP authorization and MCP security best practices; OAuth resource indicators and best current practice in RFC 8707, RFC 9700, and RFC 9728; OWASP GenAI LLM risks and Agentic risks; OWASP API BOLA; and OWASP SSRF guidance. These references inform controls but do not themselves prove the implementation.

Repository security posture

Protected main requires pull requests, signed commits, a current branch, resolved review threads, and required CI/security/build checks. One maintainer cannot provide independent human approval for maintainer-authored changes; automated review does not replace a second human. OpenSSF findings are posture signals, not vulnerabilities by themselves. The reporting process is in SECURITY.md.