Deepsec Documentation Guide
vercel-labs/deepsec
Points the agent at deepsec's own docs to answer questions about initializing, configuring, resuming, scanning with and extending the vulnerability scanner.
Generate a CVE 5.x JSON document from an <tracker tracking issue, ready to paste into the Vulnogram source tab of the ASF CVE tool at https://cveprocess.apache.org/cve5/<CVE-IDsource.
$ npx skills add apache/magpie --skill generate-cve-json -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install apache/magpie generate-cve-json --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/apache/magpie.git skills-src && mkdir -p .claude/skills && cp -r skills-src/tools/cve-tool-vulnogram/generate-cve-json .claude/skills/generate-cve-json && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "generate-cve-json" agent skill from https://github.com/apache/magpie/tree/main/tools/cve-tool-vulnogram/generate-cve-json into .claude/skills/generate-cve-json/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-cve-json", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/apache/magpie/tree/main/tools/cve-tool-vulnogram/generate-cve-jsonType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add apache/magpie --skill generate-cve-json -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install apache/magpie generate-cve-json --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/apache/magpie.git skills-src && mkdir -p .agents/skills && cp -r skills-src/tools/cve-tool-vulnogram/generate-cve-json .agents/skills/generate-cve-json && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "generate-cve-json" agent skill from https://github.com/apache/magpie/tree/main/tools/cve-tool-vulnogram/generate-cve-json into .agents/skills/generate-cve-json/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-cve-json", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add apache/magpie --skill generate-cve-json -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install apache/magpie generate-cve-json --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/apache/magpie.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/tools/cve-tool-vulnogram/generate-cve-json .cursor/skills/generate-cve-json && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "generate-cve-json" agent skill from https://github.com/apache/magpie/tree/main/tools/cve-tool-vulnogram/generate-cve-json into .cursor/skills/generate-cve-json/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-cve-json", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/apache/magpie.git --path tools/cve-tool-vulnogram/generate-cve-json--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add apache/magpie --skill generate-cve-json -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install apache/magpie generate-cve-json --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/apache/magpie.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/tools/cve-tool-vulnogram/generate-cve-json .gemini/skills/generate-cve-json && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "generate-cve-json" agent skill from https://github.com/apache/magpie/tree/main/tools/cve-tool-vulnogram/generate-cve-json into .gemini/skills/generate-cve-json/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-cve-json", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install apache/magpie generate-cve-jsonInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add apache/magpie --skill generate-cve-json -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/apache/magpie.git skills-src && mkdir -p .github/skills && cp -r skills-src/tools/cve-tool-vulnogram/generate-cve-json .github/skills/generate-cve-json && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "generate-cve-json" agent skill from https://github.com/apache/magpie/tree/main/tools/cve-tool-vulnogram/generate-cve-json into .github/skills/generate-cve-json/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-cve-json", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add apache/magpie --skill generate-cve-json -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install apache/magpie generate-cve-json --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/apache/magpie.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/tools/cve-tool-vulnogram/generate-cve-json .opencode/skills/generate-cve-json && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "generate-cve-json" agent skill from https://github.com/apache/magpie/tree/main/tools/cve-tool-vulnogram/generate-cve-json into .opencode/skills/generate-cve-json/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "generate-cve-json", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
generate-cve-jsonGenerate a CVE 5.x JSON document from an <tracker tracking issue, ready to paste into the Vulnogram source tab of the ASF CVE tool at https://cveprocess.apache.org/cve5/<CVE-IDsource.
Generate Cve JSON is an agent skill from apache/magpie. Generate a CVE 5.x JSON document from an <tracker tracking issue, ready to paste into the Vulnogram source tab of the ASF CVE tool at https://cveprocess.apache.org/cve5/<CVE-IDsource. The conversion is deterministic: same issue in, same JSON bytes out. Handles multiple credits (one per line) and multiple references (URLs extracted from the issue's "Public advisory URL" and "PR with the fix" fields; the "Security mailing list thread" field is treated as internal-only and never exported).
Its SKILL.md is about 8.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 17 other files (for example `README.md`, `src/generate_cve_json/__init__.py` and `src/generate_cve_json/__main__.py`).
It sits in Security, covering Vulnerability scanning. The repository describes itself as: Agent-assisted maintainership and development framework for Apache projects — Triage, Mentoring, Drafting (agent-authored fixes with human review), and Pairing (developer-side… The licence is Apache-2.0.
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit f3cab5c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships script files (Python), which the agent can run.
Shell commands in SKILL.md call:
uvghhelmFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
cveprocess.apache.orgAlso links to:
github.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Generate Cve JSON loads about 8.3k tokens when it runs. Until then it costs about 129 tokens; SKILL.md has 4,244 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from apache/magpie at commit f3cab5c, republished under its Apache-2.0 licence (© apache). 4,244 words, ~8,286 tokens.
.claude/skills/generate-cve-json/SKILL.md (or your agent's skills folder). This skill also uses 13 other files; get the full folder from GitHub.This skill produces a CVE 5.x JSON document from a tracking issue in
<tracker>, ready to
paste into the Vulnogram "#source" tab of the ASF CVE tool. The goal is
to eliminate the manual "copy each field from the issue into the right
Vulnogram form input" step when you are preparing to publish an advisory.
Project-agnostic by design. All project-specific values (vendor, top-level product / package name, project display map, CNA org id, generator tag, …) are loaded from a TOML config the adopting project ships at
<project-config>/tools/cve-tool-vulnogram/cve-json-config.toml. Concreteapache-foo-project-*strings appearing in this document are illustrative examples of how a project with a project-style package layout would configure things; replace them mentally with the adopter's own package taxonomy. The schema is documented in the package README.
Golden rule: the script generates a proposal JSON document. It parses a handful of structured fields from the issue body, but it cannot read the security team member's mind. Always review the generated JSON before pasting, and always do the final review inside Vulnogram before moving the CVE from DRAFT → REVIEW → READY → PUBLIC.
Release-vote gating (opt-in, recommended for ASF projects). The
emitted CNA_private.state follows a tri-state state machine:
DRAFT — the CNA is incomplete or the project has opted into
release-vote gating and no vote is in progress yet.REVIEW — the CNA is review-ready (CVE ID + title + description +
affected versions + CWE + severity + ≥ 1 credit + ≥ 1 reference)
and either the project hasn't opted into gating (legacy: ready ⇒
REVIEW) or an RC vote is in progress (signalled by the configured
tracker label or a --review CLI flag).PUBLIC — the CNA is review-ready and the public advisory has
shipped (a vendor-advisory reference is present).Projects opt into gating by setting [workflow].release_vote_gating = true in their cve-json-config.toml and choosing the label name
via [workflow].rc_voting_label (default "rc voting"). The sync
skill is responsible for detecting [VOTE] threads on the project's
dev list (e.g. dev@<project>.apache.org) and proposing the label
add/remove; the generator only reads the label on the tracker. Non-
ASF adopters who publish advisories without a separate release-vote
step typically leave gating off — the legacy "ready ⇒ REVIEW"
behaviour is the right default for that workflow.
Determinism: the same input issue body produces exactly the same JSON bytes on every run. The script uses only the Python standard library, has no timestamps or machine-dependent values in its output, sorts JSON keys, and sorts references alphabetically. This lets you paste the result into Vulnogram, tweak fields in the tool, re-run the script later, and cleanly diff the two to see what the tool has added / what you changed by hand.
232.--cve-id CVE-YYYY-NNNN+ — override the CVE ID if the issue body's
CVE tool link field has not yet been filled in, or retarget the
JSON to a different CVE ID.
--title "<vendor>: <product>: …" — override the CVE title.
Default is the GitHub issue title with the project's
<vendor>: <product>: prefix (sourced from the TOML config) when
it does not already start with that phrase.
--version-start X.Y.Z — override the start of the affected version
range (the affected[].versions[].version field). Default is the
lower bound parsed from the Affected versions field when it uses
>= X, < Y syntax, otherwise "0".
--remediation-developer "Name" — append a type: "remediation developer" credit on top of whatever the body's Remediation
developer field already lists (auto-populated by the
security-issue-sync skill from the linked PR's author). Repeat
the flag to add multiple developers; duplicates between the
body field and CLI flags are dropped silently. The reporter
credit(s) from the Reporter credited as field are always
emitted with type: "finder".
--vendor / --product / --package-name / --collection-url —
override the product identity fields. The defaults come from the
project's TOML config (product.vendor, product.default_product,
product.default_package_name, product.default_collection_url).
They are used as the identity for Affected versions lines that
don't start with a recognisable per-package directory name
(see the multi-product note below). --collection-url reaches the
record only through the purl it is used to derive (see
product.purl_type below) — except for a product that opts out of
purls, the one case a record still carries a collectionURL.
Helm charts — purl_type = "helm", and you must know where the
chart is published. A chart is identified by its repository, not by
its name: two projects may both ship a chart called superset. So the
generator emits
pkg:helm/<chart>?repository_url=<base URL>taking the base URL from product.default_collection_url (or the
package's collection_url override), and refuses to emit a purl at
all without one rather than producing a chart identifier that matches
somebody else's chart.
If the base URL is not recorded anywhere, ask whoever publishes the
chart. It is whatever a user would put in helm repo add — the
https://… site serving index.yaml, or the oci://… registry path
for a chart published as an OCI artifact. Either is accepted verbatim;
a trailing slash is dropped so the same repository does not produce two
identifiers. Do not infer it from the project's homepage: charts are
routinely served from a different host than the project site.
Note that helm is not one of the types the purl specification
registers. It is used because the scanners that would match this
advisory to a deployed chart emit it, and because the two spec-correct
encodings — pkg:oci/ for an OCI registry and pkg:generic/ for a
classic repository — would give the same chart two different identities
depending on how it happened to be published. A strict validator may
object to the type; being invisible to every scanner is the worse
outcome.
product.purl_type (config only) — the Package URL type
for the project's packages (pypi, npm, cargo, …). Every
affected[] entry carries a packageURL (pkg:<type>/<packageName>).
Per the CVE Record Format the purl never includes a version — the
entry's versions[] carries the range.
The purl is the only package identifier the record carries. The
ASF CVE tool treats the Package URL as the recommended identifier and
derives the legacy collectionURL / packageName pair from it when
the record is serialised for publication, so the generator emits the
purl alone. Writing the pair as well would hand the tool two
identifiers that can disagree — which it reports rather than
silently reconciles.
A purl is required, not optional. A record needs one to be
promoted, so the generator refuses to emit a record it cannot build
a purl for rather than producing one the CNA will reject later.
Leaving the key unset is fine when the type can be derived from
product.default_collection_url — PyPI, npm, crates.io,
RubyGems and NuGet hosts are recognised — and only hosts whose type
is unambiguous are mapped, because a guessed type yields a
valid-looking identifier pointing at the wrong ecosystem.
Set purl_type = "none" to state deliberately that a product has no
package host — a source-only release published to dist.apache.org
and nowhere else, for instance. That is an explicit decision rather than an omission, which
is the distinction the previous optional behaviour lost. Those
entries — and only those — carry collectionURL / packageName
instead, because there is no purl for the CVE tool to derive them
from.
Name normalisation follows the package-url spec per type, and is
implemented for the types whose rules have been read from it:
pypi (lowercased, _ becomes -) and npm (scope becomes the
namespace, so @angular/animation renders as
pkg:npm/%40angular/animation; names keep their case, since
mixed-case npm packages were grandfathered in). Any other type has
its name passed through unchanged, and a name needing namespace
semantics is covered by product.purl_namespace below, and without
one such a type is an error rather than a guessed purl.
product.purl_namespace (optional, config only) — the namespace
for purl types that require one: a Maven groupId, a Composer
vendor, a Go module prefix. Types the spec gives no namespace
(pypi, cargo, gem, nuget) ignore it, and an npm scope
carried in the package name itself wins over it. A type that
requires a namespace and has none is an error naming this key — a
guessed Maven groupId would point at another organisation's artifact,
and silently omitting the purl produces an unpromotable record.
[packages.overrides."<packageName>"] (config only) — per-package
distribution identity, for a project that ships to more than one
ecosystem. Accepts product, collection_url and purl_type; anything
omitted falls through to the product.* default, so a package that
differs only in purl type need not restate its collection URL.
The case this exists for: a project whose packages are on PyPI and
which also ships, say, a Helm chart from its own site. product.*
describes only the majority ecosystem, so without an override the
odd-one-out inherits it and the record claims pkg:pypi/<chart> — a
package that host does not carry. Since purls are what scanners match
on, a wrong one is acted upon, unlike the wrong free-text product name
it replaced.
[packages.overrides."apache-example-helm-chart"]
product = "Apache Example Helm Chart"
collection_url = "https://example.apache.org/"
purl_type = "none"The key is the resolved packageName, so the package must be one the
configured package_pattern matches — extending that pattern is a
prerequisite, not an extra. --product-for still wins over the
product set here.
--product-for PACKAGE=PRODUCT — override the CVE product display
name for a specific packageName. Repeat to override multiple
packages. Useful when a package is not in the project's
project_display_map config, or when an acronym needs different
casing from the title-cased fallback. Example:
--product-for apache-foo-project-baz='Apache Foo Project Baz'.
--org-id <uuid> — override the CNA assigner org id (defaults to
the ASF org id).
--discovery <word> — override source.discovery (default
"UNKNOWN"; valid CVE 5.x values include UNKNOWN, INTERNAL,
EXTERNAL, USER).
--no-envelope — emit only the inner cna container instead of
the full CVE 5.x record (envelope is the default).
--review / --draft (mutually exclusive) — force the emitted
CNA_private.state to REVIEW or DRAFT regardless of the
tracker's labels. Useful in two cases:
--review lets a release manager nudge a record forward by
hand when the rc voting label is not yet set on the tracker.--draft walks a record back when an RC vote was cancelled or
failed and the label is still around.
Both flags only matter when release-vote gating is enabled in
the project's TOML config (see below); otherwise the state is
derived from the CNA's readiness alone and these flags have no
effect beyond what the legacy logic produces.--attach — after generating the JSON, embed it at the end of
the tracking issue's body (after the CVE tool link field),
wrapped in a collapsible <details> block. The block is bracketed
by HTML-comment markers
(<!-- generate-cve-json: cve=CVE-YYYY-NNNN+ version=v1 --> …
<!-- generate-cve-json:end cve=CVE-YYYY-NNNN+ version=v1 -->)
that the script uses on later runs to find the existing block and
replace it in place, so re-runs update the embedded attachment
instead of duplicating it or breaking other body fields. The
attachment lives in the body — not as a comment — so it stays
above every status-change comment in the timeline (effectively
"pinned" without needing any pin mechanism). Requires the
positional issue argument; incompatible with --stdin.
For the generated JSON to be useful, the issue body should already be
filled in through a prior security-issue-sync run. In particular:
Short public summary for publish — becomes the CVE description.
Affected versions — becomes the CVE affected[] list. The script
understands the common version-expression shapes (< 3.2.2,
>= 2.0.0, < 3.2.2, <= 3.2.1, a bare version like 3.1.5, and a
bare lower bound like >= 2.0.0).
Multi-product CVEs are supported — put one package per line,
prefixing each with the package directory name as it appears in
the adopter's repo, and the script emits one affected[] entry
per line with the right product and package identity. Example
(illustrative — using a hypothetical apache-foo project's
sub-project layout):
apache-foo-project-alpha <=6.5.0
apache-foo-project-beta <=1.9.0Known package directory names are resolved to the vendor-preferred
display casing via the project's packages.project_display_map
config table; unknown packages fall back to title-cased dash-split
and can be overridden with --product-for. A line without a
package prefix (or a single-line field) falls back to the
--product / --package-name defaults, which preserves the
single-product behaviour.
< NEXT VERSION placeholder — multi-package trackers don't
know which package version will ship the fix until the wave's
release manager picks it during a release cut. Until then, the
Affected versions lines use the literal token NEXT VERSION as
the upper bound, e.g.:
apache-foo-project-alpha < NEXT VERSION
apache-foo-project-beta < NEXT VERSIONThe generator strips < NEXT VERSION before parsing each line and
emits a versions[] entry without lessThan (open-ended upper
bound — "affected from <low> onwards, no fix released yet").
When the wave ships and the version is known, the
security-issue-sync skill replaces each NEXT VERSION with the
actual < X.Y.Z and the next regen produces a fully-bounded entry.
Case-insensitive; combines with a lower bound (e.g.
>= 2.0.0, < NEXT VERSION becomes {version: "2.0.0", status: "affected"}).
Security mailing list thread — internal navigation reference
only; the script does not export URLs from this field into
references[]. Keep whatever the reporter or triager put there.
Public advisory URL — each URL in this field is extracted and
added to references[] with tags: ["vendor-advisory"]. Populated
by the release manager (or the security-issue-sync skill) once
the advisory is archived on <users-list>. The
--advisory-url CLI flag still exists for ad-hoc overrides.
PR with the fix — each URL in this field becomes a reference URL.
Multiple URLs are supported: paste them on separate lines, as a
bullet list, or comma-separated — the script extracts every
https?://… token it finds.
Reporter credited as — each line becomes one CVE credit entry
with type: "finder". Multiple credits are supported: put each
person on their own line. Full Name, Affiliation on a single line
is treated as one credit, not two, so the common
Jed Cunningham, Astronomer pattern works as expected. Bullets
(- , * , 1. ) are stripped. Blank lines are ignored. If you
need to credit many people::
Jed Cunningham
Saurabh Banawar
selen (Huntr bounty 3e88d364-5047-4768-a52c-6568f21ef35b)
Remediation developer — each line becomes one CVE credit entry
with type: "remediation developer". Same parsing rules as
Reporter credited as (newline-separated, Full Name, Affiliation
is one credit, bullets stripped). Auto-populated by the
security-issue-sync skill from the linked PR's author the first
time PR with the fix is set; manual edits survive subsequent
syncs (the skill only proposes appending names that aren't already
there). The --remediation-developer CLI flag adds further names
on top of whatever the body already lists.
Bot / AI credit policy. This generator is intentionally neutral on credit content: whatever a tracker's Reporter credited as or Remediation developer field carries is what lands in
credits[]. The filtering of obvious bot / AI accounts (e.g.dependabot[bot],*-scanner,automated-*) happens upstream in the skills at extraction time — seebot-credits-policy.mdfor the detection rule and the per-skill enforcement sites. Keeping the filter upstream means an intentional human override (typed directly into the field) survives every JSON regeneration without needing a special bypass flag here.
CWE-285: Improper Authorization style works; so does a bare
CWE-285 or a plain sentence. The script extracts the CWE-\d+ token
for the cweId field and uses the rest as the human-readable
description.None, Low, Medium, High, Critical
(case-insensitive) are emitted as the text content of a metrics[].other
block. Vulnogram lets you replace this with a CVSS vector in its form if
you want a numeric score.https://cveprocess.apache.org/cve5/CVE-2026-40913. The script extracts
the CVE-YYYY-NNNN+ token from this field. If the field is still
_No response_, pass the CVE ID with --cve-id.If one of these fields is missing, the JSON still generates, but the reviewer will need to fill the gap in Vulnogram. The skill surfaces any empty field in the proposal so nothing is silently skipped.
gh CLI authenticated with collaborator access to
<tracker> — the script reads the tracker via gh.uv installed — the script is a small uv-managed Python
project and is invoked as uv run --project tools/cve-tool-vulnogram/generate-cve-json generate-cve-json <N>.See
Prerequisites for running the agent skills
in README.md.
Before reading the tracker:
gh api repos/<tracker> --jq .name returns the adopter's
tracker repo name (per <project-config>/project.md), anduv --version returns.If either fails, stop and tell the user what to install or log in to.
Fetch the issue body and check every template field the script reads. If
a field is missing or still _No response_, either run
security-issue-sync first to fill it
in, or override it on the command line.
gh issue view <N> --repo <tracker> --json body --jq .body \
| grep -E '^###|^_No response_'Ask the user whether to proceed if any critical field is empty (description, affected versions, CVE tool link, credits). Do not silently generate a JSON with placeholder values.
Run the project's console script through uv run --project, which
prepares the (cached) virtualenv on first use and reuses it on later
runs:
uv run --project <framework>/tools/cve-tool-vulnogram/generate-cve-json generate-cve-json <N> \
--output /tmp/<CVE-ID>.json \
--version-start <earliest-affected-version>--version-start is the one flag the tracking issue body almost never
contains and that Vulnogram expects filled in (the body field usually
encodes only the upper bound). The remediation developer credit comes
from the body's Remediation developer field, populated by the
security-issue-sync skill from the linked PR's author — no CLI flag
needed in the normal flow. For a fix that landed in 3.2.2 and was
first introduced in 3.0.0, for example:
uv run --project <framework>/tools/cve-tool-vulnogram/generate-cve-json generate-cve-json 232 \
--output /tmp/CVE-2026-40913.json \
--version-start 3.0.0Pass --remediation-developer "Name" only when you need to add a
developer credit on top of (or in place of) what the body already
contains — for example a co-author who didn't end up as the PR's
GitHub author.
Additional flags, all optional:
--cve-id CVE-YYYY-NNNN+ — override the CVE ID if the CVE tool link
field is empty.--title "<vendor>: <product>: …" — override the title.--vendor / --product / --package-name / --collection-url —
override product identity (defaults sourced from the project's TOML
config under [product]).--org-id <uuid> — override the CNA assigner org id (defaults to the
ASF org id).--discovery UNKNOWN|INTERNAL|EXTERNAL|USER — override
source.discovery.--no-envelope — emit only the cna container (no cveMetadata,
no dataType/dataVersion wrapper). Use this if Vulnogram's #source
tab is in "inner block only" mode.--stdin — read the issue body from stdin instead of calling gh.
Useful for offline iteration and for drafting by hand.The script is deterministic — re-running it with the same flags and the same tracking-issue body produces the same JSON bytes.
The generated record matches what Vulnogram exports after a save, minus editor cruft. Notable fields:
containers.cna.affected[] — vendor, product, packageURL (the
version-less purl) and a versions[] entry with version, lessThan,
status: "affected", versionType: "semver". An entry for a product
configured with purl_type = "none" carries collectionURL /
packageName in place of the purl.containers.cna.descriptions[] — both a plain value and an HTML
supportingMedia alternative (Vulnogram's WYSIWYG mode needs both).containers.cna.problemTypes[].descriptions[] — cweId,
human-readable description, type: "CWE".containers.cna.metrics[].other — type: "Textual description of severity" and content.text = the severity word.containers.cna.credits[] — one entry per Reporter credited as
line (type "finder"), plus one entry per Remediation developer
body line and per --remediation-developer CLI override (type
"remediation developer"); duplicates between the body field and
CLI flags are dropped silently.containers.cna.references[] — URLs with auto-tagged tags:pull/ or commit/ URLs → ["patch"];lists.apache.org / security.apache.org → ["vendor-advisory"];containers.cna.source.discovery — "UNKNOWN" by default.containers.cna.providerMetadata.orgId — ASF assigner org id.cveMetadata — assignerOrgId, cveId, serial, state: "PUBLISHED".After the script finishes, print these three things in order:
The output file path, with a one-line cat suggestion so the user
can review the JSON in the terminal:
```
Wrote /tmp/cve-CVE-2026-40913.json
cat /tmp/cve-CVE-2026-40913.json
```
A clipboard-copy command appropriate to the user's platform. On
Linux with xclip installed:
```
xclip -selection clipboard < /tmp/cve-CVE-2026-40913.json
```On Wayland: wl-copy < /tmp/cve-...json. On macOS: pbcopy < …. If
xclip / wl-copy / pbcopy is not on PATH, skip the clipboard
command and tell the user to copy manually.
The Vulnogram #source paste URL, as a clickable link rendered per
the "Linking CVEs" rule in AGENTS.md:
```
Paste the JSON into the Vulnogram #source tab:
[CVE-2026-40913](https://cveprocess.apache.org/cve5/CVE-2026-40913#source)
```The #source tab on the ASF CVE tool is the direct "paste raw JSON" view of the Vulnogram form. The page loads the current record, you paste the script output over the top, click Save, and the form view reflects the new values.
--attach to embed (or refresh) the JSON in the issue bodyIf the user also wants the JSON attached to the tracking issue itself
(so it is discoverable from the issue without needing the local file),
add --attach to the invocation:
uv run --project <framework>/tools/cve-tool-vulnogram/generate-cve-json generate-cve-json 232 \
--output /tmp/CVE-2026-40913.json \
--version-start 3.0.0 \
--attachWhat --attach does:
--attach),
edits the tracking issue's body to embed the full JSON inside a
four-backtick fenced code block, collapsed behind a <details>
disclosure so long records don't bloat the issue view. The block is
appended after the existing template fields, right after the
CVE tool link field, so it lives at the end of the body.<!-- generate-cve-json: cve=CVE-YYYY-NNNN+ version=v1 --> …
<!-- generate-cve-json:end cve=CVE-YYYY-NNNN+ version=v1 -->) so
subsequent runs can find the existing embedded block and replace it
in place, without spawning duplicates and without touching any
other text in the body.--attach is safe and idempotent: same issue body →
same JSON → the script patches the body, leaving you with one and only
one embedded attachment per CVE id. If the current body already
matches what the script would write, the PATCH is skipped entirely
(no no-op timestamp on the issue).Embedded CVE JSON in issue body on <tracker>#NNN on first run and Replaced CVE JSON in issue body on <tracker>#NNN on subsequent runs, followed
by a URL that deep-links to the ## CVE JSON — paste-ready for …
heading anchor inside the body.Why embedded in the body and not as a comment? Two reasons:
(GitHub also does not expose its user-attachments file-upload
pipeline to the REST API — only the web UI drag-and-drop uses it — so
a real file attachment isn't available to automation anyway. Embedding
as body text is the closest automatable equivalent and is directly
visible without a download round-trip.)
Confidentiality. The embedded block lives inside the private repo,
so it inherits the repo-wide confidentiality rules. Linking CVE
references inside the block follows the "Linking CVEs" rule in
AGENTS.md: before publication the block links
the ASF CVE tool; after publication, re-running the script includes a
cve.org link as well.
Per the "Keeping the reporter informed" rule in
README.md, any status change on an issue must be
recorded in an issue comment. Pasting a new version of the CVE record is
a status change. Propose (and, on confirmation, post) a short comment
like:
CVE entry regenerated from the tracking issue — generated paste-ready JSON for
CVE-2026-40913from the current body fields (description, affected versions< 3.2.2, CWE-285, Low severity, N credits, M references). Pasted into the Vulnogram#sourcetab; the record is now in sync with the tracking issue.
Include a count of credits and references so a later reviewer can sanity-check that nothing was dropped.
Once the JSON has been pasted into Vulnogram and saved, do not edit
the local JSON file to match tool-side changes. Re-run the script instead
(it is deterministic — you will get a clean baseline), diff the new
output against the current Vulnogram state, and paste the merged JSON
back. This keeps the tracking issue as the single source of truth: if
Vulnogram shows something different from the generated JSON, either the
issue body is out of date and needs a security-issue-sync run, or the
tool-side difference is intentional and the reviewer will keep it.
cveprocess.apache.org or the project's <tracker> repo
from the references list before serialising. Those URLs are private
ASF-internal links and should not appear in a published CVE record.
See the "Confidentiality of <tracker>" section of
AGENTS.md.AGENTS.md. When the skill mentions the CVE in
proposals, recaps or comments on the <tracker> issue, it must
render the ID as a markdown link — before publication to the ASF
CVE tool, and additionally to cve.org after publication.<tracker> references are always linked per the "Linking
<tracker> issues and PRs" rule in
AGENTS.md. When the skill mentions the
tracking issue in its own comments, render it as a markdown link.Full Name, Affiliation pattern. References are extracted
from URL tokens in the field value. Do not reintroduce comma-splitting
on credits.--no-envelope drops the
cveMetadata block which includes the CVE ID; the JSON is pure CNA
content. Make sure the user knows they will have to set the CVE ID by
hand in Vulnogram in that mode.AGENTS.md — repo-wide conventions (confidentiality,
Linking CVEs, Linking <tracker> issues and PRs, release-branch
defaults).README.md — handling process, in particular
step 13 (fill in CVE tool fields and send advisory from the tool)
and step 15 (paste the attached JSON into Vulnogram's #source tab,
move the CVE to PUBLIC, close the issue).security-issue-sync — the sibling
skill that populates the tracking issue fields this skill consumes.security-issue-fix — the other
sibling skill that opens a public PR and updates the tracking issue
with the fix URL.© apache, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 13 other files in tools/cve-tool-vulnogram/generate-cve-json of apache/magpie.
Open the folder on GitHubat commit f3cab5c
We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in apache/magpie, which our catalogue first saw on October 8, 2026.
Generate Cve JSON next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Generate Cve JSON this skillapache/magpie | 112 | 1 repos | ~8.3k | Automated safety check: Pass | Apache-2.0 | |
| Deepsec Documentation Guidevercel-labs/deepsec | 8.1k | — | ~956 | Automated safety check: Pass | Apache-2.0 | |
| Shiro Attack CLISummerSec/ShiroAttack2 | 2.6k | — | ~945 | Automated safety check: Pass | MIT | |
| Cve Remediationrundeck/rundeck | 6.3k | — | ~2.9k | Automated safety check: Pass | Apache-2.0 | |
| Native Dependency Updatemono/SkiaSharp | 5.6k | — | ~4.1k | Automated safety check: Pass | MIT | |
| Forensifyalexgreensh/repo-forensics | 188 | — | ~2.5k | Automated safety check: Notes | Custom licence |
vercel-labs/deepsec
Points the agent at deepsec's own docs to answer questions about initializing, configuring, resuming, scanning with and extending the vulnerability scanner.
SummerSec/ShiroAttack2
当用户要求利用、检测或测试 Apache Shiro rememberMe 反序列化漏洞 (Shiro-550, CVE-2016-4437) 时使用。触发词包括 "Shiro"、"rememberMe"、"shiro attack"、"CVE-2016-4437"、"Shiro-550"、"爆破 Shiro key"、"利用 Shiro"、"Shiro…
rundeck/rundeck
Verify if a CVE affects the project and remediate it. An agent skill from rundeck/rundeck.
mono/SkiaSharp
Update native dependencies (libpng, libexpat, zlib, libwebp, harfbuzz, freetype, libjpeg-turbo, etc.) in SkiaSharp's Skia fork.
alexgreensh/repo-forensics
Cross-agent self-inspection of your AI-agent stack. An agent skill from alexgreensh/repo-forensics.
evdenis/cvehound
Write, debug, or validate a CVEhound detection rule (.cocci or .grep) for a Linux kernel CVE.
apache/magpie
Scan the release distribution area (dist/release/<project/ when releasedistbackend = svnpubsub, or the configured distribution location), identify releases past the project's retention rule, and…
apache/magpie
Read-only audit of GitHub Actions runner compatibility for one repository, a repository set, one Apache project, or the full Apache org.
apache/magpie
Add the Release Manager's public key to the project KEYS file: check it meets the ASF strength floor, draft the KEYS diff, and emit the svn (or backend) commands and keyserver reminder for the RM to…
apache/magpie
Print a human-readable index of every skill installed for this repository, grouped by the family each one declares, with the name to invoke it by and the first sentence of its description.
apache/magpie
Draft a teaching-register comment on a GitHub issue or PR thread on the configured <upstream repo, aimed at a contributor missing context the maintainer would spell out.
apache/magpie
Show how Magpie is adopted in this repo — install method and pin, drift, wired agent targets, installed skill families, symlink health — and change that wiring from the same view.
Categories
Generate a CVE 5.x JSON document from an <tracker tracking issue, ready to paste into the Vulnogram source tab of the ASF CVE tool at https://cveprocess.apache.org/cve5/<CVE-IDsource. Generate Cve JSON is an agent skill from apache/magpie.org/cve5/<CVE-IDsource.
Generate Cve JSON fits situations like: tasks that involve Vulnerability scanning.
Run `npx skills add apache/magpie --skill generate-cve-json -a claude-code`. Or copy the skill folder (tools/cve-tool-vulnogram/generate-cve-json in apache/magpie) into .claude/skills/generate-cve-json in your project. Claude Code loads it when a task matches its description.
Run `npx skills add apache/magpie --skill generate-cve-json -a codex`. Or copy the skill folder (tools/cve-tool-vulnogram/generate-cve-json in apache/magpie) into .agents/skills/generate-cve-json in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add apache/magpie --skill generate-cve-json -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/generate-cve-json, .gemini/skills/generate-cve-json, .github/skills/generate-cve-json and .opencode/skills/generate-cve-json in your project.
Going by SKILL.md and its folder, Generate Cve JSON needs Python for the scripts in its folder and the command-line tools its instructions call (uv, gh and helm). Our summary lists: Python 3.
SKILL.md names 2 domains. In commands or code: cveprocess.apache.org; the agent is likely to contact it when it follows the instructions. As links in the text: github.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Generate Cve JSON is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 8.3k tokens (SKILL.md is roughly 33k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Generate Cve JSON: Deepsec Documentation Guide (vercel-labs/deepsec, 8.1k stars), Shiro Attack CLI (SummerSec/ShiroAttack2, 2.6k stars), Cve Remediation (rundeck/rundeck, 6.3k stars) and Native Dependency Update (mono/SkiaSharp, 5.6k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
apache (a GitHub organization) maintains it in apache/magpie, which has 112 GitHub stars. The repository holds 48 skills in this directory. The repository was last updated on October 7, 2026.
Source: apache/magpie on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.