Install
$ agentstack add skill-apache-magpie-security-issue-import Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Possible prompt-injection directive.
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
security-issue-import
This skill is the on-ramp of the security-issue handling process. It converts an inbound ` email thread into an ` tracking issue that follows the repo's issue template, then drafts the receipt-of-confirmation reply to the reporter.
It never sends email. It never creates a tracker for a candidate the user has explicitly rejected. It never assumes a report is valid — the validity / invalid / CVE-worthy decision still happens later in the discussion on the created tracker (Step 3 of [README.md](../../README.md)).
Golden rule — propose, then default to import. Every import this skill performs is a proposal that lists the candidate emails, the extracted fields, and the draft confirmation reply. The user's default disposition for any Report or forwarder-relayed candidate (the latter classified by the optional [security-issue-import-via-forwarder](../security-issue-import-via-forwarder/SKILL.md) sub-skill when forwarders.enabled is non-empty) is "import as a new tracker landing in Needs triage"; the user only has to type back when they want to deviate from that default — skip NN to reject a candidate upfront with no reply, or NN:reject-with-canned to reject upfront and draft a specific canned negative-assessment / out-of-scope reply. A bare all (or no reply at all to the proposal — the user typing "go", "proceed", "yes, all") means "import every non-rejected candidate as proposed". The skill must still surface each candidate one-by-one in the proposal so the user can scan and override if needed; what the skill must not do is sit on a report waiting for an explicit per-candidate green light. The bias is toward landing trackers — a wrongly-imported report is cheap to close at Step 5 / 6 of the handling process; a wrongly-skipped one gets buried in the inbox and the reporter is left without a disposition.
Golden rule — rejection means no tracker, ever. When the user rejects a candidate upfront — any of skip NN, NN:reject-with-canned , an explicit "reject 1", "mark 1 invalid", "don't import 1", or a cancel / none / "hold off" on the whole proposal — the skill must not create a tracker for that candidate. This holds even when the user also asks for a canned reply to be drafted: the draft is a courtesy to the reporter, the absence of a tracker is the disposition. There is no "create the tracker so the team can close it as invalid later" path; if the team has decided pre-triage that the report is invalid, the audit trail lives on the Gmail thread and on the canned-responses.md precedent, not in a tracker that exists only to be closed. A tracker is created only when the candidate is imported as a real Report (or a forwarder-relayed candidate classified by the [security-issue-import-via-forwarder](../security-issue-import-via-forwarder/SKILL.md) sub-skill) for triage.
Non-import candidate classes (automated-scanner, consolidated-multi-issue, media-request, spam, cross-thread-followup, cve-tool-bookkeeping) keep the original "propose first, apply only on explicit confirm" rule — those never default to a tracker.
Golden rule — confidentiality. The inbound thread on ` is private. The skill may paste the email body verbatim into the created tracking issue (that repo is also private). It must **never** paste the report content into a public surface — not into , not into a public GHSA, not into any comment on a public repo. The same confidentiality rule documented in the "Confidentiality of " section of [AGENTS.md`](../../AGENTS.md) applies in full.
Golden rule — every ` / ` reference is clickable in the surface it lands on. Whenever this skill emits a reference to a tracker issue, PR, or comment — the proposal shown to the user before import, the created tracker issue body (observed-state dump, sibling-tracker cross-links, prior-rejection cross-links, fix-already-public PR pointers), the receipt-of- confirmation draft email reply, the recap output — the reference must be one click away in whatever surface it lands on:
- On markdown surfaces (the created tracker issue body, the
draft email reply destined for the ` thread, any markdown-rendered cross-link list): use the markdown link form per [AGENTS.md` § Linking tracker issues and PRs](../../AGENTS.md#linking-tracker-issues-and-prs):
- **Sibling `
issue**:#NNN` - Public `` PR (e.g. fix-already-public match):
[#NNN](https://github.com//pull/NNN)
- Comment: link to the
#issuecomment-anchor.
- On terminal surfaces (the proposal shown to the user before
import, the recap output): wrap the visible short form (#NNN, #NNN) in OSC 8 hyperlink escape sequences (\e]8;;\e\\\e]8;;\e\\) so modern terminals (iTerm2, Kitty, GNOME Terminal, WezTerm, Windows Terminal, …) render the short text as clickable. Where OSC 8 is unsupported (CI logs, dumb terminals), fall back to printing the bare URL on the same line after the number.
Bare #NNN with no link wrapper of any kind is never acceptable. The created tracker issue is read by the security team who drill into the cross-links to assess; the draft email reply lands on ` where the reporter needs the references to be one click away. Both surfaces are private, but URLs themselves are public-safe per the [Confidentiality of `](../../AGENTS.md#confidentiality-of-the-tracker-repository) rule — what stays private is the contents the link points at.
Self-check before posting any draft email or creating any tracker issue: grep the body for bare #\d+ / #\d+ tokens that aren't already inside a markdown link or an OSC 8 wrapper, and convert any match.
Adopter overrides
Before running the default behaviour documented below, this skill consults [.apache-magpie-overrides/security-issue-import.md](../../docs/setup/agentic-overrides.md) in the adopter repo if it exists, and applies any agent-readable overrides it finds. See [docs/setup/agentic-overrides.md](../../docs/setup/agentic-overrides.md) for the contract — what overrides may contain, hard rules, the reconciliation flow on framework upgrade, upstreaming guidance.
Hard rule: agents NEVER modify the snapshot under /.apache-magpie/. Local modifications go in the override file. Framework changes go via PR to apache/magpie.
Snapshot drift
Also at the top of every run, this skill compares the gitignored .apache-magpie.local.lock (per-machine fetch) against the committed .apache-magpie.lock (the project pin). On mismatch the skill surfaces the gap and proposes [/magpie-setup upgrade](../setup/upgrade.md). The proposal is non-blocking — the user may defer if they want to run with the local snapshot for now. See [docs/setup/install-recipes.md § Subsequent runs and drift detection](../../docs/setup/install-recipes.md#subsequent-runs-and-drift-detection) for the full flow.
Drift severity:
- method or URL differ → ✗ full re-install needed.
- ref differs (project bumped tag, or
git-branch
local is behind upstream tip) → ⚠ sync needed.
- **
svn-zipSHA-512 mismatches the committed
anchor** → ✗ security-flagged; investigate before upgrading.
Prerequisites
Before running, the skill needs:
- At least one configured mail-source backend per
[/project.md → Mail sources](../..//project.md#mail-sources). The skill treats every backend the same way — through the abstract operations defined in [tools/mail-source/contract.md](../../tools/mail-source/contract.md) (list_recent_threads, read_thread, list_drafts, list_sent_since, create_draft, thread_url). Reference adapters: [gmail](../../tools/gmail/tool.md) (full read+write), [ponymail](../../tools/ponymail/tool.md) (read-only ASF archive), [imap](../../tools/mail-source/imap/README.md) (stub), [mbox](../../tools/mail-source/mbox/README.md) (read-only offline archive — stub). To discover new reports the configured backends must collectively cover list_recent_threads + read_thread; to draft the receipt-of-confirmation reply in Step 7 they must additionally cover create_draft. If no available backend covers create_draft, Step 7 surfaces a one-line "no draft backend available" note and the user composes the reply by hand.
ghCLI authenticated (gh auth statusreturns OK) with
collaborator access to `. The skill calls gh issue create and gh search issues` directly.
See [Prerequisites for running the agent skills](../../docs/prerequisites.md#prerequisites-for-running-the-agent-skills) in docs/prerequisites.md for the overall setup.
Step 0 — Pre-flight check
Before touching any candidate thread, verify:
- **Mail-source backends from `/project.md →
Mail sources are available.** For each declared backend, run the backend's trivial health probe (per its adapter doc — Gmail: mcp__claudeaiGmail__searchthreads with pageSize: 1; Ponymail: mcp_ponymail__auth_status(); IMAP: a CAPABILITY against the configured host; mbox: a stat` on the archive path) and record the result in the skill's observed-state bag. Apply the [contract's resolution rule](../../tools/mail-source/contract.md#resolution-rule--which-backend-runs-an-operation) to figure out which backend serves which op for this run.
mandatory: yesbackend unavailable → **stop
immediately**. Surface "mandatory mail-source backend ` unavailable: `; run aborted". The user fixes the auth / connection and re-invokes.
mandatory: nobackend unavailable → continue with the
remaining backends. If the resolution then leaves an operation with no provider (e.g. no available backend supports create_draft), the skill records "no `` backend available" in the observed-state bag and the relevant downstream step omits that proposal with a clear hand-back to the user.
- Every declared backend healthy → proceed; the
observed-state bag records one provider per op so every dispatch later is unambiguous.
ghis authenticated and has access. Run
gh api repos/ --jq .name; if it errors (401, 403, 404), stop and tell the user to log in with gh auth login or get added to ``.
- (Reference-adopter guidance.) The reference adopter
lists gmail as primary mandatory: yes and — per the ASF default — ponymail as mandatory: yes too (fallback role for drafts, since PonyMail is read-only). So for the reference flow both backends are pre-flight prerequisites: a Gmail-MCP failure stops the run (drafts have no home), and a PonyMail-MCP miss — not registered, or registered but unauthenticated for the private ` archive — stops it too, per item 1's mandatory: yes rule. Gmail handles reads of just-arrived inbound mail and all draft creation; PonyMail handles archive lookups (and is the primary read path when authenticated). Adopters whose Mail sources table sets ponymail to mandatory: no` get the old degrade-quietly behaviour; the step-by-step references to "Gmail" below should be read as "the backend the resolution rule picked for the relevant op".
- Privacy-LLM contract. This skill reads ``
bodies that may contain third-party PII the reporter discloses about other people. Run the gate-check first — non-zero exit is a hard stop:
``bash uv run --project /tools/privacy-llm/checker \ privacy-llm-check ``
The checker auto-locates /privacy-llm.md (template at [projects/_template/privacy-llm.md](../../projects/_template/privacy-llm.md)) and verifies every entry in Currently configured LLM stack is approved per [tools/privacy-llm/models.md](../../tools/privacy-llm/models.md#the-pre-flight-check). In addition, verify:
~/.config/apache-magpie/is writable (the redactor's
mapping file lives there);
- the configured collaborator source is reachable via
gh api (default: ` from project.md`);
- the redaction-tuning knobs (collaborator exemption,
enabled field types) are loaded into the skill's observed-state bag — they apply at filter-time below.
Each subsequent body fetch in Steps 4 / 7 / 7g (template- field extraction, draft assembly, recap) follows the redact-after-fetch protocol in [tools/privacy-llm/wiring.md](../../tools/privacy-llm/wiring.md#redact-after-fetch-protocol); the receipt-of-confirmation draft assembly follows the [reveal-before-send protocol](../../tools/privacy-llm/wiring.md#reveal-before-send-protocol) when (and only when) the draft references a third-party identifier.
- Disclosure governance from
/security-intake-config.md.
If the file exists, read the disclosure_governance block and load these two keys into the observed-state bag for use in Step 7:
reporter_acknowledgement_model—manual|auto|none. Controls
whether and how the receipt-of-confirmation reply is drafted (Step 7.4).
window_days— integer; the CVD window in calendar days, used as the
disclosure deadline hint when composing the acknowledgement draft.
If the file does not exist or the disclosure_governance block is absent, silently default to reporter_acknowledgement_model: manual and window_days: 90. A missing file is not a stop condition — adopters who have not yet created this config receive the same ASF defaults the skill has always applied.
If a mandatory: yes mail-source backend or the gh check fails, do not proceed — the skill would fail mid-flow otherwise, leaving half-built state (a draft on the wrong thread, or a tracker with no receipt reply). Fail fast instead. mandatory: no backends degrade quietly per the contract's resolution rule. A privacy-llm pre-flight failure is also a hard stop — the redactor's mapping store and the collaborator-source lookup are both load-bearing for every subsequent body read.
Inputs
Before running, resolve the user's selector into a concrete set of candidate Gmail threads:
| Selector | Resolves to | |---|---| | import new (default) | every security@ thread received in the last 14 days that has not yet been imported as an issue and has not already been answered-and-closed on-thread | | import since:YYYY-MM-DD | every security@ thread received since the given date that is not yet imported | | import thread: | the single Gmail thread with that threadId — useful for re-importing after a manual discard, or for picking up a single message the automatic scan missed | | import last 30d / import all / import last Nd (explicit request only) | a wider sweep — use when the skill has not been run in a while or the user is doing a backlog catch-up. The all alias spans disclosure_governance.window_days days (default 90) from /security-intake-config.md. |
If the user supplies no selector, default to import new (14-day window).
Why the default is 14 days. Most reports that land on security@ fall into one of three steady-state buckets: (a) imported as a tracker within days of arrival, (b) answered on-thread with a canned negative response that the reporter accepts silently, or (c) obvious spam the triager ignores. None of those need a second look past 14 days. Widening the default window past two weeks would keep re-surfacing the same already-handled threads every sync run, which is noise. The user can always pass import last 30d or import all explicitly when a deeper sweep is genuinely warranted (e.g. after a long quiet period, or during a backlog audit).
Step 1 — List candidate threads from Gmail
Search `` for inbound reports, excluding the tooling / GitHub-notification / mailing-list chatter that isn't a report:
Use the canonical candidate-l
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: apache
- Source: apache/magpie
- License: Apache-2.0
- Homepage: https://magpie.apache.org/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.