Status: Ratified by the Hop PMC. Originally drafted by the ASF Security Team
(2026-06-01) against apache/hop (default branch main); the inferred items
were then code-verified against the source and confirmed/corrected by the PMC
(2026-06-22). Claims below cite file:line evidence where it is load-bearing.
Revision triggers: a change to the Hop Server's auth / remote-execution model; a change to the Hop Web authentication modes or to what the Hop Web web application deploys; a new scripting/exec transform or action; a change to how connection credentials / variables are stored or resolved; a new metadata source.
- Project: Apache Hop (
apache/hop) — the "Hop Orchestration Platform": visual data and metadata orchestration (pipelines + workflows) authored in a GUI and run on a local engine, a remote Hop Server, or Beam runners. - Scope of this model: the
apache/hoprepository only (hop-websiteexcluded per the PMC, 2026-05-15). - What Hop is: a tool that executes operator-authored data pipelines and
workflows — by design those can read/write files, query databases, call
services, and run scripting/exec steps. It is not a sandbox and not a
multi-tenant isolation boundary (confirmed: no JVM
SecurityManager/policy anywhere inengine/core/plugins; the scripting engines are deliberately configured for full host access — see §9).
Hop is operated by a data engineer / operator who authors pipelines
(.hpl) and workflows (.hwf) and runs them — interactively in Hop GUI, via
the hop-run CLI, or submitted to a Hop Server for local/remote execution.
| Family | Path | Role / trust notes |
|---|---|---|
| Execution engine | engine/, engine-beam/ |
Runs pipelines/workflows the operator authored — incl. transforms that touch files, DBs, network, and scripting/exec steps. |
| Hop Server (servlet / HTTP) | engine/ — package org.apache.hop.www + HopServerMeta in org.apache.hop.server; launched by the hop-server command (org.apache.hop.www.HopServer). (The org.apache.hop.server connection helpers HttpUtil/ServerConnectionManager — see §9 — live in core/.) |
The network trust boundary: an embedded Jetty server whose servlets accept pipeline/workflow run requests over HTTP (/hop/execPipeline, /hop/addPipeline+/hop/startExec, /hop/registerPackage, …). Who may submit/run, and with what auth, lives here (§7, §8). |
| Hop JSON API | engine/src/main/java/org/apache/hop/www/api/ |
Part of Hop Server, not a separate deployable. Mounted on /hop/api/v1/ (WebServer.java) and exposes execute/sync (run a web service), metadata CRUD, plugins and location execution info. In the standalone hop-server deployment it sits inside the same ConstraintSecurityHandler as every servlet, so it inherits Hop Server's Basic/JAAS auth; when the same API is co-deployed inside Hop Web it is gated instead by Hop Web's own filters (HopBasicAuthFilter / HopOidcAuthFilter / HopServerAuthorizationFilter) — see the Hop Web row and §8. |
| Arrow Flight server (gRPC) | plugins/tech/arrow/ — package org.apache.hop.arrow.flight; launched by the hop arrow command (org.apache.hop.arrow.command.ArrowCommand) |
A separate network listener, distinct from both Hop Server and Hop Web: a gRPC/Arrow Flight endpoint that hands rows to and from Data Stream metadata elements. Binds 0.0.0.0:33333 by default. TLS (incl. mutual TLS) and username/password authentication are configurable but off unless the operator passes the options (§8) — with neither, anything that can reach the port can read the data it streams. |
| GUI (desktop / web) | ui/ (hop-ui, SWT core), rcp/ (desktop fragment), rap/ (hop-ui-rap, RAP/RWT web GUI) |
Authoring surface used by the trusted operator. rap/ is the web GUI code, not a server — but see the Hop Web row: the shipped web application deploys it together with Hop Server servlets. |
| Hop Web (deployed web application) | assemblies/web/ (WAR + apache/hop-web image), built from rap/ + engine/ |
A distinct network-facing deployment, separate from both rap/ and hop-server. The one WAR co-deploys the RAP UI on /ui and /ui-dark, HopServerServlet on /hop/*, and HopApiApplication on /hop/api/v1/* on the same origin (web.xml). It does not use Hop Server's enable_auth / hop.pwd Basic auth; it has its own auth modes (§8). Docker image binds 0.0.0.0:8080. |
| Plugins | plugins/ |
The large transform/action set, incl. scripting (GraalJS/Rhino/Groovy), shell/exec, SQL, and per-DB/per-cloud connectors (plugins/tech/*). |
| Connection / driver layer | lib-jdbc/ (bundled JDBC drivers), core/ (org.apache.hop.core.database, org.apache.hop.metadata) |
DB/file/cloud credentials + JDBC drivers the operator configures. (There is no standalone metadata/ module — connection/metadata code is in core/.) |
In scope: engine + Hop Server + Hop Web + plugins + connection layer + GUI glue. Intended caller trust: Hop is operated as a single trust domain — the pipeline/workflow author, the local operator, and anyone holding Hop Server credentials are all trusted (they direct what Hop does). There are several network-facing surfaces — Hop Server, Hop Web and the optional Arrow Flight server — and any of them is where an untrusted actor can appear; Hop Server and Hop Web have separate auth models (§8).
hop-website,docs/,integration-tests/,assemblies/build mechanics, samples/demos — not the shipped runtime product. (Note: the default security posture baked byassemblies/anddocker/— the shippedhop-server.xml,pwd/hop.pwd, and the container0.0.0.0bind + default credentials — is an in-scope fact for the auth analysis in §8/§10, even though the assembly build itself is out of scope.)- Bundled third-party JDBC drivers / libraries' own vulnerabilities — a CVE
in a packaged driver is a dependency/supply-chain matter, not a Hop defect
(Hop's job is to call them correctly).
lib-jdbc/bundles redshift, clickhouse, h2, mssql, vertica, crate, monetdb, jt400, snowflake, derby, duckdb, hsqldb, postgresql, sqlite, mysql. - Credential acquisition / storage / rotation for the DBs/services Hop connects to — the operator supplies these via connections/variables (§8, §10).
- Multi-tenant isolation between pipelines/users on a shared engine or server — Hop runs as a single trust domain (§9).
- Pipeline/workflow author → engine. The author is trusted; what they build (incl. scripting/exec/SQL steps) is intended execution, not an attack (§7, §9).
- Remote client → Hop Server (HTTP). The high-value boundary: a network
client requests pipeline/workflow execution. Authentication, transport
security, and "who can run what" live here. The JSON API on
/hop/api/v1/is served by the same process and behind the same auth (§8, §10). - Metadata / project ingestion. Pipeline/workflow + metadata files loaded
from disk/VCS. Loading a file parses it (with hardened XML — §8) and
instantiates only the no-arg metadata classes of referenced
transforms/actions; no scripting/exec/DB/network/UI code runs from loading
alone. Running it executes those steps — so running an untrusted
.hpl/.hwfis equivalent to running untrusted instructions (§11). Verified:PipelineMeta.java,TransformMeta.java:238. - Connection layer → external DB/file/cloud. Carries operator-configured credentials; responses are backend-controlled (§8).
- Variables / parameters. Resolved into transform config at run time by
raw, unescaped string substitution — an injection surface if a value is
sourced from untrusted input (§9). A
Set Variablestransform/action can copy an upstream row-stream value (or an OS env /-Dproperty) into a variable, so untrusted data can demonstrably reach a sink.
JVM; the OS the engine/server runs on (full file + process access for
exec/shell/scripting steps); network reachability to configured backends + the
Hop Server's listen interface; system trust store for outbound TLS (with the
caveats in §9). The operator is responsible for setting javax.net.ssl.keyStore
where strict outbound TLS verification is required (see §9).
| Input | Source | Trusted? | Notes |
|---|---|---|---|
Pipeline/workflow definitions (.hpl/.hwf) |
Operator/author | Trusted | Running an untrusted definition = running untrusted code (§11). Loading is hardened against XXE (§8). |
| Hop Server run requests | Network client | Untrusted-capable | Auth/authz is the boundary. The server enforces HTTP Basic auth by default — covering both the XML servlets and the JSON API — but ships a world-known default credential and has no per-endpoint authz (§8). |
| Connection configs + credentials | Operator | Trusted (secret) | Stored only obfuscated by default — not confidential at rest unless the operator opts into AES2 / a secrets resolver (§8). |
| Variables / parameters | Operator, OS env / -D, or upstream row data |
Untrusted-capable | Resolved by raw substitution; injection into SQL/paths/commands if the value is untrusted (§9). |
| Metadata (from project files / VCS) | Operator/author | Trusted-by-default | Untrusted if loaded from an external source (§11). No signature/provenance check exists. |
| Row/stream data processed by a pipeline | Upstream sources | Pass-through | Hop moves it; semantic validation is the pipeline author's. |
- Out of scope: the pipeline/workflow author, the local operator, and any holder of Hop Server credentials — Hop is a single trust domain, and they already control execution (a scripting step that runs code is intent, not an attack).
- In scope: a remote actor against an exposed Hop Server or Hop Web
deployment — submitting or running pipelines, reading results and mutating
metadata over
/hop/*or/hop/api/v1/*, or driving the RAP authoring UI on/ui— bounded by whatever auth fronts the surface (enable_authforhop-server, the Hop Web auth mode for Hop Web, §8); and a network MITM between Hop and its backends or between client and server. - Conditional: an attacker who can get an untrusted pipeline/metadata
file loaded/run, or who controls a variable/parameter value (incl. an
upstream row value picked up by
Set Variables) that reaches a sink.
- Hop Server authentication (with a critical caveat). (This property is
scoped to the standalone
hop-serverdeployment only — Hop Web has noenable_authand nohop.pwd; see the separate Hop Web property below.) The servlet Hop Server enables HTTP Basic authentication by default (enable_authdefaults to true —HopServerMeta.java:229,251,WebServer.java:197), gating every endpoint, so a fully unauthenticated client is rejected. Caveat: the only shipped credential is the publicly-known defaultcluster/cluster(pwd/hop.pwd,HopServer.java:164), there is no per-endpoint authorization (a single/*role gate — any authenticated user can run/stop pipelines), and the Docker image binds0.0.0.0:8080with those defaults. Changing the credential and restricting exposure is an operator responsibility (§10). — violation symptom: remote code execution using the unchanged default credential on an exposed deployment; severity: critical. - Hop Web authentication and authorization (separate model from
hop-server). Hop Web does not inherit thehop-serverenable_auth/cluster:clusterposture described above; it has its own authentication mode insecurity-config.json(HopSecurityConfig.java,HOP_WEB_SECURITY_MODE), and it ships in modeNONE. The boundary per mode:NONE(default). The RAP UI on/ui//ui-darkis open by design — this is the single-user / trusted-network install and the session is treated as unrestricted. The co-deployed Hop Server API on/hop/*is default-denied (403) byHopServerAuthorizationFilter. The filter authorizes the container-mapped path (getServletPath()+getPathInfo()), which is the path the container has already normalized. ModeNONEhas no identity to authorize against, and those endpoints deploy and execute pipelines/workflows. Opt-in flagallowUnauthenticatedServerApi/HOP_WEB_ALLOW_UNAUTHENTICATED_SERVER_APIreopens it for operators running Hop Web purely as an execution server behind their own network controls — violation symptom: unauthenticated remote code execution via/hop/*on an exposed deployment that enabled the flag; severity: critical; mitigation is operator-side network control (§10).BASIC/OAUTH2. Hop's own servlet filters (HopBasicAuthFilter,HopOidcAuthFilter) are mapped on/*— the whole application, UI and server API alike — and establish a principal plus roles. Unlikehop-server,/hop/*then gets per-endpoint authorization: each path maps to a required permission and unmapped paths are default-denied, so a Read-only user can read status but notaddPipeline/startPipeline/execWorkflow.EXTERNAL. Authentication is delegated to the servlet container or a reverse proxy; Hop only readsrequest.getUserPrincipal(). Nothing inrap/enforces it, and the shippedweb.xmlcontains no<security-constraint>— so an operator who selectsEXTERNALwithout adding one gets an unauthenticated/uiwhile the General tab shows an authenticated mode (EXTERNAL) — the Security tab's own status line still reads "Session is unrestricted (no AuthN)", so the tab surfaces the contradiction rather than claiming authentication is on./hop/*still returns401(no principal) andHopWebEntryPointnow logs a warning for every principal-less session in a non-NONEmode, but the UI itself is open. — violation symptom: a fail-open UI on a deployment the operator believes is authenticated; severity: high; mitigation: a container<security-constraint>over/*, or a proxy that rejects unauthenticated requests (§10).
- Cross-site browser requests to the Hop Server are rejected. The servlets
answer state-changing operations on
GET, so a page the operator is visiting could otherwise drive them with the operator's browser and credentials (Originis no defence: browsers omit it on cross-siteGET). A single handler wrapped around every servlet context, the static resources and the JSON API (CrossSiteRequestHandler.java, installed inWebServer.javaahead of authentication) rejects a request whoseSec-Fetch-Sitethe configuredCrossSitePolicydisallows — by defaultcross-site, and under--cross-site-policy same-originalsosame-site. The same check covers Hop Web, which co-deploys these servlets on/hop/*outsideWebServer, via a servlet filter mapped ahead of the authentication filters (CrossSiteRequestFilter.java,web.xml); there it is configured bycrossSitePolicyinsecurity-config.json(Configuration → Security → General) and matters more, because Hop Web's authenticated modes are session-backed and a browser attaches the session cookie to a cross-site request by itself. The Hop Web UI (/ui) is not covered. Requests carrying noSec-Fetch-*headers (hop-run, the Hop GUI, curl, automation) are allowed, so non-browser clients are unaffected;--cross-site-policy offdisables the check entirely. This narrows drive-by use of an authenticated operator's browser only — it is not per-endpoint authorization, and does nothing about a client that reaches the server directly (§9). — violation symptom: a visited web page starts or stops pipelines on a server the operator is logged in to; severity: high. - XML parsing is hardened against XXE. Pipeline/workflow/metadata files are
parsed through a secure
DocumentBuilderFactory(XmlParserFactoryProducer.java) with external general/parameter entities and external DTD loading disabled andFEATURE_SECURE_PROCESSINGon — XXE file-read/SSRF and entity-expansion are mitigated (verified empirically). The same secure parser is used by the Hop Server remote-add endpoints. StAX ingest (XmlInputStreamand otherXMLInputFactorysites) usescreateSecureXmlInputFactory(), which disables DTD processing and external entities. - Credential storage — NOT confidential by default. Connection passwords in
metadata are by default only reversibly obfuscated, not encrypted: the
built-in
Hopencoder (HopTwoWayPasswordEncoder.java) XORs against a hardcoded, publicly-known seed and prefixesEncrypted— the code itself states it is "not really encryption … obfuscation." Anyone with the file recovers the plaintext. Real confidentiality is opt-in: setHOP_PASSWORD_ENCODER_PLUGIN=AES2with an operator-heldHOP_AES_ENCODER_KEYorHOP_AES_ENCODER_KEY_FILE(AES-GCM), and/or keep secrets out of metadata via a variable resolver (HashiCorp Vault, Azure Key Vault, Google Secret Manager). Encoder plugin and key can be re-bound per project/environment on enable (and via the Set password encoder action); the active encoder remains process-global. See §9, §10, §11a. - Credential leakage in logs. No plaintext password is logged by default,
and decrypted DB passwords travel in a JDBC
Propertiesobject, not the URL. However, resolved JDBC/REST/HTTP URLs are logged at debug/detailed level without credential masking (Database.java:488,Rest.java:142,199), so credentials an author embeds in a URL can leak — operators should avoid in-URL credentials. - Transport security — available, off by default. The Hop Server can serve
over HTTPS via a Jetty
SslContextFactoryconfigured with a JKS keystore in the<sslConfig>block ofhop-server.xml, but TLS is off by default (the shipped config starts a plain-HTTP listener; only auth is on). Outbound JDBC TLS is fully driver-delegated; HTTP/REST/cloud transforms use the JVM trust store unless given a per-transform truststore. The Arrow Flight server (hop arrow) is likewise plaintext and unauthenticated unless started with--arrow-flight-tls-certificate/--arrow-flight-tls-key(optionally--arrow-flight-tls-client-cafor mutual TLS) and--arrow-flight-username/--arrow-flight-password; it logs a warning when it starts without them. Enabling TLS is an operator responsibility (§10).
- Not a sandbox. An authored pipeline/workflow runs scripting/shell/SQL and
touches files/network with full host/JVM capability — by design. There is
no
SecurityManageranywhere. Thescripttransform sets GraalJSHostAccess.ALL+allowHostClassLookup(true)(ScriptUtils.java:165-166); the legacyjavascripttransform andevalaction use Mozilla Rhino with noClassShutter;User Defined Java Class/Janino/Java Filtercompile arbitrary Java;Exec process/Shellrun OS commands viaRuntime.exec/ProcessBuilder. The only restriction mechanism is an opt-in, default-empty substring deny-list (JaninoCheckerUtil+codeExclusions.xml) that covers only the three Janino-based steps and blocks nothing out of the box (§11a). - No isolation between pipelines/tenants running on the same engine/server beyond what the OS/JVM provides. Hop is a single trust domain (§7).
- No per-endpoint authorization on the Hop Server. Any authenticated user is fully privileged across both the XML servlets and the JSON API (§10).
- Credential confidentiality at rest is not provided by default — only reversible obfuscation; key-based protection is opt-in (§8).
- No strict TLS verification on all client/internal paths. The relaxation
that is genuinely in effect is in
ServerConnectionManager, which installs a process-global defaultSSLContextthat skips CA-chain/hostname validation (date-only) whenjavax.net.ssl.keyStoreis unset. (HopServerMeta.getHttpClientalso constructs a self-signed-accepting, no-hostname-verify socket factory insslMode, but it is not actually wired into the returned client — latent.) Several transforms also offer opt-inignoreSsl/trustAllCertificatesswitches (all default to verification on). The HashiCorp Vault and OpenBAO variable resolvers verify the secrets server's certificate by default too, but the setting is serialised per resolver, so a definition saved with it off keeps reaching the secrets server unverified until an operator changes it. - No automatic sanitization of variables.
${VAR}/%%VAR%%/$[hex]tokens are resolved by raw, unescaped string substitution (StringUtil.environmentSubstitute); the result is concatenated directly into SQL strings, file paths, and shell bodies. Parameterizing/escaping any variable that may carry untrusted data is the pipeline author's job. (Note: the row-stream value path of SQL transforms — Table Input lookup params, Execute SQL "parameters" mode — IS bound via JDBCPreparedStatement?placeholders; that path is parameterized by design and is not the injection concern.) - No protection if an untrusted
.hpl/.hwfis loaded and run — equivalent to executing untrusted instructions. There is no signature, provenance, or integrity check on these files; they are unsigned XML, and trust comes solely from their source.
- Lock down the Hop Server: change the default
cluster/clustercredential, do not expose the remote-execution API to an untrusted network, and restrict who can submit runs. Keepenable_authon — it is what protects the XML servlets and the JSON API alike — it has none of its own. Be aware the Docker image binds0.0.0.0:8080with the default credential. - Lock down Hop Web (separate from
hop-serverabove —enable_authandhop.pwddo not apply): it ships in modeNONE, where/uiis open by design. For any shared deployment setHOP_WEB_SECURITY_MODEtoBASICorOAUTH2, or toEXTERNALtogether with a container<security-constraint>over/*(or an authenticating reverse proxy) —EXTERNALon its own fails open. LeaveHOP_WEB_ALLOW_UNAUTHENTICATED_SERVER_APIoff unless you deliberately run Hop Web as an execution server behind network controls. PersistHOP_CONFIG_FOLDER/security/so users and role mappings survive upgrades. - Protect credentials at rest: enable the AES2 encoder
(
HOP_PASSWORD_ENCODER_PLUGIN=AES2+HOP_AES_ENCODER_KEYorHOP_AES_ENCODER_KEY_FILE) and/or a secrets resolver (Vault / Azure Key Vault / Google Secret Manager); never commit default-obfuscated credentials to VCS; avoid embedding credentials in URLs. - Manage connection credentials; don't source connection config or pipeline/metadata files from untrusted input — only run pipelines from trusted authors.
- Treat scripting/exec/SQL steps as code; parameterize variables that carry
untrusted data. The Janino deny-list (
codeExclusions.xml) can be populated to block named constructs in the three Janino-based steps if desired. - Use TLS for the server + sensitive backends. Set
javax.net.ssl.keyStoreto avoid the relaxed process-global TLS trust manager (§9).
- Exposing a Hop Server with the unchanged default credential (
cluster/cluster), or withenable_auth=false, to an untrusted network → remote pipeline execution = remote code execution. - Running Hop Server with
enable_auth=falseon an untrusted network → unauthenticated pipeline execution + metadata mutation over the JSON API. - Exposing Hop Web in mode
NONEto an untrusted network →/uiis an unrestricted GUI session, so anyone who can reach it can author and run pipelines/workflows in-process (the GUI executes locally throughPipelineEngineFactory/LocalPipelineEngine, it does not go through/hop/*) = remote code execution, even though/hop/*still answers403. EnablingHOP_WEB_ALLOW_UNAUTHENTICATED_SERVER_APIadditionally opens the remote/hop/*and/hop/api/v1/*execution API. - Selecting Hop Web mode
EXTERNALwithout a container<security-constraint>(or proxy) → an open/uion a deployment the operator believes is authenticated. - Running an untrusted pipeline/workflow file (or one fetched from an untrusted source).
- Building unparameterized SQL / shell / file paths from untrusted variable
values — e.g. a value placed into a variable by a
Set Variablestransform from an untrusted upstream row, or from an attacker-influenced OS env /-Dproperty. The resolver does not escape, so this is injection (SQL injection, path traversal, shell command construction).
All of the following are DISCLAIMED §9 non-guarantees with the §7 adversary being the trusted author/operator — they are intended functionality, not vulnerabilities:
- "A pipeline can run JavaScript/Groovy/Python/shell/SQL" — by design. The
scripttransform's GraalJSHostAccess.ALL+allowHostClassLookup(true), the Rhino transforms/evalaction without aClassShutter, and theScriptValuesAddedFunctionshelpers (execProcess,loadFileContent,appendToFile) are deliberate full-host scripting affordances. - "
User Defined Java Class/Janino/Java Filtercompile arbitrary Java with noSecurityManager" — by design; the emptycodeExclusions.xmldeny-list (which permitsSystem.exit/Runtime.execuntil an operator populates it) is the documented default, not a regression. - "
Exec processusesRuntime.exec;ShellusesProcessBuilder(cmd.exe /Con Windows; the script file is run directly on other OSes);sql/execsqlrow/dynamicsqlrowexecute operator-authored SQL;ssh/as400commandrun commands on a remote host" — running operator-authored commands/SQL is the step's purpose. - "A connection password in a
.hpl/.hwfis only obfuscated / the encoder seed is hardcoded" — by design; the defaultHopencoder is obfuscation, not confidentiality. Key-based confidentiality (AES2) and secrets resolvers are opt-in (§8). An exposed default-obfuscated metadata password is recoverable by design. - "Hop connects to a database with a configured password" — operator-supplied connection config, not a finding.
- "A bundled JDBC driver has CVE-XXXX" — dependency/supply-chain, handled via the driver/ASF process, not a Hop code defect.
- "Hop reads/writes the files a pipeline tells it to" — the operator's pipeline doing its job.
- (Clarifications so triagers don't misfire): the SQL row-stream value path
uses
PreparedStatement?binding and is not a SQL-injection bug; theformulatransform (bounded POI/FormulaParserDSL) and thesimpleevalaction (field/variable comparison) are not code-execution steps and should not be conflated with the scripting steps above.
A change to the Hop Server auth or remote-exec model; a change to the Hop Web authentication modes, its servlet filters, or to what the Hop Web web application deploys; a new scripting/exec transform or action; a change to credential/variable storage or resolution (e.g. a new default encoder); a new metadata source format/location; or a decision to support multi-tenant isolation (which today does not exist).
| Disposition | When | Section |
|---|---|---|
| VALID | A genuine implementation defect that violates a §8 property under the §7 adversary in in-scope code — e.g. an auth gate that can be bypassed (an endpoint reachable without the configured credential), an authorization hole beyond the documented single /* role, a credential leak in logs, or an XXE that bypasses the hardened parser |
§7, §8 |
| OUT-OF-MODEL | Adversary is the trusted author/operator/credential-holder; or code in hop-website/tests/samples/assembly build |
§3, §7 |
| DOWNSTREAM-RESPONSIBILITY | Default-credential / network exposure, credential mgmt, running untrusted pipelines, unparameterized untrusted variables, enabling TLS | §10 |
| DISCLAIMED | A §9 non-guarantee (authored pipeline runs code; default obfuscation; no pipeline isolation; no per-endpoint authz; relaxed internal TLS; bundled-driver CVE) | §9 |
| MODEL-GAP | Plausible, not covered → escalate to PMC | §12 |
The v1 draft's open questions have been resolved by the PMC (2026-06-22):
- Framing (Q1): Confirmed — Hop runs operator-authored pipelines (incl. scripting/exec) by design; it is not a sandbox (§1, §9; code-verified).
- Trust model (Q2, Q7): Confirmed — single trust domain: author,
operator, and Hop Server credential-holder are trusted and out of the
adversary model. Running an untrusted
.hpl/.hwfis DOWNSTREAM-RESPONSIBILITY / OUT-OF-MODEL; the network-facing server submit-run path stays in scope (§7). - Out of scope (Q3): Confirmed — website, tests/samples, assembly build, bundled-driver CVEs (§3), with the caveat that the shipped default posture is an in-scope fact.
- Hop Server auth (Q5): Resolved as code fact — Basic auth on by default
but a world-known default credential, no per-endpoint authz, Docker
0.0.0.0bind. Treated as DOWNSTREAM-RESPONSIBILITY: operators must change the credential and restrict exposure (§8, §10). - TLS (Q6): Resolved — available, off by default; internal relaxations are documented §9 non-guarantees with an operator mitigation (§9, §10).
- Credentials (Q8): Resolved — default storage is obfuscation, not confidentiality (DISCLAIMED); AES2 / secrets resolvers are the supported confidentiality controls (§8, §11a). Unmasked URL logging noted in §8/§10.
- Variable injection (Q9): Resolved — raw unescaped substitution is a DISCLAIMED §9 non-guarantee; sanitizing untrusted variables is the author's DOWNSTREAM responsibility (§9, §11).
- Scripting/exec (Q12): Resolved — full host capability by design (DISCLAIMED), with the opt-in default-empty Janino deny-list as the only hardening hook (§9, §11a).
- Host environment / credential rotation (Q10/Q11): Confirmed downstream/out-of-scope (§3, §5, §10).
- Recurring non-findings (Q18a): Expanded with concrete per-step bullets (§11a).
- Discoverability chain (meta): Confirmed —
AGENTS.md → SECURITY.md → THREAT_MODEL.md.
Not generated for v1.