Security advisories for your repositories
When someone finds a weakness in software you maintain, you fix it first and tell people second. A security advisory is how you tell them: a short, structured statement of what is affected, how badly, and which version fixes it. Scanners read advisories to warn everyone who depends on your package.
fremforge keeps an organisation’s advisories under Security › Reports ›
Advisories, and through the API at /_app/api/v1/orgs/{org}/security-advisories.
Draft in private
New advisory opens a draft. A draft names:
- the repository it is about;
- a one-line title and a description: what the weakness is, who is affected, the impact, and how to fix or work around it;
- the affected packages, each with its ecosystem, package name, vulnerable versions and the first patched version;
- the severity, as a CVSS vector or a level (critical, high, medium, low);
- the weaknesses (CWE ids), an optional CVE id and references.
A draft is visible only to:
- the organisation’s owners. Its auditors see only that it exists, its repository, state and dates, never its content;
- the administrators of the repository it is about (see Repository administrators);
- the people they invite to it (see Collaborators).
Its title, description, references and comments are stored encrypted. fremforge’s own operational tooling and AI agents see neither the text nor who wrote it.
The people who can see a draft can discuss it in confidential comments. They stay private, also after the advisory is published.
Vulnerable versions
Write the vulnerable versions as one or two constraints, the same form GitHub uses:
| You write | Means |
|---|---|
< 1.2.3 | every version before 1.2.3 |
>= 1.0.0, < 1.2.3 | from 1.0.0 up to, not including, 1.2.3 |
<= 2.0.1 | every version up to and including 2.0.1 |
= 3.1.0 | only 3.1.0 |
> is refused: the OSV format has no exclusive lower bound, so use >=.
With < X the first patched version is X. Leave Patched version empty,
or use <= for the last affected version.
Ecosystems: npm, PyPI, Maven (groupId:artifactId), Go (the module path),
crates.io, RubyGems, NuGet, Packagist, Pub, Hex, GitHub Actions
(owner/repository), SwiftURL and CRAN.
Severity
A CVSS 3.1 base vector sets the severity from its base score, computed by fremforge. A CVSS 4.0 base vector is checked and kept as given. Choose the severity yourself then: the CVSS 4.0 score is not computed.
Publish
Publish advisory needs a severity and at least one affected package.
- For a public repository (not private, in an organisation whose visibility
is public), the advisory becomes public at once: a page at
https://frem.sh/_app/advisories/<id>and an OSV record (see below). Whether the repository is public is checked again on every public read. If you make the repository private later, its advisories stop being served on the next read. - For a private repository, the advisory stays visible only within your organisation. It does not become public if you open the repository later; publish a new one.
Release the fix before you publish: the advisory tells everyone where the weakness is.
Developing the fix happens outside fremforge for now. An advisory holds text; fremforge has no temporary private fork for it. A private repository in your organisation would be readable by every team with access to all repositories, which by default includes Members and Viewers, so it is not offered. Develop the fix the way your project handles unpublished security fixes, and publish the advisory once the fixed version is released.
Every advisory has an id of the form FFSA-xxxx-xxxx-xxxx, fixed when the
draft is created.
Repository administrators
A repository’s administrators handle the advisories and private reports of
that repository without being owners of the organisation, the way GitHub
lets repository administrators do it. They find the reports sent to the
repositories they administer under Reports to repositories you administer
at /_app/security-reports, can accept
or reject them, and read and comment on those repositories’ drafts. Whether
someone administers a repository is asked of frem.sh on every request, so a
change of permissions applies at once. An organisation owner counts as an
administrator of every repository in the organisation.
Collaborators
Invite people to a draft or published advisory by their frem.sh login, for
example an outside researcher or a maintainer from another project. They need
not be members of your organisation. An invited person reads the advisory and
its confidential comments, and adds comments, from their own page at
/_app/security-reports. They cannot
change or publish it. Removing them ends their access at once. Up to 20 people
can be invited to one advisory.
Private vulnerability reporting
With private vulnerability reporting on, anyone signed in to frem.sh who can read a repository can report a weakness in it to you privately, including people outside your organisation. Without it, a finder has to guess an email address or open a public issue.
It is off until you turn it on. Owners set an organisation-wide default under Security › Reports › Advisories › Settings, and can turn it on or off for single repositories there; a repository setting overrides the default.
What a reporter sends
The report form is at
https://frem.sh/_app/security-reports/new?repo=<org>/<repository>. Link to it
from your repository’s SECURITY.md. A report has a title, a description,
the affected versions, how the weakness was found and an optional proof of
concept. It is stored encrypted, and only the organisation’s owners, the
repository’s administrators and the reporter see it. Its text is never in
an email or the audit log; the audit log names reports by id.
To keep the channel usable, fremforge limits reports:
- 3 per person to one repository, and 10 per person in all, within 24 hours;
- none from an account less than 24 hours old;
- 5 a minute from one IP address.
A request that would break a limit is refused and nothing is stored.
Deciding a report
The organisation’s owners get an email when a report arrives, and find it
under Security › Reports › Advisories › Private reports. The repository’s
administrators find it on their own page at
/_app/security-reports.
- Accept makes a draft advisory from the report, invites the reporter to it as a collaborator, and asks them to accept a reporter credit.
- Do not accept closes the report with a reason: not a vulnerability, duplicate, out of scope, spam or other.
Either way, the reporter is told by email. A reporter can withdraw a report until it is decided. A rejected report is deleted 2 years after it was rejected. Accepted reports and their advisories stay with your organisation.
Dependency scanning
A published advisory is matched against your organisation’s dependency
inventory every day and right after you publish it: a repository that depends
on an affected version gets a finding under Security › Findings ›
Dependencies, with the advisory’s FFSA id, like any other vulnerability.
Withdrawing the advisory removes the findings it raised.
For other organisations, an advisory is matched only when it is in fremforge’s platform feed. That needs, checked again every day:
- the repository is public; and
- your organisation provably owns every affected package: a package of
your organisation in the frem.sh package registry, or a Go
module under
frem.sh/<your organisation>/; or else fremforge has reviewed the advisory and approved it.
Ownership comes from frem.sh’s own records, never from the package name: an
npm scope or a module path that merely resembles your organisation’s name
does not count. If you lose the package or make the repository private, the
advisory leaves the platform feed at the next daily run. The platform feed is
served at /_app/api/v1/advisories?scope=platform, and fremforge folds it into
the OSV databases its scanners read.
Withdraw, close, delete
- A published advisory is withdrawn, never deleted. It stays in the
feed with
withdrawnset, so scanners learn that it no longer applies. - A draft you do not publish can be closed (and reopened) or deleted with its comments.
Credits
Credit the people who found, reported or fixed the weakness, by their frem.sh
login and an OSV credit type.
A credit is shown publicly and exported only once the credited person has
accepted it, on their own page at
/_app/security-reports. Crediting
yourself needs no acceptance.
Export: OSV and CSAF
Every advisory, drafts included, can be downloaded as:
- OSV 1.6: the format dependency scanners read (osv-scanner, Trivy, and fremforge’s own dependency scanning);
- CSAF 2.0: a
csaf_security_advisorydocument, the machine-readable advisory format that guidance under the EU Cyber Resilience Act and the BSI expect from manufacturers. A draft is TLP AMBER with statusdraft, a published advisory TLP WHITE with statusfinal.
Each download is recorded in the audit log
(security.advisory.exported), because a draft’s export describes a weakness
that is not fixed yet.
The public OSV feed
Published advisories of public repositories are served without authentication, oldest change first, at most 100 per page:
# The first page
curl -s 'https://frem.sh/_app/api/v1/advisories?limit=100'
# The next page: pass the `next` value of the previous answer as `since`
curl -s 'https://frem.sh/_app/api/v1/advisories?since=2026-10-25T00:00:00Z'
# One advisory
curl -s https://frem.sh/_app/api/v1/advisories/FFSA-xxxx-xxxx-xxxxEach record follows the OSV schema, with
the CVE id (if any) as an alias and database_specific.source set to
fremforge. Whether the repository is public is checked on every request, so
an advisory of a repository made private is not served on the next read. The
public reads are limited to 60 requests a minute per client address
(429 above that).
Requesting a CVE id
fremforge is not a CVE Numbering Authority and does not request CVE ids
for you. Under Request a CVE id, an advisory gives you its content as text
for MITRE’s CVE request form, or for the CNA that
covers your project if it has one. Send it yourself, then enter the CVE id you
receive in the advisory. The API has the same text at
/orgs/{org}/security-advisories/{id}/cve-request.
The EU Cyber Resilience Act
The CRA expects a manufacturer to handle vulnerabilities in its products: fix them, and publish information about fixed ones. Advisories with CSAF export support that. They do not make you compliant on their own, and fremforge does not report anything to ENISA or a national CSIRT for you. Reporting under CRA Article 14 stays with you.
Not available yet
- A temporary private fork to develop the fix in: not offered, see Publish.
API
| Method and path | Scope | Does |
|---|---|---|
GET /orgs/{org}/security-advisories | findings:read / advisories:read | list (?state=, ?repo=) |
POST /orgs/{org}/security-advisories | policy:write | create a draft |
GET, PUT, DELETE /orgs/{org}/security-advisories/{id} | findings:read or advisories:read / policy:write | read, replace, delete a draft or closed one |
POST .../{id}/publish, /close, /reopen, /withdraw | policy:write | change its state |
GET .../{id}/osv, /csaf, /cve-request | findings:read or advisories:read | export |
POST .../{id}/credits, DELETE .../{id}/credits/{credit} | policy:write | credits |
GET, POST .../{id}/comments | advisories:read / policy:write | confidential comments |
findings:read reads only published advisories of public repositories,
with accepted credits only. Drafts, closed advisories, advisories of private
repositories and every advisory’s comments need advisories:read, which
findings:read does not include and which tokens minted for CI jobs do not
hold by default. A credit names a frem.sh user: an unknown login is refused.
The full schemas are in the API reference.