Naar de hoofdinhoud

Exportschema

Deze pagina is het schema van de volledige data-export: wat de bundel bevat en de vorm van elk record. Hoe je een export start en verifieert en welke limieten gelden, staat op de pagina over de data-export. De verwerkersovereenkomst verwijst in §9 naar deze pagina.

Indeling van de bundel

export-<your-org-slug>-<YYYY-MM-DDTHH-MM-SS-mmmZ>.tar.gz
├── VERIFY.md                          — step-by-step verification recipe
├── manifest.json                      — every file below, SHA-256 and size
├── manifest.json.intoto.jsonl         — DSSE-signed in-toto Statement over manifest.json
├── audit.ndjson                       — your org's audit events, last 90 days
├── access-log.ndjson                  — your registry access log (package and container downloads, uploads and deletes; CI cache hits are in pulled-versions.ndjson)
├── bundles/
│   ├── <repo>.bundle                  — git bundle: full history, every ref
│   └── <repo>.empty                   — instead of a bundle, for a repository with no commits (zero bytes)
├── findings/                          — scan findings, see "Scan findings, policy, attestations and SBOMs" below
├── policy/                            — package policy, verdicts, exceptions and scanner settings
├── attestations/                      — build provenance and release attestations, with their signatures
├── sboms/                             — repository and container-image SBOMs, with an index
└── metadata/
    ├── packages.ndjson                — package inventory, see "Packages" below
    ├── packages-files.ndjson          — every file of every package version
    ├── packages-container-tags.ndjson — container image tag → manifest digest
    ├── components.ndjson              — third-party component inventory, see "Component inventory" below
    ├── deployments.ndjson             — deployments your CI/CD reported, see "Deployments" below
    ├── pulled-versions.ndjson         — package versions pulled per day and consumer, see "Pulled versions" below
    └── <repo>/
        ├── repo.ndjson                — repository settings, description, topics
        ├── issues.ndjson              — every issue, open and closed
        ├── pulls.ndjson               — every pull request, open and closed
        ├── comments.ndjson            — issue and pull-request comments
        ├── labels.ndjson
        ├── milestones.ndjson          — open and closed
        ├── releases.ndjson            — release metadata; see "Release assets" below
        └── lfs-manifest.ndjson        — LFS object inventory, see "LFS content" below

In namen van repository’s worden tekens buiten a-z 0-9 . _ - vervangen door _.

Gebruikte standaarden:

  • Repository’s: het eigen git bundle-formaat van Git. git clone <bundle> bouwt de repository volledig opnieuw op, inclusief geschiedenis, branches en tags. Een repository zonder commits heeft niets om te bundelen en verschijnt in plaats daarvan als een leeg bestand <repo>.empty.
  • Issues, pull requests en de andere bestanden in metadata/: NDJSON, één JSON-object per regel, in dezelfde vorm die de Forgejo-API voor elk object teruggeeft.
  • Auditlog: NDJSON, één gebeurtenis per regel (id, action, actor, fields_json, created_at). Dezelfde vorm als de interne auditstroom van fremforge.
  • Registertoegangslog: NDJSON, oudste eerst, één gebeurtenis per regel in de vorm die GET /orgs/{slug}/access-log teruggeeft, met IP-adressen van clients en logins zoals vastgelegd. Het omvat alles wat binnen de bewaartermijn van je auditlog nog bewaard wordt. Zie Registertoegangslog.
  • Integriteit: manifest.json noemt elk bestand met zijn SHA-256-hash en grootte. Het manifest is DSSE-ondertekend met de Ed25519-buildersleutel van fremforge. De handtekening staat in manifest.json.intoto.jsonl en is te verifiëren tegen de publieke trust root op https://www.frem.sh/.well-known/slsa-trust-root.json met openssl, jq, python3 en curl, zonder tooling van fremforge. Het volledige recept staat in VERIFY.md in de bundel en in §“Het ondertekende manifest verifiëren” op de pagina over de data-export. Dit is dezelfde trust root die voor SLSA-buildattestaties wordt gepubliceerd: één sleutel, twee predicaattypen, geen afhankelijkheid van Sigstore.

