Problem
sourceDescriptions[].url may point at a remote OpenAPI document, which is the spec-conformant reading of the field. arazzo-cli does not fetch remote documents, so workflows that target an operationId fail with:
operationId "<id>" not found in loaded OpenAPI specs
Reported in #2, where a spec-conformant Arazzo file points at a hosted document:
sourceDescriptions:
- name: bankApiV1
url: https://example.com/v1/openapi/spec.json
type: openapi
There is no workaround inside a debug session other than vendoring the document locally, because the debug launch config has no equivalent of the CLI's --openapi.
Current behavior
Semantics are classified by URL shape, decided from the Arazzo document text alone:
sourceDescriptions[].url |
Meaning today |
| Relative URI-reference |
The OpenAPI document: resolved against the Arazzo file's directory, loaded, indexed; request base derived from its servers |
Absolute http(s) |
The request base URL (legacy). Not fetched. |
The absolute case is a deliberate compatibility choice, not an oversight: generated workflows and examples have always used that field as the base URL, and silently reinterpreting it as "fetch this document" would change where existing workflows send requests.
Proposed
Add opt-in remote fetching. --fetch-remote-sources is a semantic disambiguator, not a security gate: it selects document semantics for absolute URLs, resolving the collision with the legacy meaning above. Once generate emits document-pointing urls and legacy files age out, fetching can become the default with --no-fetch for offline/CI determinism.
Destination policy while fetching (decidable from URL text alone, no DNS resolution in the decision):
| Fetch target |
Policy |
https:// any host |
allowed |
http:// loopback (localhost, *.localhost, 127.0.0.0/8, [::1]) |
allowed — W3C Secure Contexts / RFC 8252 precedent |
http:// any other host |
allowed with explicit --insecure-http-sources |
Every row is reachable; the second flag is the user's signature on accepting a MITM-able network, in the same spirit as curl -k. The fetch layer gets a stricter default than step execution deliberately: step URLs are first-party content of a document the user reviewed and chose to run, whereas a fetched document is second-order content nobody reviews whose servers[] steers credentialed traffic. This mirrors how package managers require TLS for dependency resolution while restricting nothing about what the installed code then does.
Constraints
- Fail closed. A failed fetch is an error, never a silent fallback to base-URL semantics.
--dry-run stays network-free, so its output remains a trustworthy statement of what would be sent. Remediation message points at vendoring or --openapi.
- MCP exposes fetching via server-side config rather than inheriting a CLI flag — there the operator is an agent, so the config is how the absent owner exercises the trust decision.
- Fetches reuse the workflow
ClientConfig (timeouts, transport trust) plus a response size cap.
- Resolved base URLs stay visible in dry-run/trace output.
Related
Problem
sourceDescriptions[].urlmay point at a remote OpenAPI document, which is the spec-conformant reading of the field. arazzo-cli does not fetch remote documents, so workflows that target anoperationIdfail with:Reported in #2, where a spec-conformant Arazzo file points at a hosted document:
There is no workaround inside a debug session other than vendoring the document locally, because the debug launch config has no equivalent of the CLI's
--openapi.Current behavior
Semantics are classified by URL shape, decided from the Arazzo document text alone:
sourceDescriptions[].urlservershttp(s)The absolute case is a deliberate compatibility choice, not an oversight: generated workflows and examples have always used that field as the base URL, and silently reinterpreting it as "fetch this document" would change where existing workflows send requests.
Proposed
Add opt-in remote fetching.
--fetch-remote-sourcesis a semantic disambiguator, not a security gate: it selects document semantics for absolute URLs, resolving the collision with the legacy meaning above. Oncegenerateemits document-pointing urls and legacy files age out, fetching can become the default with--no-fetchfor offline/CI determinism.Destination policy while fetching (decidable from URL text alone, no DNS resolution in the decision):
https://any hosthttp://loopback (localhost,*.localhost,127.0.0.0/8,[::1])http://any other host--insecure-http-sourcesEvery row is reachable; the second flag is the user's signature on accepting a MITM-able network, in the same spirit as
curl -k. The fetch layer gets a stricter default than step execution deliberately: step URLs are first-party content of a document the user reviewed and chose to run, whereas a fetched document is second-order content nobody reviews whoseservers[]steers credentialed traffic. This mirrors how package managers require TLS for dependency resolution while restricting nothing about what the installed code then does.Constraints
--dry-runstays network-free, so its output remains a trustworthy statement of what would be sent. Remediation message points at vendoring or--openapi.ClientConfig(timeouts, transport trust) plus a response size cap.Related
openapioption on the debug launch config, worth deciding alongside this.arazzo generatefails on OpenAPI 3.2 spec #3 — same reporter's OpenAPI 3.2generatefailure (independent:run/debug index 3.2 documents fine).plans/assessments/openapi-32-and-sourcedescriptions-options.md§5.