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" belowIn 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-logteruggeeft, 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.jsonnoemt elk bestand met zijn SHA-256-hash en grootte. Het manifest is DSSE-ondertekend met de Ed25519-buildersleutel van fremforge. De handtekening staat inmanifest.json.intoto.jsonlen is te verifiëren tegen de publieke trust root ophttps://www.frem.sh/.well-known/slsa-trust-root.jsonmetopenssl,jq,python3encurl, zonder tooling van fremforge. Het volledige recept staat inVERIFY.mdin 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:
| Veld | Betekenis |
|---|---|
owner, type, name, version | de pakketversie waartoe het bestand behoort |
file_id, file_name | de identifier en naam van het bestand in het register |
size | grootte in bytes |
sha256 | SHA-256 van het bestand; ook sha512 als het register die vastlegt |
download_path | pad 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_path | de 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.
| Veld | Betekenis |
|---|---|
purl, ecosystem, name, version | het component, als package URL en de onderdelen daarvan |
licence, licence_source | de licentie-expressie en waar die vandaan is gelezen |
subject_kind, subject_name, subject_ref | waar het wordt gebruikt: de repository, het pakket of het image, en de ref of digest |
image_tags | bij een image de tags die ernaar wijzen; anders leeg |
source_repo | de repository die het heeft gebouwd, voor zover bekend |
is_direct | true voor een directe afhankelijkheid, false voor een transitieve, null als de SBOM het niet vermeldt |
environment, environment_source | de omgevingsklasse (sandbox, development, test of production) en hoe die is ingesteld |
is_current, first_seen_at, last_seen_at, removed_at | of 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.
| Veld | Betekenis |
|---|---|
id | de identifier van de deployment |
repository, environment, environment_class | de repository (owner/name), de omgevingsnaam die je opgaf, en de klasse daarvan (sandbox, development, test, staging of production) |
ref, sha, task, description | de uitgerolde ref en commit, de taak (deploy, tenzij je een andere opgaf) en je beschrijving |
image_digests, packages | de imagedigests en package-URL’s die de deployment noemt |
state | de laatste status: pending, queued, in_progress, success, failure, error of inactive |
creator_kind, creator, run_id | wie hem meldde (job, robot, user of token), de naam daarvan, en bij een job de Actions-run |
created_at, updated_at | wanneer hij is gemeld en het laatst is gewijzigd |
statuses | elke 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.
| Veld | Betekenis |
|---|---|
day | de UTC-dag, YYYY-MM-DD |
origin | registry voor je eigen pakketten, proxy voor de dependency-proxy |
ecosystem, name, version | het pakkettype (npm, pypi, maven, nuget, go, container, …), de naam en de versie |
consumer | wie 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) |
pulls | geslaagde downloads die dag |
first_seen_at, last_seen_at | de 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 opmanifestSha256enpredicateTypeover; 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
statusnietsignedis, heeft geen envelope (envelope_pathisnull). - 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 vansboms/index.ndjsonis het opgeslagen SBOM-record (id,subject_kindrepoofimage,format,repo_full_nameofartifact_name,release_tag,image_tags,manifest_digest,created_at,sha256_digesten de rest van het opgeslagen record, zonder opslagpaden) plus drie velden over het bestand in deze bundel:document_path,document_sha256endocument_status. Die laatste isokals het document overeenkomt met de SHA-256 die bij het opslaan is vastgelegd,digest_mismatchals dat niet zo is (de bytes worden toch geëxporteerd, en beide digests staan op de regel), enmissingals 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.