Skip to content

Commit fcc7d35

Browse files
authored
docs: correct workflow publishing security-review claim, add catalog vetting notes (#4736)
* docs: correct workflow publishing security-review claim, add catalog vetting notes workflows/PUBLISHING.md described the workflow submission check as a security review of shell step content and called listed workflows "reviewed" for that purpose. Maintainers only check submission form and completeness, matching the language already used for extensions, presets, and bundles. Preset and bundle catalog docs demonstrated install_allowed without the vetting guidance extensions.md already gives, so a project-supplied catalog could look implicitly trusted. Add the same "vet before marking install_allowed" note to docs/reference/presets.md and docs/reference/bundles.md (covering both bundle sources and the component catalogs a bundle can pull in). * docs: reconcile shell-step review language in PUBLISHING.md The prior commit's new Verification Process wording ("maintainers do not review... at all") contradicted the untouched Authors bullet under Security, which said maintainers reject submissions whose shell steps can't be justified at review time. Reword both, plus the parallel sentence in the Security section, so all three consistently say maintainers may reject an obviously dangerous submission during the form/completeness pass, but this is never a security audit. Assisted-by: Claude Sonnet 5 (model: claude-sonnet-5, autonomous) * docs: extend catalog vetting guidance to step catalogs and workflow reference docs Address review feedback on #4736: the bundle catalog trust warning omitted step catalogs and their inspection command, and the new catalog-vetting guidance only lived in the author-facing publishing guide, not in the user-facing workflow reference docs (workflow run/add, .specify/workflow-catalogs.yml). Adds an equivalent warning to docs/reference/workflows.md and extends the regression test to assert the step-catalog inspection command explicitly.
1 parent c00dc05 commit fcc7d35

5 files changed

Lines changed: 51 additions & 7 deletions

File tree

‎docs/reference/bundles.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ from; `discovery-only` sources appear in `search` and `info` but refuse
174174
installation. Inspect the active stack before installing a bundle from a
175175
non-default source.
176176

177+
> **Vet both the bundle source and its component catalogs.** A project can supply its own bundle catalog and `install-allowed` component catalogs (extension, preset, workflow, and step) under `.specify/`; that project configuration existing is not evidence anything in it was reviewed. Before installing a bundle from an unfamiliar project, run `specify bundle catalog list` — and the equivalent `extension`/`preset`/`workflow catalog list` and `specify workflow step catalog list` commands for the components it pulls in — and treat any source you didn't add yourself as unvetted until you've reviewed it.
178+
177179
### List the Catalog Stack
178180

179181
```bash

‎docs/reference/presets.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ Changes the resolution priority of an installed preset. Lower numbers take prece
138138

139139
Preset catalogs control where `search` and `add` look for presets. Catalogs are checked in priority order (lower number = higher precedence).
140140

141+
> **A project's `.specify/preset-catalogs.yml` can point `add` and `search` at a catalog you didn't choose.** Before installing a preset in an unfamiliar project, run `specify preset catalog list` and inspect any catalog marked install-allowed — a project supplying that config, or marking a catalog install-allowed, is not evidence its presets were reviewed. Only mark a catalog `install_allowed` for one you authored or have vetted yourself; leave unfamiliar and community catalogs discovery-only.
142+
141143
### List Catalogs
142144

143145
```bash
@@ -156,7 +158,7 @@ specify preset catalog add <url>
156158
| -------------------------------------------- | -------------------------------------------------- |
157159
| `--name <name>` | Required. Unique name for the catalog |
158160
| `--priority <N>` | Priority (default: 10; lower = higher precedence) |
159-
| `--install-allowed / --no-install-allowed` | Whether presets can be installed from this catalog (default: discovery only) |
161+
| `--install-allowed / --no-install-allowed` | Whether presets can be installed from this catalog (default: discovery only). Only enable for a catalog you own and vet; never enable it for an unvetted public catalog. |
160162
| `--description <text>` | Optional description |
161163

162164
Adds a catalog to the project's `.specify/preset-catalogs.yml`.

‎docs/reference/workflows.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@ Shows detailed information about a workflow, including its steps, inputs, and re
386386

387387
Workflow catalogs control where `search` and `add` look for workflows. Catalogs are checked in priority order.
388388

389+
> **A project's `.specify/workflow-catalogs.yml` can point `add` and `search` at a catalog you didn't choose.** Before running a workflow from an unfamiliar project, run `specify workflow catalog list` (and `specify workflow step catalog list` for the step catalogs its steps can pull in) — a project supplying that config is not evidence its workflows or steps were vetted. Maintainers do not audit `run` fields; read a workflow's shell steps yourself before running it (see [Who maintains workflows?](#who-maintains-workflows)).
390+
389391
### List Catalogs
390392

391393
```bash

‎tests/test_catalog_trust_docs.py‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""Regression tests for catalog trust/vetting guidance in docs (#4733).
2+
3+
These check for the specific inconsistencies reported in the issue:
4+
workflow publishing docs claimed a security review of submitted workflow
5+
code, and preset/bundle catalog docs lacked the vetting guidance that
6+
extension catalog docs already had.
7+
"""
8+
9+
from pathlib import Path
10+
11+
REPO_ROOT = Path(__file__).resolve().parents[1]
12+
13+
14+
def test_workflow_publishing_does_not_claim_security_review():
15+
text = (REPO_ROOT / "workflows" / "PUBLISHING.md").read_text(encoding="utf-8")
16+
assert "Security** — no malicious shell commands" not in text
17+
assert "workflows are reviewed at submission time" not in text
18+
assert "not a security review" in text
19+
20+
21+
def test_preset_catalog_docs_warn_about_vetting_install_allowed():
22+
text = (REPO_ROOT / "docs" / "reference" / "presets.md").read_text(encoding="utf-8")
23+
assert "install_allowed" in text
24+
assert "vet" in text.lower()
25+
26+
27+
def test_bundle_catalog_docs_cover_bundle_source_and_component_catalogs():
28+
text = (REPO_ROOT / "docs" / "reference" / "bundles.md").read_text(encoding="utf-8")
29+
assert "component catalogs" in text.lower()
30+
assert "vet" in text.lower()
31+
assert "specify workflow step catalog list" in text
32+
33+
34+
def test_workflow_reference_docs_warn_about_catalog_trust():
35+
text = (REPO_ROOT / "docs" / "reference" / "workflows.md").read_text(encoding="utf-8")
36+
assert "vet" in text.lower()
37+
assert "specify workflow step catalog list" in text

‎workflows/PUBLISHING.md‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,16 @@ git push origin add-your-workflow
228228
229229
## Verification Process
230230
231-
After submission, maintainers will review:
231+
Maintainers check that:
232232
233233
1. **Definition validation** — valid `workflow.yml`, correct schema
234234
2. **Step correctness** — all step types used correctly, no dangling references
235235
3. **Input design** — clear prompts, sensible defaults and enums
236-
4. **Security** — no malicious shell commands, safe operations
237-
5. **Documentation** — clear README explaining what the workflow does and when to use it
236+
4. **Documentation** — clear README explaining what the workflow does and when to use it
238237

239-
Once verified, the workflow appears in `specify workflow search`.
238+
This is a check of the submission's **form and completeness**, not a security review — maintainers may reject a submission if its `shell` step content looks obviously dangerous during this pass, but they do not systematically audit, endorse, or support the workflow's code. Treat every workflow, including catalog-listed ones, as untrusted until you've read its `run` fields yourself (see [Security: shell steps execute arbitrary code](#security-shell-steps-execute-arbitrary-code)).
239+
240+
Once these checks pass, the workflow appears in `specify workflow search`.
240241

241242
---
242243

@@ -277,13 +278,13 @@ When releasing a new version:
277278

278279
Workflow `shell` steps execute their `run` field through `/bin/sh` (POSIX) or the platform shell. There is no sandbox between the step and the user's machine: a malicious or buggy `run` block can read environment variables, modify files outside the project, exfiltrate data, or escalate privileges.
279280

280-
Catalog-listed workflows are reviewed at submission time (see [Verification Process](#verification-process)), but you should still treat every install as code-execution from an untrusted source until you have read the `workflow.yml`:
281+
Catalog-listed workflows are checked for form and completeness at submission time (see [Verification Process](#verification-process)); maintainers may reject an obviously dangerous submission they happen to notice, but this is not a security audit — you should treat every install as code-execution from an untrusted source until you have read the `workflow.yml`:
281282

282283
- **Before installing a workflow**, fetch the raw YAML and audit every `shell` step's `run` field directly. `specify workflow info <name>` only shows metadata (name, version, inputs, step IDs/types) — not the shell content that would actually execute.
283284
- **Constrain interpolated values, don't just quote them** in `run` blocks: expressions are spliced in as raw text with no automatic escaping, and there is no shell-escaping filter, so quoting is not a security boundary. Restrict `{{ inputs.something }}` substitutions to a fixed set with `enum`/an allowlist so a malicious input can't inject shell syntax; treat quoting only as correctness handling for already-constrained values.
284285
- **Treat prior-step output as untrusted too** — `{{ steps.*.output.* }}` from a `prompt` step is AI-generated text that upstream content can influence. Don't interpolate agent output into a `run` field at all when you can't constrain it; branch on it with `if`/`switch` or act on it in a non-shell step instead.
285286
- **Limit privilege**: shell steps inherit the user's environment. Workflows that need elevated access (sudo, secrets, GitHub tokens) should call them out explicitly in the README so reviewers can spot the requirement.
286-
- **Authors**: if your workflow has shell steps that look risky out of context (deletions, network calls, credential reads), document the rationale in your README. Maintainers will reject submissions whose shell steps can't be justified at review time.
287+
- **Authors**: if your workflow has shell steps that look risky out of context (deletions, network calls, credential reads), document the rationale in your README. Maintainers may reject a submission whose shell steps look obviously dangerous and unjustified, but this spot-check is not a security audit — don't rely on catalog acceptance as a safety signal.
287288

288289
### Integration Flexibility
289290

0 commit comments

Comments
 (0)