chore: add draft threat model - #1642
Open
oscerd wants to merge 1 commit into
Open
Conversation
Adds docs/threat-model.md, a first draft of Karavan's threat model following the ASF Security threat-model-producer rubric. Karavan has no SECURITY.md and no entry in the ASF security site's project-coordinates.json. The Apache Camel security model (camel.apache.org/manual/security-model.html) scopes itself to apache/camel artifacts and notes that sibling subprojects have their own security surfaces, so Karavan currently has no document a triager can cite when classifying a vulnerability report or a scanner finding. The draft is written from public artifacts only. Every claim carries a (documented) / (maintainer) / (inferred) provenance tag: 53 documented, 0 maintainer, 28 inferred. The inferred claims are unratified hypotheses, each routed to a numbered question in section 4.14 for the maintainers to confirm, correct, or strike. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
oscerd
force-pushed
the
docs/threat-model
branch
from
August 28, 2026 13:37
b42af8b to
b499cb9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
A first draft of a threat model for Karavan, at
docs/threat-model.md.It is deliberately not an audit, a pentest report, or a findings list. It describes
the implicit contract between Karavan and the people who deploy it: what Karavan
assumes, what it guarantees given those assumptions, what it leaves to the operator,
and which misuses look reasonable but aren't. The audience is two-sided — an operator
deciding how to deploy Karavan, and a triager who has to classify an inbound
vulnerability report or a scanner hit and cite a section to justify the call.
Why now
Karavan has no
SECURITY.md, and no entry in the ASF security site'sproject-coordinates.json.The Apache Camel security model
scopes itself to
apache/camelartifacts and explicitly notes that sibling subprojects"have their own security surfaces" — Karavan isn't named. So today there is nothing a
triager can cite when a report or an automated scan lands.
The draft inherits Camel's role vocabulary (route author / operator / external message
sender) rather than inventing a parallel one, and Appendix A back-maps all eleven of
that document's statements to sections here.
The claim the document turns on
The trust boundary is HTTP authentication, and nothing after it. A Karavan account
is Camel's "route author", which that model declares fully trusted. Docker mode
bind-mounts
/var/run/docker.sock; Kubernetes mode grantsverbs: ["*"]on secrets,configmaps, serviceaccounts, pods and deployments plus
pods/exec; a project'sdocker-compose.yamlreachesMountType.valueOf(...)and/bin/sh -c; andconfiguration/build.shis a user-editable file copied into the builder at mode0755and executed.
If that's right, then "an authenticated user achieves RCE" is
OUT-OF-MODEL: adversary-not-in-scope, and §4.11a lists it as a suppression entry alongside thedocker.sock mount, the wildcard RBAC, and the
application.propertiescredentials thatevery secret scanner flags. Q2 below is asking you to confirm exactly that.
Provenance
Written from public artifacts only — no maintainer input yet. Every non-trivial claim
carries a tag:
53
(documented)· 0(maintainer)· 28(inferred)(inferred)means hypothesis, not yet confirmed. Each one routes to a numberedquestion in §4.14. Please don't read the draft as asserting these — they're the ask.
The ask — wave 1 (blocking)
Each states a proposed answer. Confirm, correct, or strike — a one-line reply per
question is enough, and I'll fold the answers in and promote the tags.
Q1 — the default admin password.
platform.password=K@r@v@n422seedsadminanddeveloper. The project's own artifacts point both ways:AuthService.loadDefaultsreads as a getting-started convenience, but
docs/WEB_DOCKER.mdanddocs/WEB_KUBERNETES.mdpresent it as the first-login credential and link straight tothe source line, with no instruction to change it. Is the default the supported
production posture (making default-credential reports
VALID), or a dev convenienceoperators are expected to override (making them
OUT-OF-MODEL: non-default-build, andmaking the install docs a gap to close)?
Q2 — is "any authenticated user is fully trusted" the intended model? Proposed:
yes — a Karavan account is Camel's route author, so one user reaching another's project
is not a vulnerability, and the absence of per-project authorization is a scope decision
rather than a gap. This is the load-bearing question; most of §4.9 and the whole triage
table in §4.13 depend on it.
Q3 — are the Git repository and the image registry trusted inputs? Proposed: yes —
Karavan imports whatever the repo holds as code, doesn't verify commit signatures, and
pulls images by tag. A malicious repo or registry is outside the adversary model.
Q4 — is API-token project scoping meant to be enforced?
allowedProjectIdsispersisted, documented in
AccessTokenas "Scoped access limits (ABAC)", and attached tothe identity — but I can't find an endpoint that reads it. Related:
ROLE_SERVICE_ACCOUNTappears in no
@RolesAllowed, and/ui/notification/user/{username}and/ui/logwatch/{type}/{name}/{username}take a username from the path without comparingit to the caller. Proposed: forward-looking scaffolding rather than a current
guarantee, and §4.9 should say so plainly.
Q5 — the negative side-effect inventory. Proposed: on its own host,
karavan-appinstalls no signal handlers, spawns no child processes (no
Runtime.exec/ProcessBuilderanywhere in the module), reads no host paths beyond its classpath, thetwo configured SSH files and Vert.x temp dirs, and listens on no port but the configured
HTTP one. Are those four deliberate guarantees, or just true today? These are negative
claims — almost never written down, and impossible to cite — so they're the
highest-value thing to confirm.
Waves 2–4
Nine more in §4.14, deliberately held back so wave 1 can be answered in one sitting:
resource limits and which
§4.5adefaults are supported posture (Q6–Q8), browser-sidethreats and the VS Code extension's workspace-trust assumption (Q9–Q12), and document
ownership and revision policy (Q13–Q14).
One item that may belong on security@ instead
Q9 observes that the
csrfcookie is minted and stored on the session, but that Ifound no server-side handler validating it against an incoming header. Either CSRF is in
the model and the check is missing, or the browser isn't an adversary channel and the
cookie should be removed so it stops reading as a control (§4.9 lists it under "false
friends" precisely because it's ambiguous today).
It's framed as a question rather than an exploit, and it's derivable from the public
source — but if you'd rather that one didn't get worked through in a public PR, say so
and I'll strip it from the draft and route it to
security@apache.orginstead.Notes
changes — it describes Karavan as it is, not as it should be.
classes and seven component families earns some of that, but I'd happily cut §4.8 or
§4.11 down if you find it long.
🤖 Generated with Claude Code