Geen eigen formaten. Elk artefact in de bundel is te lezen met standaard opensourcetooling. Een CLI van fremforge is niet nodig.

Pakketten

metadata/packages.ndjson is de inventaris van het pakketregister van je organisatie: één regel per pakketversie, met het type (container, npm, maven, pypi, generic, …), de name en de version, zoals de pakket-API van Forgejo ze opsomt.

metadata/packages-files.ndjson noemt elk bestand van elk van die versies, één regel per bestand:

VeldBetekenis
owner, type, name, versionde pakketversie waartoe het bestand behoort
file_id, file_namede identifier en naam van het bestand in het register
sizegrootte in bytes
sha256SHA-256 van het bestand; ook sha512 als het register die vastlegt
download_pathpad op frem.sh dat precies dit bestand downloadt met een API-token (Authorization: token …); het register kan antwoorden met een redirect naar objectopslag. null voor registertypen waarvan de bestands-URL niet alleen uit de inventaris is af te leiden (bijvoorbeeld Maven); gebruik daarvoor web_path
web_pathde downloadlink van het bestand op zijn pakketpagina, voor een ingelogde browser

Bij containerimages is een pakketversie een tag (of, voor een manifest zonder tag, zoals één platform van een multi-arch-image, de digest zelf). metadata/packages-container-tags.ndjson koppelt elke tag aan zijn manifestdigest (owner, name, tag, manifest_digest), wat docker pull <image>@sha256:… en andere OCI-tools gebruiken. De lagen en de config van het image staan in packages-files.ndjson als bestanden die naar hun digest zijn genoemd, met download_path naar de endpoints /v2/…/blobs/… en /v2/…/manifests/… van het register.

Controleer een gedownload bestand tegen de inventaris:

row=$(jq -c 'select(.name=="@acme/lib" and .version=="1.2.0")' metadata/packages-files.ndjson)
curl -sSL -H "Authorization: token $TOKEN" -o pkg.bin "https://frem.sh$(jq -r .download_path <<<"$row")"
echo "$(jq -r .sha256 <<<"$row")  pkg.bin" | sha256sum -c -

De inventaris zit altijd in de bundel. De pakketbestanden zelf komen alleen op verzoek, als apart archief: zie §“Pakketinhoud”.

Componentinventaris

metadata/components.ndjson is de inventaris van componenten van derden in je organisatie: één regel per component en plek waar het wordt of werd gebruikt, dezelfde rijen die GET /orgs/{slug}/components/usages teruggeeft. Beëindigd gebruik wordt 180 dagen bewaard en zit erbij, zodat de geschiedenis met je meegaat.

VeldBetekenis
purl, ecosystem, name, versionhet component, als package URL en de onderdelen daarvan
licence, licence_sourcede licentie-expressie en waar die vandaan is gelezen
subject_kind, subject_name, subject_refwaar het wordt gebruikt: de repository, het pakket of het image, en de ref of digest
image_tagsbij een image de tags die ernaar wijzen; anders leeg
source_repode repository die het heeft gebouwd, voor zover bekend
is_directtrue voor een directe afhankelijkheid, false voor een transitieve, null als de SBOM het niet vermeldt
environment, environment_sourcede omgevingsklasse (sandbox, development, test of production) en hoe die is ingesteld
is_current, first_seen_at, last_seen_at, removed_atof het gebruik actueel is, en wanneer het voor het eerst en het laatst is gezien en verwijderd

Deployments

metadata/deployments.ndjson bevat elke deployment die je CI/CD heeft gemeld met POST /orgs/{slug}/repos/{repo}/deployments, één regel per deployment, oudste eerst op identifier.

