Skip to content

feat(security): config schema + adapter contracts (PR1/5)#381

Merged
potiuk merged 2 commits into
apache:mainfrom
potiuk:feat-security-genericization-pr1-schema
May 30, 2026
Merged

feat(security): config schema + adapter contracts (PR1/5)#381
potiuk merged 2 commits into
apache:mainfrom
potiuk:feat-security-genericization-pr1-schema

Conversation

@potiuk
Copy link
Copy Markdown
Member

@potiuk potiuk commented May 30, 2026

Summary

First of 5 PRs converting the security skill family from
Airflow/ASF-coupled to a generic framework with ASF as the
default-configured option.

This PR is pure additions — zero behaviour change. Every
existing ASF assumption gets a config knob with the current
behaviour as the default, so the airflow-s reference adopter is
byte-equivalent to today.

Scope

Based on a discovery audit (179 findings across 18 files) that
catalogued every ASF/Airflow hardcoded assumption in the security
skill family and grouped them into 11 dimensions: cve_authority,
governance, security_inbox, forwarders, mail_provider,
archive_system, tracker, scope_detection, release_process, roster,
product.

Files

  • projects/_template/project.md — new Security workflow
    configuration
    section with 11 YAML blocks. Every field carries
    a comment naming what it controls, the ASF default, when a
    non-ASF adopter would override it, and the 1-3 skills that
    consume it.

  • tools/cve-tool/README.md — adapter contract for CNA
    backends. Defines the interface every CVE-authority adapter must
    implement (allocate, fetch_current_state, push_update,
    publish, retract) plus a generic state-verb mapping
    (allocatedreview-readypublish-readypublic).
    ASF-default adapter: tools/vulnogram/ (renamed to
    tools/cve-tool-vulnogram/ in PR4).

  • tools/mail-archive/README.md — adapter contract for
    public mail-archive backends. Defines search_thread_url,
    fetch_thread_by_url, list_recent_threads,
    publication_signal_url. ASF-default adapter: tools/ponymail/
    (renamed in PR3).

  • tools/forwarder-relay/README.md — adapter contract for
    forwarder-relay inbound paths. Defines detect,
    extract_credit, contact_handle, preamble_match,
    reporter_addressing_block. ASF-default adapter: the ASF
    Security forwarder shape in tools/gmail/asf-relay.md
    (renamed in PR3).

  • docs/labels-and-capabilities.md — 3 new rows for the new
    tool stubs (all capability:setup, pure interface specs).

What is not in this PR

  • No skill body changes.
  • No tool implementations renamed.
  • No ASF-default adapter changes — tools/vulnogram/,
    tools/ponymail/, tools/gmail/asf-relay.md continue to be
    the only shipping adapters and continue to be referenced where
    they always have been.

Skills will be lifted to read these knobs in PR2–PR5.

Coming up

  • PR2 — trivial config-driven lifts: security-tracker-stats-dashboard,
    security-issue-fix, security-issue-deduplicate,
    security-issue-import-from-md, security-issue-triage,
    security-issue-import-from-pr.
  • PR3 — forwarder + archive sub-tools: rename
    tools/ponymail/ and tools/gmail/asf-relay.md as ASF-default
    adapters; update security-issue-import (drop ASF-security relay row from generic body, push into optional sub-skill),
    security-issue-invalidate (Step 5d), security-issue-sync
    Step 2b.
  • PR4 — CVE-authority sub-tool extract: biggest of the five.
    Rename tools/vulnogram/tools/cve-tool-vulnogram/.
    Rewrite security-cve-allocate, security-issue-sync (Steps
    5b/5c — the 600-line section), security-issue-invalidate
    Step 0, security-issue-deduplicate,
    docs/security/process.md Steps 12-14, docs/security/roles.md
    against the <cve-tool> placeholder and tool-agnostic state
    verbs.
  • PR5 — docs + final scrub: docs/security/threat-model.md,
    forwarder-routing-policy.md, how-to-fix-a-security-issue.md,
    new-members-onboarding.md; delete remaining literal
    @potiuk / @raboof / Apache Airflow / airflow | providers | chart from skill bodies and templates.

Test plan

  • uv run --project tools/skill-and-tool-validator skill-and-tool-validate
    clean (1 pre-existing soft warning on an unrelated skill).
  • pytest clean for the validator (218 tests).
  • All pre-commit hooks pass (markdownlint, doctoc, typos,
    check-placeholders, etc.).
  • Spot-read the rendered project.md on GitHub and confirm
    table formatting / YAML-block rendering looks right.
  • Confirm the airflow-s adopter still resolves every existing
    ASF behaviour without changes (byte-equivalence invariant).

