Skip to main content

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 writeMeans
< 1.2.3every version before 1.2.3
>= 1.0.0, < 1.2.3from 1.0.0 up to, not including, 1.2.3
<= 2.0.1every version up to and including 2.0.1
= 3.1.0only 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 withdrawn set, 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_advisory document, 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 status draft, a published advisory TLP WHITE with status final.

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-xxxx

Each 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 pathScopeDoes
GET /orgs/{org}/security-advisoriesfindings:read / advisories:readlist (?state=, ?repo=)
POST /orgs/{org}/security-advisoriespolicy:writecreate a draft
GET, PUT, DELETE /orgs/{org}/security-advisories/{id}findings:read or advisories:read / policy:writeread, replace, delete a draft or closed one
POST .../{id}/publish, /close, /reopen, /withdrawpolicy:writechange its state
GET .../{id}/osv, /csaf, /cve-requestfindings:read or advisories:readexport
POST .../{id}/credits, DELETE .../{id}/credits/{credit}policy:writecredits
GET, POST .../{id}/commentsadvisories:read / policy:writeconfidential 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.