luigidemasi commented on code in PR #6: URL: https://github.com/apache/camel-kit/pull/6#discussion_r4443622015
########## docs/security-model.yaml: ########## @@ -0,0 +1,634 @@ +# Machine-readable companion to docs/security-model.md (Camel Kit Security Model and Threat Model). +# The prose document is canonical; regenerate this file whenever it changes. +# Section references (4.x) point at the prose document. Disposition labels match the Apache Camel Security Model. +schema: camel-kit-security-model/1 +project: Apache Camel Kit (Kit and Knowledge products) +repository: apache/camel-kit +products: + - id: kit + path: kit/ + version: 0.4.2-SNAPSHOT + latest_release: 0.4.1 + - id: knowledge + path: knowledge/ + version: 0.0.3-SNAPSHOT + latest_release: 0.0.2 (published under the former io.github.luigidemasi coordinates) + index_release_channel: knowledge-index-v1-YYYY.MM.DD-HHMMSS +kit_source_baseline_commit: 70796c02 +knowledge_source_baseline_commit: 9c8173cb +repository_layout_commit: 9c8173cb +revised_at_commit: a19d0529 +date: "2026-10-22" +last_review_round: "2026-10-27" +status: draft - policy ratified 2026-10-27; acceptance pending verification items V1-V6 (tracked in #153-#158); revised 2026-11-02 after review round 3 +canonical: docs/security-model.md +umbrella_model: https://camel.apache.org/manual/security-model.html +reporting: + policy: SECURITY.md + process: https://camel.apache.org/security/ + private_list: [email protected] + asf_security_team: [email protected] + public_issues_for_vulnerabilities: forbidden + +roles: + - role: developer + trust: fully-trusted + note: Route author and operator of their own machine; flags, config files and design approvals are trusted input. + - role: developer-os-account-and-same-user-processes + trust: trusted + note: Outside the adversary model (luigidemasi/camel-kit#149). + - role: ai-coding-harness + trust: trusted-to-enforce-its-own-permission-model + note: Holds provider credentials; its model output - including the arguments it passes to MCP tools - is untrusted input. + - role: author-of-analysed-source-tree + trust: untrusted + note: Umbrella "Reading route sources without running them" contract applies, inherited in full (maintainer, 2026-10-27). + - role: far-side-services + trust: trusted-to-contact-at-pinned-coordinate + note: External MCP servers, Maven Central, ASF repositories, GitHub (raw, API, release assets); responses are data, never instructions. + - role: other-local-accounts + trust: weaker-adversary + note: Camel Kit must not widen what they can read. + - role: network-peer + trust: untrusted + note: TLS assumed; init redirects followed except HTTPS-to-HTTP; the Knowledge downloader validates each redirect target before the hop (#143). + +component_families: + - id: A + name: Kit workspace CLI + paths: ["kit/camel-kit-core (command, service, generator, catalog, config)", kit/camel-kit-main, kit/camel-jbang-plugin-kit] + entry_points: [init, doctor, doc, nextId, plan analyze, graph] + in_model: true + reachability: Reachable from a non-operator input (analysed tree via init --here, downloaded catalog content, model-authored pipeline artifact, another local account). + - id: B + name: Kit graph analysis + paths: [kit/camel-kit-graph] + entry_points: [camel-kit graph, init --here auto-analysis] + in_model: true + reachability: Reachable from the contents of the analysed tree (file bodies, names, symbolic links) without building or running the project. + - id: C + name: Kit skills, templates, traits, agent registry, workflow manifest + paths: [kit/camel-kit-core/src/main/resources/skills, kit/camel-kit-core/src/main/resources/templates, kit/camel-kit-core/src/main/resources/agents, kit/camel-kit-core/src/main/resources/workflow] + in_model: true + reachability: Only when a shipped instruction or generated artifact itself crosses a boundary it documents holding (allow-list, worker tool list, hook or guard, MCP coordinate or repository). The model disobeying an instruction is not a finding. + - id: D + name: Ship controller (Technology Preview) + paths: [kit/camel-kit-core ship/**, kit/camel-kit-core command/ship] + entry_points: [camel-kit ship, /camel-ship delegates] + in_model: true + reachability: Reachable from worker or native-result output, the staged or analysed tree, a Maven Central response, or another local account; never when it requires the developer's own OS account. + - id: E + name: Ship resolver and evidence payloads + paths: [kit/camel-kit-ship-resolver, kit/camel-kit-core ship/evidence/**] + in_model: true + reachability: Same as D. + - id: F + name: External MCP servers (Camel JBang MCP, Citrus MCP) + in_model: false + route_to: ["apache/camel (Apache Camel Security Model)", Citrus] + note: Kit's responsibility ends at the generated configuration (pinned coordinate, named repositories, allowed-tool list). + - id: G + name: Generated integration projects + in_model: false + route_to: [Apache Camel Security Model] + note: In model only for what Kit's gates claim about them (P10) and disclaim (4.9). + - id: H + name: Shipped but unsupported + paths: [examples/, tools/, camel-kit-dispatch/, src/test/**, .idea/, camel-kit.gif, .github/workflows] + in_model: false + - id: K + name: Knowledge product - MCP server, index acquisition, bundled embedding model, published index + paths: [knowledge/mcp, knowledge/embedding, knowledge/schema, knowledge/index, "knowledge-index-v1-* releases"] + entry_points: [camel_docs_search, camel_docs_component_info, camel_docs_cve_search, camel_docs_release_info, camel_docs_jira_lookup, camel_docs_validate_endpoint, camel_docs_index_info] + in_model: true + section: "4.4a" + reachability: Reachable from a tool argument, from the release-list, manifest or archive responses, from the cache directory contents, or by another local account; never when it requires the developer's own OS account. + - id: K2 + name: Knowledge indexer (maintainer build tool producing the index data) + paths: [knowledge/indexer] + entry_points: [-Prebuild-index build, index-release.yml workflow] + in_model: true + section: "4.4a" + reachability: Its inputs are upstream Apache sources at release tags, trusted; a finding needs hostile upstream content (adversary not in scope) unless the indexer breaks its own path or process boundary. + +processes_inventory_status: See 4.5 - each row records what the process does to the host and whether the statement is documented, code-inspected (V4) or maintainer-verified. + +entry_points: + - entry: camel-kit init + input: project name, --ai, --here, --force, -p, -c, --citrus-version, --source-platform + attacker_controllable: false + trust: operator + - entry: camel-kit init --here / --source-platform + input: existing source tree (graph analysis, runtime detection, merge of .codex/config.toml and opencode.json) + attacker_controllable: true + caller_must_enforce: Analyse only trees you are willing to read; building or running them is a separate decision. + - entry: camel-kit init (fetch) + input: catalog JAR, YAML schema, Kamelet listing, Maven search JSON, Citrus schema JAR, Forage catalog + attacker_controllable: network-peer-or-hostile-origin + caller_must_enforce: Trust the pinned HTTPS origins or use --no-fetch with a vetted cache. Redirects are followed except HTTPS-to-HTTP; no checksum or signature verification (accepted boundary, maintainer 2026-10-27). Kit's own parsing, extraction and path controls remain in scope (P4). + - entry: ~/.camel-kit/config.properties, .camel-kit/config.properties + attacker_controllable: false + trust: operator + - entry: camel-kit graph <sub> [root] + input: file bodies, names and link targets under root + attacker_controllable: true + caller_must_enforce: Confinement to root and bounded time and memory are claimed by P1; enforcement verification is V2. + - entry: .camel-kit/project-graph.json (graph output consumed by skills) + attacker_controllable: derived-from-tree + caller_must_enforce: Treat as data in prompts. + - entry: camel-kit doc check/stale/unstale + input: YAML frontmatter of model-authored pipeline artifacts + attacker_controllable: true + caller_must_enforce: Parsed as data; digests are staleness markers only. + - entry: camel-kit plan analyze + input: implementation-plan.md task metadata (model-authored) + attacker_controllable: true + - entry: camel-kit nextId <slug> + attacker_controllable: false + trust: operator + - entry: camel-kit ship --text / --document + input: context for the model + attacker_controllable: developer-supplied-but-loaded-context + caller_must_enforce: Do not pass secrets; third-party documents can carry instruction-like text. + - entry: camel-kit ship native result envelope (--result PATH; bob2-native, copilot-native, claude-native, codex-native) + input: stage result JSON and file proposals + attacker_controllable: true + controller_enforces: [strict JSON schema, approved path set only (route and test paths, pom.xml, .camel-kit/config.properties), known-secret scan before any write, then the Pi candidate checks] + - entry: camel-kit ship Pi RPC result and the staged candidate the worker edited (pi backend, default) + input: stage result JSON; files written in the staging workspace + attacker_controllable: true + controller_enforces: [strict JSON schema, tree policy, artifact validation (manifest, declared routes and tests, pom policy, Camel Main Java policy, Citrus dependency policy, launch surface), secret scan of changed material files, expression gate, deterministic validation] + note: Ordinary additional material files are accepted and published (P5). + - entry: camel-kit ship staged workspace / candidate tree + attacker_controllable: derived + controller_enforces: [tree policy, publication of every changed material file] + - entry: Ship resolver + input: Maven Central responses + attacker_controllable: true + controller_enforces: [checksum fail, exact coordinates, size caps, no redirects, SHA-256 content identity] + - entry: Ship environment variables + attacker_controllable: false + trust: operator + note: Sensitive-looking values redacted from evidence and scanned for leaks; passed to the Pi worker by design (maintainer, 2026-10-27). + - entry: shipped skills, templates, traits, agents/registry, camel-kit-workflow.yaml + attacker_controllable: false + trust: distribution + - entry: MCP responses, downloaded documentation, repository READMEs (consumed by the agent) + attacker_controllable: true + caller_must_enforce: Loaded context is data (context-authority.md); only purpose-specific validated fields carry data authority. + - entry: Knowledge camel_docs_* tool arguments (component, query, version, runtime, cve_id, severity, jira_id, uri, max_results) + input: strings and integers from the MCP client (the agent) + attacker_controllable: true + server_enforces: [Lucene query text escaped (QueryParser.escape), max_results clamped to 25, endpoint URI validated against the bundled Camel catalog only, no argument names a path, URL or command] + - entry: Knowledge release list, manifest and archive (GitHub releases API, release assets, or a configured manifest URL) + input: JSON release pages, index.json manifest, knowledge-index.zip + attacker_controllable: network-peer-or-origin + server_enforces: [release pages <= 2 MiB and <= 10 pages, tag pattern knowledge-index-v1-YYYY.MM.DD-HHMMSS, drafts and prereleases ignored, pagination must stay on the configured endpoint, manifest version must match the tag, format version 1 and embedding model and 384 dimensions checked, version name safety rules, SHA-256 of the archive compared with the manifest before unpacking, zip entries confined to the version staging directory, atomic activation, failed update keeps the previous version] + note: Trusted pinned origin (GitHub release of apache/camel-kit); a configured knowledge.index.url may use https or file anywhere and http only to a loopback host; every redirect target is validated before the hop (#143). + - entry: Knowledge configuration (knowledge.index.path/url/version/releases-url/cache-dir, KNOWLEDGE_INDEX_* environment, quarkus.http.*) + attacker_controllable: false + trust: operator + - entry: Knowledge cache directory (~/.camel-kit/knowledge-index) + attacker_controllable: same-user-only + server_enforces: [version directories must be real directories (no symlinks), current marker and etag validator rebound on each activation, staging cleanup under the update lock] + +configuration_variants: + - knob: camel-kit init --ai <target> + default: bob2 + effect: Selects which generated harness controls exist (allow-lists, read-only worker definitions, hooks, guard policies). + security_relevant: true + stance: documented per target in 4.5a; the Claude MCP grant is V3 + - knob: Generated MCP tool lists and Claude settings.json MCP rules + default: workflow manifest allowed_tools (read-only and generation helpers, no runtime mutation or control tools) + effect: Availability filter - Codex enabled_tools, Copilot tools, Pi directTools, Qwen includeTools. Approval only - Bob 2 alwaysAllow/autoApprove = manifest list; Claude Code settings.json permissions.allow mcp__camel__*, mcp__camel-knowledge__*, mcp__citrus__* = every tool of each server (.mcp.json autoApprove/alwaysAllow keys are not a Claude Code filter). Prompt before every call - Codex default_tools_approval_mode prompt, OpenCode permission ask, Qwen and Copilot prompts. Antigravity - full tool set, no generated approval. + security_relevant: true + stance: ruled 2026-10-27 - the Claude wildcard pre-approval is NOT the accepted posture; accepted posture is explicit grants aligned with the manifest allowed_tools, verified in the generated behaviour (V3). Until then the generated default is a documented deviation triaged VALID-HARDENING. + - knob: camel.mcp.repos, knowledge.mcp.repos, citrus.mcp.repos, camel.catalog.repos, JBang //REPOS + default: Maven Central, ASF public, ASF snapshots, Central snapshots + effect: Snapshot repositories serve mutable artifacts. + security_relevant: true + stance: ruled 2026-10-27 - snapshots retained for development with their mutability documented; release defaults pin released versions; snapshot mutability waives no other control + - knob: knowledge.mcp.group-id / knowledge.mcp.version (Kit's pin of the Knowledge server) + default: io.github.luigidemasi / 0.0.2 + effect: Kit launches the released 0.0.2 Knowledge server from its former coordinates; that release uses the standalone repository's original index download URL and does not support release discovery or pinning. + security_relevant: true + stance: documented (kit/README.md, knowledge/README.md); moving the pin to org.apache.camel is a release decision + - knob: camel-kit init --no-fetch + default: false + effect: Skips every init-time download. + security_relevant: false + - knob: camel-kit init --force + default: false + effect: Overwrites generated assets (data loss, not security). + security_relevant: false + - knob: -p key=value, -c path + default: none + effect: Overrides any distribution property including versions and repository lists. + security_relevant: true + stance: trusted input + - knob: camel-kit ship --ask + default: smart + effect: never removes pauses for ambiguity, not authority checks; not a safety mode. + security_relevant: true + stance: documented + - knob: camel-kit ship --backend + default: pi + effect: Pi worker gets read-only tools or, in EXECUTE, bash/edit/write inside the staging cwd, launched with --no-approve and --offline, inheriting the controller environment; native backends use the host's read-only subagent. + security_relevant: true + stance: ruled 2026-10-27 - Pi retained with the documented boundary (inherited environment, no process sandbox, exact-value scan of selected secrets); failures of the claimed controls remain in scope + - knob: camel-kit ship --accept-experimental + default: false + effect: Runs unverified Pi/Node versions. + security_relevant: true + stance: documented opt-in + - knob: camel-kit ship --maven-repository + default: <state root>/catalog-repository + effect: Checksum enforcement applies to downloads only; protecting the repository between runs is the caller's. + security_relevant: true + stance: documented + - knob: CAMEL_KIT_SHIP_STATE_HOME + default: unset (.camel-kit/ship/state in the project) + effect: Relocates run records, evidence, transcripts and the staged workspace. + security_relevant: true + stance: documented + - knob: camel-kit ship --stage-timeout + default: 10m + security_relevant: false + - knob: knowledge.index.path (KNOWLEDGE_INDEX_PATH) + default: unset + effect: Uses a local index directory in place; no network, no cache. + security_relevant: true + stance: documented (air-gapped and development use) + - knob: knowledge.index.url (KNOWLEDGE_INDEX_URL) + default: unset (release discovery) + effect: Explicit manifest URL; https and file are accepted anywhere, http only to a loopback host; a plaintext manifest from a remote host, or a redirect to one, is refused before any request (#143). + security_relevant: true + stance: documented; operator-selected origin is trusted input + - knob: knowledge.index.version (KNOWLEDGE_INDEX_VERSION) + default: unset (newest compatible published index) + effect: Exact index pin; never falls back to another version. + security_relevant: true + stance: documented + - knob: knowledge.index.releases-url, knowledge.index.cache-dir + default: https://api.github.com/repos/apache/camel-kit/releases, ~/.camel-kit/knowledge-index + security_relevant: true + stance: documented; operator input + - knob: quarkus.http.host-enabled / quarkus.http.host / quarkus.http.port (Knowledge SSE transport) + default: disabled (stdio only) + effect: Opens an HTTP/SSE listener without authentication on the configured host and port. + security_relevant: true + stance: documented opt-in; keep on loopback (4.10) + +claimed_properties: + - id: P1 + property: Source-reading contract for graph analysis, inherited in full from the umbrella model - no code execution, class loading, placeholder/secret resolution, network or child processes; always finishes in bounded time and memory; output is data. Bound in place - GraphBuilder 60-second timeout per parser other than the POM parser. Not yet verified - per-parser regression coverage (V1); POM parser bound, memory or file-size bound, confinement of reads to the analysed root when the tree contains symbolic links (V2). + violation_symptom: Child process, class loaded or defined from the source, outbound connection, read of a file outside the analysed root (including through a symbolic link), placeholder resolved, non-termination, or unbounded memory during graph analysis. + severity: security-critical (VALID regardless of the verification status in V1/V2) + provenance: contract - documented (umbrella) and maintainer (2026-10-27, Q1 and Q2); XML/StAX hardening documented (SecureXml, BizTalk parsers); GraphBuilder timeout documented; Java, Groovy, YAML, DataWeave, properties enforcement inferred (V1); confinement and resource enforcement inferred (V2) + - id: P2 + property: Hardened XML parsing at every XML entry point, including Ship pom.xml validation. + violation_symptom: XXE, SSRF or local file read through XML. + severity: security-critical + provenance: documented (SecureXml, BizTalk*Parser, ArtifactValidator) + - id: P3 + property: init confines its writes to the operator-selected target directory and removes only what it generated, through no symlink. An untrusted tree or a symbolic link that redirects a write outside the target is in scope; an intentionally operator-selected destination is authorized. + violation_symptom: File created, replaced or deleted outside the operator-selected target, or a write or deletion redirected through a symbolic link. + severity: security-critical when reachable from an attacker-controllable input (analysed tree, registry data); otherwise correctness + provenance: contract - maintainer (2026-10-27, Q9); deletion guards documented (GeneratedAssetCleaner, AtomicFileWriter); write confinement through symlinked subtrees inferred (V5) + - id: P4 + property: Pinned, named-repository supply chain for everything fetched or configured; Ship resolver uses fixed HTTPS Maven Central, checksum fail, no redirects, exact coordinates, size caps, SHA-256 content identity, isolated URLClassLoader payloads. Kit's own handling of what it downloads is in scope - catalog JSON is read from the JAR stream in memory, Citrus schema entries are written only inside the cache directory after a normalize/startsWith guard, Forage catalog entries are written by file name only. + violation_symptom: Unpinned coordinate, repository outside the named lists, download accepted on checksum mismatch (Ship), artifact outside its exact path, payload class loaded from elsewhere, or a downloaded artifact that escapes the cache directory or executes code through Kit's parsing or extraction. + severity: security-critical + provenance: documented (mcp-setup.md, distribution.properties, ShipMavenResolver, ShipJvmPayloadBootstrap, CatalogDownloader, CitrusSchemaDownloader, ForageCatalogService); in-scope clause maintainer (2026-10-27, Q7) + - id: P5 + property: Ship controller alone writes run state, commits transitions and decides what is accepted and published. Native backends - proposals written only for the approved route and test paths, pom.xml and .camel-kit/config.properties, after a known-secret scan; other paths rejected (ShipNativeWorker.applyProposals). Pi backend (default) - the worker edits the staged candidate directly; acceptance through tree policy, artifact validation (manifest, declared routes and tests, pom policy, Camel Main Java policy FORBIDDEN, Citrus dependency policy, launch-surface validation), secret scan of changed material files and deterministic validation; ordinary additional material files are permitted and published. Publication journaled, atomic, verified against the validated candidate, recoverable. + violation_symptom: Worker output changes a stage, pause or publication decision; a native proposal is written outside the approved set or without the secret check; a Pi candidate is accepted despite a tree-policy denial, a failing artifact or launch-surface check, or a verbatim secret; published tree differs from the validated candidate; torn publication left unrecovered. + severity: security-critical + provenance: documented (docs/commands.md, docs/ship-native.md, ShipNativeWorker, ArtifactValidator, ShipCamelMainBootstrap.validateLaunchSurface, ShipPublicationService); Pi acceptance and extra material files - maintainer, 2026-10-22 (review of #6) and 2026-10-27 (Q8) + - id: P6 + property: Ship tree policy - denied credential and state paths, protected and volatile classes, rejection of symlinks, hard links and special files, quotas (20000 entries, 64 MiB per file, 1 GiB aggregate, depth 128, 4096-char paths). + violation_symptom: Denied path enters a snapshot, workspace, prompt or publication; a link is followed. + severity: security-critical + provenance: documented (ShipTreePolicy, docs/architecture.md) + - id: P7 + property: Ship never persists provider credentials; sensitive environment values redacted from evidence, Stamp arguments and transcripts; verbatim secret in a changed material file rejected. Detection floor - exact UTF-8 values of sensitive-named environment variables of at least 8 characters. + violation_symptom: Provider credential unredacted in run state, Stamp, logs or a published file; a verbatim selected secret accepted in a changed material file. + severity: security-critical + provenance: documented (#149, LocalCommandRunner, ChangedWorkspaceSecretScanner); floor accepted as the claim - maintainer (2026-10-27, Q8) + - id: P8 + property: Ship validation isolated from the live project and the network - separate JVM, controller-resolved classpath, scrubbed environment, frozen read-only copy, owner-only directories, log cap, timeout, process-tree termination, endpoint stubbing, rejection of code-bearing YAML. + violation_symptom: Validation JVM reaches the network or live project, inherits caller secrets, writes outside private directories, or starts YAML that executes a script. + severity: security-critical (network/live-project reach, secret inheritance) + provenance: documented (EvidenceRunner, ShipCamelMainBootstrap, docs/commands.md) + - id: P9 + property: Ship Simple-expression gate - 16 KiB bound, no control/format characters, no indirect expansion. + violation_symptom: Expression with indirect expansion forwarded. + severity: hardening + provenance: documented (ShipExpressionPolicy) + - id: P10 + property: Generated harness assets carry the accepted least-privilege posture - read-only Ship workers, read-only Codex roles, Copilot deny hook, Pi guard policy, no HTTP port for the Camel and Citrus MCP servers, and MCP grants aligned with the manifest allowed_tools (no runtime mutation or control tools) - as availability filters for Codex (enabled_tools), Copilot (tools), Pi (directTools) and Qwen (includeTools), as Bob 2's auto-approval list, with Codex, Copilot, Qwen and OpenCode prompting before MCP calls and Antigravity receiving the full tool set without generated approval. Accepted Claude posture - explicit per-tool grants aligned with the manifest. Current generated Claude settings.json deviates - mcp__<server>__* pre-approves every tool of the three servers (V3). Claim is about the generated artifact; enforcement is the harness's. + violation_symptom: Generated asset grants more than the accepted posture - a worker with edit or shell tools, a filter or auto-approval list containing a tool outside the manifest allowed_tools, a prompt-mode target generated with auto-approval, a hook or guard that fails open on a documented pattern. The known Claude wildcard pre-approval is a documented deviation, not a breach - a report that only restates it is tracked under V3 (#155) as VALID-HARDENING until the template changes; a report that demonstrates a breach through the grant (a credential read or destructive action without a prompt, or any other in-scope boundary breach) is evaluated on that breach and its impact and is never downgraded to V3 or closed as its duplicate (maintainer, 2026-10-27, review of #6). + severity: hardening; security-critical when the widened grant reaches a credential or destructive action without a prompt + provenance: documented (docs/agent-architectures.md, docs/ship-claude.md, docs/ship-native.md, templates/mcp-configs/*, templates/claude/settings.json, Claude Code permissions reference); current Claude grant - maintainer, 2026-10-22 (review of #6); accepted posture - maintainer, 2026-10-27 (Q3) + - id: P11 + property: Stated resource bounds - route/Citrus YAML 2 MiB, native result 16 MiB and 1000 files, Pi prompt 1 MiB, Pi log 16 MiB, session 64 MiB, evidence log 64 MiB, stage timeout 10m, resolver 64 roots/512 artifacts/128 MiB JAR/4 MiB POM, tree quotas, migration-context depth 3 and 50 nodes; graph parsers other than the POM parser 60 s each (serves P1); Knowledge tool results at most 25 per call, release pages at most 2 MiB and 10 pages, manifest 5 s and archive 5 min deadlines. + violation_symptom: A limit not enforced at its documented value. + severity: hardening + provenance: documented (ShipArtifactLimits, ShipNativeWorker, PiWorker, EvidenceRunner, ShipMavenResolver, ShipTreePolicy, docs/commands.md, KnowledgeMcpServer, IndexDownloader) + - id: P12 + property: Knowledge server transport - stdio by default with no listening socket; the HTTP/SSE transport exists only when the operator enables it (quarkus.http.host-enabled=true) on the configured host and port. + violation_symptom: A listening socket without the opt-in, or on a host other than the configured one. + severity: security-critical + provenance: documented (knowledge/README.md "Running the MCP Server"); no-listener claim for the default configuration inferred (V6) + - id: P13 + property: Knowledge index acquisition integrity - a local knowledge.index.path is used in place without network; otherwise a published knowledge-index-v1-* release (newest compatible, or the exact pinned version) or an explicitly configured manifest is fetched with bounded pages and deadlines, the manifest must match the release tag, format version 1, the bundled embedding model and 384 dimensions, the archive SHA-256 must equal the manifest value before unpacking, zip entries are confined to the per-download staging directory, the version directory is activated atomically and must be a real directory, a failed update keeps the previous working index, and a pinned client never falls back to another version. Remote manifest, discovery and asset URLs, and every redirect target checked before the hop, must be https, or http to a loopback host only (#143). An unpinned client whose resolution fails falls back to a classpath-bundled index extracted into a temporary knowledge-index* di rectory that is removed on orderly shutdown; a pinned client does not. + violation_symptom: An archive accepted on SHA-256 mismatch; an entry written outside the staging or version directory; a version name outside the safe-name rules accepted; a pinned client using another version or the classpath fallback; a manifest from a different release tag accepted; a remote fetch or redirect issued over non-loopback http; activation of a partially unpacked version. + severity: security-critical (integrity and path escape) + provenance: documented (knowledge/README.md "Index Distribution", IndexDownloader, LuceneSearchService, apache/camel-kit#143) + - id: P14 + property: Knowledge tool arguments are queries, not code - camel_docs_* arguments are used as escaped Lucene query text, structured field lookups, version strings and an endpoint URI validated against the bundled Camel catalog; no argument names a file path, URL or command; the server spawns no process and performs no network access other than index acquisition. + violation_symptom: A tool argument reaching the filesystem, the network or a code path, or changing which index or files are read. + severity: security-critical + provenance: documented (knowledge/README.md tool table, LuceneSearchService QueryParser.escape, KnowledgeMcpServer MAX_RESULTS_CAP); no-process and no-other-network claims inferred (V6) + +correctness_only_properties: + - Deterministic graph merge order. + - Staleness digests in camel-kit doc. + - The Ship Stamp pass/fail derivation. + - Knowledge vector guard - the index carries an embedding-model stamp and a startup self-check re-embeds stored chunks; on mismatch vector search is disabled and search degrades to BM25 plus reranker. + +disclaimed_properties: + - id: D1 + statement: Not a sandbox or permission system for the AI agent; Iron Laws, constitution, checklist and context-authority are instructions to a model. + - id: D2 + statement: No defence against prompt injection beyond instruction. Boundary rule (maintainer, 2026-10-27) - an injection that breaks a documented tool, permission, parser or controller boundary is in scope; incorrect or insecure model output within permitted actions, without such a boundary failure, is not. + - id: D3 + statement: Ship is not a hostile same-user sandbox, credential broker, daemon or attestation system; Stamp and digests are not attestations. + - id: D4 + statement: Secret scan is a floor - exact UTF-8 matches of sensitive-named environment values of at least 8 characters; encoded forms and non-environment secrets are not detected; no comprehensive secret detection or confidentiality guarantee (maintainer, 2026-10-27). + - id: D5 + statement: Endpoint stubbing is not an OS sandbox; the Pi worker's cwd is not a filesystem sandbox; staging is not isolation (maintainer, 2026-10-27). + - id: D6 + statement: No signature or checksum verification for init-time downloads - TLS from pinned origins, redirects followed except HTTPS-to-HTTP (accepted boundary, maintainer 2026-10-27). + - id: D7 + statement: Snapshot repositories are mutable; no reproducibility or integrity claim; retained for development only (maintainer, 2026-10-27). + - id: D9 + statement: Validation of generated routes is a static quality gate, not a security audit. + - id: D10 + statement: Generated guards and hooks are deliberately narrow pattern lists. + - id: D11 + statement: --ask never is not a safety mode. + - id: D12 + statement: No protection of provider credentials from the harness or the model; the Pi worker receives the controller's environment by design (maintainer, 2026-10-27). + - id: D13 + statement: Camel Kit does not hold or verify the Camel runtime's security properties for generated projects. + - id: D14 + statement: Knowledge has no authentication or authorization on its MCP transport - stdio is the invoking user; the opt-in HTTP/SSE transport carries no authentication beyond its bind address. + - id: D15 + statement: Knowledge index integrity rests on HTTPS to the GitHub release origin and the SHA-256 in a manifest served from the same origin; there is no independent signature, and a configured http:// or file:// manifest is trusted as operator input. + - id: D16 + statement: Knowledge index content is upstream text (Apache documentation, release notes, advisories, catalog metadata) and may carry instruction-like text; results are data under context-authority.md. CVE and JIRA data are informational and best-effort (indexer-time NVD/CIRCL enrichment), not a complete advisory feed; camel_docs_validate_endpoint checks catalog syntax against one bundled catalog version, not security. + - id: D17 + statement: Knowledge cache metadata files honour the process umask and the archive extraction has no size cap; both rely on the trusted release origin and the user's home-directory permissions. + +false_friends: + - claim: The Iron Laws / constitution are enforced + reality: Enforced on the model by instruction; by machinery only in Ship's deterministic checks. + - claim: The Ship Stamp proves the integration is safe to release + reality: It records which checks ran on this machine, with redacted arguments, exit codes and log digests. + - claim: camel-kit doc check detects tampering + reality: It detects staleness of pipeline artifacts by digest; anyone who can write the file can rewrite the digest. + - claim: The safety hook / guard makes autonomous runs safe + reality: It blocks a short list of obvious patterns; the harness permission model is the control. + - claim: Read-only Ship workers cannot leak + reality: They cannot write, but they read what the parent's permissions allow and return text; a fresh context is not an OS sandbox. + - claim: camel_route_harden_context / camel_security_scan passed + reality: MCP output is supplemental candidate evidence, never the canonical result. + - claim: Ship validated it, so only the declared route, test, pom.xml and config changed + reality: With the Pi backend the worker may create other material files; they pass validation as ordinary material files and are published with the candidate (P5). Review the whole publication set. + - claim: camel_docs_cve_search found nothing, so the component has no vulnerabilities + reality: Coverage follows the indexed advisories and versions; enrichment is best-effort; check camel_docs_index_info and the Apache Camel security page. + - claim: camel_docs_validate_endpoint accepted the URI, so the endpoint is secure + reality: It checks component and option syntax against one bundled catalog version; TLS, credentials and exposure are the route author's. + +attack_classes_left_downstream: + - prompt injection through repository content, documentation, logs and MCP responses (including Knowledge search results) + - MCP tool poisoning and rug-pulls + - supply-chain substitution of dynamically fetched MCP servers and JBang dependencies + - dependency confusion through snapshot or mirror repositories + - secret exfiltration through generated configuration, test data, logs or transcripts + - build-time code execution by running an untrusted project's Maven build during verification + - insecure generated code accepted without review + - destructive shell commands issued by an autonomous agent + - exposure of an unauthenticated local MCP transport (Knowledge SSE) beyond loopback + +known_non_findings: + - pattern: ProcessBuilder / Runtime use in ProcessRunner, PrerequisiteChecker, DoctorService, EvidenceRunner, LocalCommandRunner, PiWorker; availableProcessors in GraphBuilder + why: Argument vectors are fixed by the CLI or controller; nothing from model output or analysed sources is spliced in. + disposition: KNOWN-NON-FINDING + - pattern: Files.delete / tree deletion in GeneratedAssetCleaner, ForageCatalogService, Ship services, ShipJvmPayloadBootstrap, IndexDownloader prune and staging cleanup + why: Confined to project-relative generated assets, controller-owned state, caches and private temp, with symlink refusal. + disposition: KNOWN-NON-FINDING + - pattern: URLClassLoader / Class.forName in ShipJvmPayloadBootstrap, ShipCitrusYamlMain + why: Loads only the controller-materialised payload resolved under P4; launcher class is a controller argument. + disposition: KNOWN-NON-FINDING + - pattern: System.getenv() in Ship + why: Read to redact and scan secrets and to launch the Pi worker; never persisted. + disposition: KNOWN-NON-FINDING + - pattern: XML factories flagged for XXE + why: Every DocumentBuilderFactory and XMLInputFactory is hardened (P2). + disposition: KNOWN-NON-FINDING + - pattern: new ObjectMapper(new YAMLFactory()) + why: Jackson tree model does not honour YAML type tags. + disposition: KNOWN-NON-FINDING + - pattern: Hardcoded credential hits in skills/**, templates/**, test resources + why: Placeholders and fixtures. + disposition: KNOWN-NON-FINDING + - pattern: --no-approve in the Pi worker argument list + why: Pi's prompt is replaced by controller oversight gates and deterministic validation. + disposition: KNOWN-NON-FINDING + - pattern: followRedirects(NORMAL) in init downloaders + why: HTTPS-to-HTTPS redirects from Maven Central and GitHub are expected; NORMAL never downgrades to HTTP; absence of independent verification is the accepted boundary (D6, D15). The Knowledge IndexDownloader no longer relies on NORMAL - it follows redirects itself and validates each target's transport before the hop (#143). + disposition: KNOWN-NON-FINDING + - pattern: Generated Claude settings.json pre-approving mvn and ./mvnw + why: Documented posture (4.5a). + disposition: KNOWN-NON-FINDING + - pattern: Generated Claude settings.json pre-approving every tool of the three MCP servers (mcp__<server>__*) + why: Known deviation from the accepted posture, tracked as V3 (#155); duplicates of a report that only restates the configuration are closed against V3. A demonstrated breach through the grant is not a non-finding - it is triaged on the breach and its impact (P10). + disposition: VALID-HARDENING (tracked) for configuration-only reports; VALID when a breach through the grant is demonstrated + - pattern: A Pi-backend Ship run publishing an ordinary additional material file (documentation, test data) + why: Documented acceptance behaviour of P5; validation bounds the launch surface and the declared artifacts, not every material file. + disposition: KNOWN-NON-FINDING + - pattern: Ship state inside the project (.camel-kit/ship/state) + why: Controller-owned, denied by tree policy, self-ignored for git. + disposition: KNOWN-NON-FINDING + - pattern: GIT_CEILING_DIRECTORIES set for child processes + why: Intended boundary (P8). + disposition: KNOWN-NON-FINDING + - pattern: The CLI downloads from the internet during init + why: Documented, pinned, avoidable with --no-fetch. + disposition: KNOWN-NON-FINDING + - pattern: The Knowledge server downloads from the internet on the first query + why: Documented index acquisition (P13); avoidable with knowledge.index.path. + disposition: KNOWN-NON-FINDING + - pattern: The Knowledge MCP transport has no authentication + why: stdio is the invoking user by design; SSE is an opt-in to keep on loopback (D14). + disposition: KNOWN-NON-FINDING + - pattern: Lucene QueryParser fed with tool arguments + why: Query text is escaped with QueryParser.escape; results are bounded (P14). + disposition: KNOWN-NON-FINDING + - pattern: ONNX Runtime native library loaded in the Knowledge server + why: The bundled embedding model and reranker are packaged at build time and copied to a private temp directory; no runtime model download. + disposition: KNOWN-NON-FINDING + - pattern: The Knowledge indexer clones repositories and calls Apache JIRA, NVD and CIRCL + why: Maintainer-run build tool on trusted upstream sources; not part of the shipped server (4.4a). + disposition: KNOWN-NON-FINDING + - pattern: Scanner hits in examples/, tools/, camel-kit-dispatch/, src/test/** + why: Shipped-but-unsupported code. + disposition: OUT-OF-MODEL:unsupported-component + +dispositions: + - label: VALID + licensed_by: ["4.8", "4.6", "4.7"] + - label: VALID-HARDENING + licensed_by: ["4.11", "4.8 P9", "4.8 P11", "V3"] + - label: OUT-OF-MODEL:trusted-input + licensed_by: ["4.6", "4.2"] + - label: OUT-OF-MODEL:adversary-not-in-scope + licensed_by: ["4.7"] + - label: OUT-OF-MODEL:unsupported-component + licensed_by: ["4.3", "4.2"] + - label: OUT-OF-MODEL:non-default-build + licensed_by: ["4.5a"] + - label: BY-DESIGN:property-disclaimed + licensed_by: ["4.9"] + - label: KNOWN-NON-FINDING + licensed_by: ["4.11a"] + - label: MODEL-GAP + licensed_by: ["4.12"] +issue_5_category_mapping: + framework_vulnerability: VALID + llm_hallucination_or_insecure_suggestion: BY-DESIGN:property-disclaimed unless a documented tool, permission, parser or controller boundary failed + user_directed_insecure_route_design: OUT-OF-MODEL:trusted-input + local_operator_environment_misconfiguration: OUT-OF-MODEL:adversary-not-in-scope or OUT-OF-MODEL:non-default-build +triage_notes: + - Outside-root read, non-termination or unbounded memory during graph analysis is VALID under P1 regardless of the verification status in V1/V2 - neither BY-DESIGN nor MODEL-GAP. + - A Pi-backend Ship run publishing an ordinary additional material file is documented P5 behaviour, not a violation. + - A report matching an open verification item is triaged on the model's claim - a breach of a claimed property is VALID while the item is open. The Claude wildcard MCP grant (V3) is the one documented deviation - a report that only restates the configuration is VALID-HARDENING until the generated default changes, while a report that demonstrates a breach through the grant is evaluated on that breach and its impact under P10 and is never downgraded to V3 or closed as its duplicate (maintainer, 2026-10-27, review of #6). + - Knowledge findings use the same dispositions; the indexer's inputs are trusted upstream sources, so a finding there needs hostile upstream content (adversary not in scope) unless the indexer breaks its own path or process boundary. + +maintainer_decisions: + - date: "2026-10-27" + decision: Review round 3 of #6 - a report that only restates the known Claude wildcard grant is VALID-HARDENING under V3, while a demonstrated breach through the grant is triaged on the breach and its impact; the Pi inventory row distinguishes intended writes from the worker's unconfined OS-account reach; the Knowledge classpath fallback (temporary knowledge-index* directory, pinned-version exception) is part of the inventory. Each verification item has a tracking issue (#153-#158). Review Comment: **[P2] Quote YAML values containing issue references so the sidecar retains the decisions** Here `decision: Review round 3 of #6 - ...` loads as only `Review round 3 of`, because whitespace followed by `#` starts a YAML comment. The entire breach-triage and inventory decision is lost from the machine-readable record even though YAML parsing succeeds. The same problem truncates `status` at line 23 and the V6 related-hardening references at line 621; affected values also occur at lines 307, 330, 332 and 531. Please quote these scalars or use folded block scalars, and assert the loaded field contents rather than parser success alone. Three semantic checks fail on this revision and pass after quoting the seven affected values in memory. #142 changes object-construction policy, so it does not alter this YAML comment behavior. _AI-generated by OpenAI Codex on behalf of @luigidemasi._ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