First of 5 PRs converting the security skill family from
Airflow/ASF-coupled to a generic framework with ASF as the
default-configured option.

This PR is pure additions — zero behaviour change. Every existing
ASF assumption gets a config knob with the current behaviour as
the default, so the airflow-s reference adopter is byte-equivalent.

Additions:

- projects/_template/project.md — new "Security workflow
  configuration" section with 11 YAML blocks covering every
  ASF-coupling dimension surfaced by the discovery audit
  (179 findings across 18 files): cve_authority, governance,
  security_inbox, forwarders, mail_provider, archive_system,
  tracker, scope_detection, release_process, roster, product.
  Every field carries a comment naming what it controls, the
  ASF default, when a non-ASF adopter would override it, and the
  1-3 skills that consume it.

- tools/cve-tool/README.md — adapter contract for CNA backends.
  Defines the interface every CVE-authority adapter must
  implement (allocate, fetch, push, publish, retract) plus a
  generic state-verb mapping (allocated -> review-ready ->
  publish-ready -> public). ASF-default adapter: tools/vulnogram/
  (renamed to tools/cve-tool-vulnogram/ in PR4).

- tools/mail-archive/README.md — adapter contract for public
  mail-archive backends. Defines search_thread_url,
  fetch_thread_by_url, list_recent_threads, publication_signal_url.
  ASF-default adapter: tools/ponymail/ (renamed in PR3).

- tools/forwarder-relay/README.md — adapter contract for
  forwarder-relay inbound paths. Defines detect, extract_credit,
  contact_handle, preamble_match, reporter_addressing_block.
  ASF-default adapter: the ASF Security forwarder shape in
  tools/gmail/asf-relay.md (renamed in PR3).

- docs/labels-and-capabilities.md — 3 new rows for the new
  tool stubs (all capability:setup, pure interface specs).

No skill bodies touched. No tool implementations renamed. No
ASF-default adapter changes. Skills will be lifted to read these
knobs in PR2-PR5.

Generated-by: Claude Code (Opus 4.7)
…ts-policy

