how to write a security advisory for your own library
A skill for writing and publishing a security advisory for your own library: drafting privately, defining affected and patched versions, describing impact and workarounds, and coordinating the release. Use when your project has a confirmed vulnerability to disclose. Triggers: 'write security advisory', 'publish GHSA', 'disclose vulnerability in my package'. Not for: reporting someone else's vuln, regular release notes.
how to write a security advisory for your own library
TL;DR
Draft the advisory privately while you build the fix, nail down the exact affected version range and the patched versions, then publish the advisory at the same moment the fixed release goes out. The advisory is a service to your users: tell them what is wrong, who is affected, and exactly how to fix it.
how to write a security advisory for your own libraryUse this when
- You confirmed a vulnerability in a library or tool you maintain
- A reporter privately disclosed a vuln and the fix is ready or nearly ready
- You need to publish a GitHub Security Advisory or equivalent notice
- You are coordinating a fix across multiple maintained branches
Not for this skill when
- The vuln is in someone else's project (report it to them privately first)
- It is a regular bug with no security impact (release notes cover it)
- You are still unsure it is a real vulnerability (confirm before drafting)
Steps
1. Draft the advisory privately
Use GitHub's draft security advisory feature or a private document. Drafting in public, even accidentally, starts the clock before the fix exists.
Expected: a private draft with sections for summary, affected versions, patched versions, impact, and workarounds. Nothing public yet.
2. Pin down affected and patched versions precisely
Test the reproduction against your release tags to find the real range. Overstating the range causes pointless upgrades; understating it leaves users exposed.
Expected: a version range like "affected: >= 2.1.0, < 2.4.3; patched: 2.4.3" that you verified, not guessed. Check every maintained branch separately; backport branches often need their own patched release.
3. Describe impact honestly and concretely
Say what an attacker can actually do: read data, execute code, escalate privilege, and under what conditions. Skip the scary adjectives; concrete impact statements build trust.
Expected: two or three sentences a user can map to their own deployment. If exploitation requires an unusual configuration, say so; it helps users triage.
4. Document workarounds for users who cannot upgrade
Not everyone can upgrade today. Give them a mitigation: a config change, a firewall rule, disabling a feature.
Expected: at least one tested workaround with steps. An untested workaround is worse than none; verify it blocks the reproduction.
5. Publish advisory and release together
Publish the advisory, push the fixed releases, and request a CVE ID in the same motion. Then announce through your normal channels: release notes, mailing list, package manager metadata.
Expected: the advisory is live, the fixed version is installable, and users have one link with everything. Staggering the advisory before the release is available just advertises the hole.
Variant: crediting the reporter
Credit reporters by name or handle with their permission, in the advisory. Good credit brings good future reports; it costs you one line.
Variant: multiple ecosystems or registries
Publish the advisory in each registry's format if you ship to several (npm, PyPI, crates, and so on). One canonical text, adapted per registry, keeps the message consistent.
Why this happens
Users cannot protect themselves from a vulnerability they do not know about, and vague advisories get ignored because nobody can tell if they apply. A precise, well-timed advisory converts "maybe affected" into "upgrade to this version today," which is the whole point.
Edge cases and pitfalls
- Publishing before the patch is available on every registry; mirror lag is real, verify installability.
- Forgetting a maintained LTS branch; check every branch you still support.
- Severity inflation: an honest medium beats a hyped critical that erodes trust.
- Embargo leaks from CI or public branches; keep fix commits private until release.
- No workaround exists: say so plainly and make the upgrade path as easy as possible.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_Stbt2MWJ019JeHKpEKD4NA
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.