VeldBetekenis
idde identifier van de deployment
repository, environment, environment_classde repository (owner/name), de omgevingsnaam die je opgaf, en de klasse daarvan (sandbox, development, test, staging of production)
ref, sha, task, descriptionde uitgerolde ref en commit, de taak (deploy, tenzij je een andere opgaf) en je beschrijving
image_digests, packagesde imagedigests en package-URL’s die de deployment noemt
statede laatste status: pending, queued, in_progress, success, failure, error of inactive
creator_kind, creator, run_idwie hem meldde (job, robot, user of token), de naam daarvan, en bij een job de Actions-run
created_at, updated_atwanneer hij is gemeld en het laatst is gewijzigd
statuseselke status, nieuwste eerst: state, description, log_url, environment_url, creator_kind, creator, created_at

Opgehaalde versies

metadata/pulled-versions.ndjson is de pull-telling: één regel per UTC-dag, pakketversie en afnemer, voor de dagen die binnen de bewaartermijn van je toegangslog nog bewaard worden. Sinds 2026-10-13 is dit het enige record van downloads die een CI-job via de dependency-proxy deed en die uit diens cache werden geleverd; die staan niet in access-log.ndjson. Dit zijn de rijen die GET /orgs/{slug}/components/pulled optelt; de advisories die dat endpoint eraan koppelt, staan niet in het bestand.

VeldBetekenis
dayde UTC-dag, YYYY-MM-DD
originregistry voor je eigen pakketten, proxy voor de dependency-proxy
ecosystem, name, versionhet pakkettype (npm, pypi, maven, nuget, go, container, …), de naam en de versie
consumerwie het ophaalde: kind (job, robot, bot, user of anonymous), name (de repository van de job, de naam van de robot of de login; null bij anoniem), id, bij een robot de login, en bij een job run_ids, de Actions-runs die het die dag ophaalden (nieuwste eerst, hooguit 100; leeg vóór 2026-10-13)
pullsgeslaagde downloads die dag
first_seen_at, last_seen_atde eerste en de laatste daarvan, in UTC met microseconden

Scanbevindingen, beleid, attestaties en SBOM’s

Elke export bevat de beveiligingsgegevens die fremforge over je organisatie bewaart, als NDJSON (één JSON-object per regel), en net als elk ander bestand gedekt door het ondertekende manifest. Elke regel is het volledige record dat fremforge opslaat, behalve de interne tenant-id en opslagpaden; weggezette bevindingen zitten erbij, met wie ze heeft weggezet, waarom en tot wanneer. Rijen die over een registerpakket gaan, hebben een object package (type, owner, name, version, file, blob_sha256).

findings/
├── sast.ndjson                        — static analysis (rule, file, line, severity)
├── dependencies.ndjson                — dependency vulnerabilities, with CVSS and EPSS where known
├── dependency-dismissals.ndjson       — repository-wide dependency dismissals
├── licences.ndjson                    — licence findings, each with its licence policy decision
├── container-images.ndjson            — container image vulnerabilities
├── container-image-dismissals.ndjson
├── secrets.ndjson                     — rule, file, line and fingerprint; the secret value is never stored
├── malware-uploads.ndjson             — malware found in uploads
├── malware-dependencies.ndjson        — known-malicious dependencies
├── malware-container-layers.ndjson    — per image manifest, each layer's malware verdict
├── packages.ndjson                    — vulnerabilities found in your registry packages
├── package-licences.ndjson            — declared and detected licences of your registry packages
└── sha-pinning.ndjson                 — workflow actions not pinned to a commit
policy/
├── package-policy.ndjson              — your package policy (mode, thresholds, licence lists, minimum age)
├── package-policy-rules.ndjson        — allow and deny rules
├── package-policy-approvers.ndjson
├── package-policy-verdicts.ndjson     — the current verdict for each package file, with reasons
├── package-gate-decisions.ndjson      — downloads blocked, or that would have been blocked in shadow mode
├── exceptions.ndjson                  — policy exceptions, who requested and who approved them
├── malware-overrides.ndjson
├── package-access-packages.ndjson     — per-package access: each configured package (mode, inheritance)
├── package-access-grants.ndjson       — per-package access grants (teams, Actions repositories)
├── package-protection-rules.ndjson    — protected package names
├── scan-overrides.ndjson              — per-repository scanner mode overrides
└── settings/                          — each scanner's org settings (sast, dependencies, licences, container-images, secrets),
                                         and licence-repo-overrides.ndjson: per-repository licence policy overrides
                                         and package-access.ndjson: the per-package access default
                                         and retention.ndjson: one line per evidence retention class, with what you set,
                                         what applies, the default, the bounds and whether a legal hold is active
attestations/
├── build-provenance.ndjson            — one line per build provenance attestation
├── build-provenance/<id>.intoto.jsonl — its DSSE envelope (the Ed25519 signature)
├── build-provenance/<id>.sigstore.json — its keyless Sigstore bundle, where one was made
├── releases.ndjson                    — release attestations: subjects, the frozen release manifest, status, and envelope_path
├── sbom-ingest.ndjson                 — attestations uploaded together with an SBOM
└── sbom-ingest/<sbom id>.intoto.jsonl
sboms/
├── index.ndjson                       — one line per SBOM, see below
├── repos/<id>.cdx.json                — a repository SBOM, CycloneDX (<id>.spdx.json for SPDX)
└── images/<id>.cdx.json               — a container image SBOM
  • Handtekeningen reizen mee met de attestaties. Elke envelope is te verifiëren tegen dezelfde trust root als de bundel, met het script uit §“Het ondertekende manifest verifiëren”, gericht op de envelope in plaats van op manifest.json.intoto.jsonl (sla de controles op manifestSha256 en predicateType over; die gelden alleen voor exportbundels). De Sigstore-bundels zijn ondertekend met de eigen Fulcio en timestampautoriteit van fremforge, niet met de publieke Sigstore; zie SLSA-provenance.
  • Een ontbrekende handtekening wordt getoond, niet verborgen. Een regel met "envelope_status": "missing" is een attestatie waarvan het handtekeningobject niet meer in de opslag stond toen de export draaide. Elke andere opslagfout laat de export mislukken.
  • Containerlagen. Het malwareoordeel over een laag hoort bij de inhoud ervan, dus een laag die met een ander image wordt gedeeld, staat met zijn oordeel onder elk van je manifesten die hem gebruiken. Images die via de dependency-proxy zijn opgehaald, staan er alleen in zolang je organisatie ClamAV-scanning van opgehaalde proxybestanden aan heeft staan; staat die uit (de standaard), dan worden ze niet met ClamAV gescand en hebben ze geen oordelen per laag.
  • Release-attestaties bestaan voor repository’s met onveranderlijke releases. Een release waarvan de status niet signed is, heeft geen envelope (envelope_path is null).
  • SBOM’s. sboms/ bevat elke SBOM die fremforge voor je repository’s bewaart (builds van releases en van de standaardbranch, geüpload of gemaakt door de centrale scan) en voor je containerimages (de inventaris per manifest van het register), als het document zelf. Een build van een repository heeft meestal zowel een CycloneDX- als een SPDX-document; zie SBOM’s. Elke regel van sboms/index.ndjson is het opgeslagen SBOM-record (id, subject_kind repo of image, format, repo_full_name of artifact_name, release_tag, image_tags, manifest_digest, created_at, sha256_digest en de rest van het opgeslagen record, zonder opslagpaden) plus drie velden over het bestand in deze bundel: document_path, document_sha256 en document_status. Die laatste is ok als het document overeenkomt met de SHA-256 die bij het opslaan is vastgelegd, digest_mismatch als dat niet zo is (de bytes worden toch geëxporteerd, en beide digests staan op de regel), en missing als het document niet meer in de opslag stond. Elke andere opslagfout laat de export mislukken.
  • Pakket-SBOM’s staan niet in sboms/. De SBOM van elk pakketbestand in het register reist mee naast het bestand in het optionele archief met pakketinhoud.