The drafted files referenced `<tool>/contract.md` but were written
as `<tool>/README.md` (matching the validator's required filename).
Update project.md cross-references accordingly.

Also fix one hallucinated link in tools/forwarder-relay/README.md
that pointed at `docs/security/reporter-credit-policy.md` (file does
not exist) — repoint to the actual bot/AI credit policy doc at
`tools/vulnogram/bot-credits-policy.md`.

Generated-by: Claude Code (Opus 4.7)
@potiuk potiuk merged commit 70a95c5 into apache:main May 30, 2026
16 checks passed
potiuk added a commit that referenced this pull request May 30, 2026
Second of 5 PRs converting the security skill family from
Airflow/ASF-coupled to a generic framework.

PR1 (#381) landed the schema + adapter contracts with ASF
defaults. This PR lifts 6 skills to read those knobs (and the
existing sibling adopter-config files) instead of inlining
ASF/Airflow values. Byte-equivalent for the airflow-s adopter:
every value the skill currently inlines either becomes a
reference to a config knob whose ASF default matches today's
inlined value, OR keeps the inlined airflow-s value as a single
named example in generic prose.

Per-skill lifts:

- security-tracker-stats-dashboard (+15/-6 SKILL.md, +14/-2
  default-config.yaml) — cross-reference `scope_detection.labels`
  and `tracker.labels` in default-config.yaml comments; no
  literal default values changed.

- security-issue-deduplicate (+26/-15) — golden-rule scope cross-
  merge, scope-check, milestone shapes, and the CVE-record URL
  now reference `scope_detection.labels`, `<project-config>/milestones.md`,
  and `cve_authority.record_url_template`.

- security-issue-import-from-md (+18/-5) — `<security-list>`
  placeholder uses, body-field heading mapping ->
  `tracker.body_fields`, label list -> `tracker.labels`, scope
  rule -> `scope_detection.labels`.

- security-issue-fix (+78/-48) — toolchain commands (`uv`,
  `breeze`, `prek`) -> `<project-config>/fix-workflow.md`; package
  registries -> `release_process.artifact_registries`;
  `apache/airflow` -> `<upstream>`; `main` -> `<default-branch>`;
  local-clone probe paths kept as airflow-s examples in generic
  prose.

- security-issue-triage (+48/-27) — scope-label triads ->
  `scope_detection.labels`; canned-response examples reframed
  as airflow-s named examples in generic guidance; `@`-handle
  routing -> roster references.

- security-issue-import-from-pr (+85/-45) — biggest lift in this
  batch. Project-board node IDs de-inlined (already in
  project.md "GitHub project board" table). Scope cascade
  (`airflow|providers|chart` triad) -> `scope_detection.labels`
  with the airflow-s mapping kept as one named example.
  `Apache Airflow:` title-prefix -> `<vendor>: <product>:`
  derived from `project.md`.

Aggregate: +280/-129 lines across 7 files. Validator clean
(1 pre-existing soft warning on an unrelated skill). 218 tests
green. No new placeholders introduced beyond those declared in
PR1's schema.

Out of scope: no ASF-default adapter (`tools/vulnogram/`,
`tools/ponymail/`, `tools/gmail/asf-relay.md`) is touched — those
are PR3/PR4. No skill outside the 6 above is touched. The
deeper Vulnogram-state-machine refactor in `security-issue-sync`,
`security-cve-allocate`, and `security-issue-invalidate` is PR4.
The forwarder-relay sub-skill extract is PR3.

Generated-by: Claude Code (Opus 4.7)
potiuk added a commit that referenced this pull request May 30, 2026
Third of 5 PRs converting the security skill family from
Airflow/ASF-coupled to a generic framework.

PR1 (#381) landed the adapter contracts. PR2 (#386) lifted the
config-driven skills. This PR extracts the ASF-Security
forwarder + PonyMail archive specifics into:

- a new optional sub-skill `security-issue-import-via-forwarder`
  that the generic intake/invalidate/sync skills invoke when
  `forwarders.enabled` is non-empty
- explicit cross-references from the adapter-contract READMEs
  to their default-ASF implementations (`tools/gmail/asf-relay.md`
  for the asf-security forwarder; `tools/ponymail/` for the
  ponymail mail-archive)

Byte-equivalent for the airflow-s adopter: every behaviour the
ASF-relay row + Step 5d + Step 2b previously produced is now
reachable via the sub-skill, which the airflow-s adopter
installs by default (`forwarders.enabled: [asf-security]`).

== New sub-skill ==

`.claude/skills/security-issue-import-via-forwarder/SKILL.md`
(+620 lines). Adapter-agnostic body — no `asf-security` /
`huntr-relay` / `hackerone-relay` string in control flow.
Reads enabled adapters from `forwarders.enabled` in
project.md, dispatches via `detect()` / `extract_credit()` /
`reporter_addressing_block()` from
`tools/forwarder-relay/README.md`. Four steps:

  Step 0 — Pre-flight check
  Step 1 — Detect adapter match
  Step 2 — Extract reporter credit
  Step 3 — Route reporter-facing drafts
  Step 4 — Hand back to parent skill

Frontmatter: `capability: capability:intake`. Validator clean.

== Skill lifts ==

- security-issue-import (-60/+54 net -6) — dropped the
  ASF-security-relay row from the Step 3 classification table;
  replaced with a pre-classification paragraph that points at
  the sub-skill when `forwarders.enabled` is non-empty.
  Generalized the Step 7 receipt-of-confirmation routing and
  every other inline `ASF-security relay` / `Report` pairing
  (golden-rule prose, Step 4 field-extraction header, Step 5
  proposal grouping, Step 6 default-disposition, rollup
  provenance template, Hard Rules).

- security-issue-invalidate (-49/+93 +44) — Step 5d ASF-relay
  inline logic replaced with adapter-aware routing through the
  sub-skill + `tools/forwarder-relay/README.md`. Four touch-
  points lifted; ASF retained as a named example in worked-
  example sections.

- security-issue-sync (-20/+20 ±0) — scoped Step 2b lift only
  (the big Vulnogram-state-machine rewrite at Steps 5b/5c is
  PR4). Draft routing now reads adapter metadata from the
  sub-skill's hand-back; no inline `Dear PMC` preamble match.

== Adapter-contract README cross-references ==

- tools/forwarder-relay/README.md (+24) — explicit
  "Implementation: tools/gmail/asf-relay.md" pointer for the
  asf-security adapter + sub-skill consumer link.

- tools/mail-archive/README.md (+19) — explicit
  "Implementation: tools/ponymail/" pointer + the skills
  that consume PonyMail today (intake / sync / invalidate).

== Doc table ==

docs/labels-and-capabilities.md gets a new row for
`security-issue-import-via-forwarder` → `capability:intake`
(satisfies the capability-sync check).

Aggregate: 7 files changed, +795/-116. Validator clean
(5 advisory soft warnings, none hard, none on PR1/PR2-touched
files). 218 tests green.

Out of scope (deferred to PR4/PR5):

- `tools/vulnogram/`, `tools/gmail/asf-relay.md` bodies (this
  PR only updates cross-references TO them, not their content)
- `tools/ponymail/` body (same)
- `security-issue-sync` Steps 5b/5c CVE-state-machine rewrite
  (PR4 — the ~600-line section)
- `security-cve-allocate` Vulnogram-specific body (PR4)
- `docs/security/process.md`, `forwarder-routing-policy.md`,
  `roles.md`, `threat-model.md` (PR5)

Generated-by: Claude Code (Opus 4.7)
potiuk added a commit that referenced this pull request May 30, 2026
* chore(security): rename tools/vulnogram/ -> tools/cve-tool-vulnogram/

Prep commit for PR4 (CVE-authority sub-tool extract).

Mechanical rename only:
- `git mv tools/vulnogram tools/cve-tool-vulnogram`
- 40 files updated via search-and-replace for the path string
- docs/labels-and-capabilities.md tool-table row repositioned to
  alphabetical order, description updated to name it as the
  default adapter implementing the tools/cve-tool/ contract

No behaviour change. Skills continue to reference the directory
at its new path. The substantive lift to read the cve_authority
config + tool-agnostic state verbs is the next commit on this
branch.

Generated-by: Claude Code (Opus 4.7)

* feat(security): CVE-authority sub-tool extract (PR4/5)

Fourth of 5 PRs converting the security skill family from
Airflow/ASF-coupled to a generic framework with ASF as the
default-configured option.

This is the biggest skill-side PR. The previous commit on this
branch (ca47278) did the mechanical rename
tools/vulnogram/ -> tools/cve-tool-vulnogram/. This commit does
the substantive content lift: 4 skills + 2 docs rewritten to
read the cve_authority config block + speak in tool-agnostic
state verbs.

Byte-equivalent for the airflow-s adopter: cve_authority.tool:
vulnogram (the ASF default) resolves <cve-tool> to
cve-tool-vulnogram, the Vulnogram-native DRAFT/REVIEW/READY/PUBLIC
states are preserved as named-example asides, every Vulnogram CLI
(vulnogram-api-setup, vulnogram-api-check,
vulnogram-api-record-update, vulnogram-api-record-fetch) is still
named where the operator's command-line invocation fires.

Per-target lifts:

- security-cve-allocate (+222/-137) — frontmatter description
  speaks of governance.cve_allocation_gate + the configured
  <cve-tool> allocation URL; preamble declares <cve-tool>
  placeholder. Body: intro paragraph reads
  cve_authority.allocate_url; PMC-only golden rule becomes
  governance.cve_allocation_gate + governance.roster_url; Step 0
  preflight uses generic governance-authorisation; Step 2 / Step 3
  / Step 4 / Step 7 read cve_authority.* knobs and reference the
  contract in <cve-tool>/README.md. Rollup template uses
  <record-url>/<source-tab-url> tokens substituted from
  cve_authority.record_url_template /
  cve_authority.source_tab_url_template.

- security-issue-sync Steps 5b/5c (+139/-91) — the
  largest single section. Step 5b reframes the push as the
  contract's push_update(cve_id, fields, state_transition=None)
  method; replaces DRAFT/REVIEW/READY/PUBLIC with generic verbs
  (allocated / review-ready / publish-ready / public),
  Vulnogram-native tokens kept as named-example asides;
  publish() method called via cve_authority.publication_propagation;
  post-push state verification via fetch_current_state(cve_id).
  Step 5c generalises the variant-template table to
  tools/<cve-tool>/... paths and replaces OAuth-push branch
  labels with push_update succeeded / failed terminology.

- security-issue-invalidate Step 0 (+29/-1) — hard-stop check
  on CVE state lifts from Vulnogram DRAFT/REVIEW/REJECTED to
  generic state verbs (allocated / review-ready); the
  separate retract flow reference becomes the adapter's
  retract() method per <cve-tool>/README.md.

- security-issue-deduplicate (+54/-6) — dedup-when-both-have-CVE
  branch speaks in state verbs; merge-of-credits flow
  references <cve-tool>'s push_update() per the contract;
  regenerate-CVE-JSON step mentions adapter storage.

- docs/security/process.md Steps 12-14 (+96/-53) — allocate
  / update / publish steps reference cve_authority.* knobs +
  <cve-tool> methods + state verbs; Vulnogram URLs kept as
  named-example asides.

- docs/security/roles.md (+50/-27) — role descriptions lift
  Vulnogram-specific OAuth + state-machine references to
  cve_authority knobs + generic state verbs; PMC ->
  governance-authorisation under governance.cve_allocation_gate.

Aggregate: 6 files, +590/-315 lines. Validator clean (5 advisory
soft warnings, none hard, all on files outside PR4 scope).
218 tests green.

The generic surface (push_update, fetch_current_state, publish,
retract, allocate) is the contract layer in tools/cve-tool/README.md
(landed in PR1 #381). The Vulnogram adapter is now an
implementation of that contract, named where the operator's
command-line tool actually fires; the skill body speaks contract.

Out of scope (PR5):

- docs/security/threat-model.md, forwarder-routing-policy.md,
  how-to-fix-a-security-issue.md, new-members-onboarding.md
- Final scrub: any remaining literal @potiuk / @raboof /
  Apache Airflow / airflow | providers | chart in skill bodies
  and templates

Generated-by: Claude Code (Opus 4.7)

* fix(security/pr4): broken relative links to old vulnogram path

The earlier rename sed (ca47278) matched "tools/vulnogram" verbatim,
but three files had link targets in the relative form "../vulnogram/"
(visible text already said "tools/cve-tool-vulnogram/" — only the URL
target was stale):

- tools/cve-org/tool.md         -> 1 link
- tools/cve-tool/README.md      -> 2 links (incl. an #record-urls anchor)
- tools/forwarder-relay/README.md -> 3 links to bot-credits-policy.md

Update each "../vulnogram/..." -> "../cve-tool-vulnogram/..." and
sweep the rest of the tree for stragglers (none found).

Generated-by: Claude Code (Opus 4.7)
potiuk added a commit that referenced this pull request May 30, 2026
Fifth and final PR of the security genericization series.

Lifts the remaining 4 docs in docs/security/ to read config knobs
from projects/_template/project.md and the contract docs from
PR1-PR4 (cve_authority.*, governance.*, security_inbox.*,
forwarders.*, archive_system.*, scope_detection.*). Plus a final
scrub of 4 skills for leftover ASF/Vulnogram literals.

Byte-equivalent for the airflow-s adopter: every ASF/Airflow/
Vulnogram-specific value either resolves through a config knob
whose ASF default matches today's behaviour, OR stays as one
named-example aside in generic prose.

Per-target lifts:

- docs/security/threat-model.md (+107/-77) — Purpose/Scope/
  Assumptions reframed from "ASF"/"PMC" to governance-knob
  terms. STRIDE matrix rows A.6/A.7/C.1-C.4/E.1-E.2 lifted:
  Vulnogram -> <cve-tool>; security@apache.org -> <security-list>;
  DRAFT/REVIEW/READY/PUBLIC -> cve_authority.states sequence
  (allocated -> review-ready -> publish-ready -> public).
  Mitigations M.10/M.16/M.18/M.19/M.27 + residual risks
  #3/#8/#10/#11 + re-audit cadence ownership generalised.

- docs/security/forwarder-routing-policy.md (+42/-27) — references
  the optional security-issue-import-via-forwarder sub-skill from
  PR3 (#387) and the tools/forwarder-relay/README.md contract.
  Replaces "ASF-security relay" / "security@apache.org" with
  forwarders.enabled / <security-list> / foundation_security_address.
  ASF-Airflow shown as a named-example aside per concept.

- docs/security/how-to-fix-a-security-issue.md (+20/-8) —
  "governance-authorised member of the adopting project (per
  governance.cve_allocation_gate)" replaces "PMC member of
  apache/airflow"; <cve-tool> + cve_authority.* replaces Vulnogram-
  specific URLs and state names; archive_system.advisory_publication_signal_url
  replaces the lists.apache.org users-list URL.

- docs/security/new-members-onboarding.md (+26/-13) — onboarding-
  style register preserved. "PMC members and committers" reframed
  as "governance body that satisfies governance.cve_allocation_gate";
  per-user-config "PMC status" steps reference the governance knob;
  Vulnogram steps reference <cve-tool> via cve_authority.record_url_template.

- Final scrub of 4 skills (+17/-15 net): security-issue-import,
  security-issue-import-via-forwarder, security-issue-invalidate,
  security-issue-fix — leftover literal references caught and
  lifted to roster.bare_name_handles / governance.escalation_contact /
  forwarders.<adapter>.contact_handle.

Aggregate: 8 files, +240/-156 lines.

That closes the series. Five PRs (#381, #386, #387, #388, this)
transitioned the security skill family from Airflow/ASF-coupled to a
generic framework with ASF as the default-configured option. The
airflow-s adopter, with the ASF defaults baked into project.md, sees
byte-equivalent behaviour throughout. Non-ASF adopters override
specific dimensions (CVE authority, mail provider, archive system,
governance gate, scope axis) by changing only their <project-config>/
files.

Generated-by: Claude Code (Opus 4.7)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant