Schéma de l’export
Cette page décrit le schéma de l’export complet des données : ce que contient le bundle et la forme de chaque enregistrement. La manière de lancer un export, de le vérifier et les limites qui s’appliquent sont décrites sur la page de l’export de données. Le §9 de l’accord de traitement des données renvoie à cette page.
Structure du bundle
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" belowLes noms de dépôts contenant des caractères en dehors de a-z 0-9 . _ - apparaissent avec ces caractères remplacés par _.
Normes utilisées :
- Dépôts : le format natif
git bundlede Git.git clone <bundle>reconstruit le dépôt de bout en bout, y compris l’historique, les branches et les tags. Un dépôt sans aucun commit n’a rien à mettre dans un bundle et apparaît à la place sous la forme d’un fichier vide<repo>.empty. - Issues, pull requests et les autres fichiers de
metadata/: NDJSON, un objet JSON par ligne, sous la forme que l’API Forgejo renvoie pour chaque objet. - Journal d’audit : NDJSON, un événement par ligne (
id,action,actor,fields_json,created_at). Même forme que le flux d’audit interne de fremforge. - Journal d’accès au registre : NDJSON, du plus ancien au plus récent, un événement par ligne sous la forme que renvoie
GET /orgs/{slug}/access-log, avec les adresses IP et les identifiants des clients tels qu’ils ont été enregistrés. Il couvre tout ce qui est encore conservé selon la durée de rétention de votre journal d’audit. Voir Journal d’accès au registre. - Intégrité :
manifest.jsonliste chaque fichier avec son empreinte SHA-256 et sa taille. Le manifeste est signé en DSSE avec la clé de build Ed25519 de fremforge ; la signature se trouve dansmanifest.json.intoto.jsonlet se vérifie contre la racine de confiance publiquehttps://www.frem.sh/.well-known/slsa-trust-root.jsonavecopenssl,jq,python3etcurl, sans aucun outil fremforge. La procédure complète se trouve dansVERIFY.mdà l’intérieur du bundle et dans la section § « Vérifier le manifeste signé » de la page de l’export de données. C’est la même racine de confiance que celle publiée pour les attestations de build SLSA : une seule clé, deux types de prédicat, aucune dépendance à Sigstore.
Aucun format propriétaire. Chaque artefact du bundle se lit avec des outils open source standard. Aucune CLI fremforge n’est nécessaire.
Paquets
metadata/packages.ndjson est l’inventaire du registre de paquets de votre organisation : une ligne par version de paquet, avec son type (container, npm, maven, pypi, generic, …), son name et sa version, tels que les liste l’API de paquets de Forgejo.
metadata/packages-files.ndjson liste chaque fichier de chacune de ces versions, une ligne par fichier :
| Champ | Signification |
|---|---|
owner, type, name, version | la version de paquet à laquelle appartient le fichier |
file_id, file_name | l’identifiant et le nom du fichier dans le registre |
size | la taille en octets |
sha256 | le SHA-256 du fichier ; également sha512 lorsque le registre en enregistre un |
download_path | le chemin sur frem.sh qui télécharge exactement ce fichier avec un jeton d’API (Authorization: token …) ; le registre peut répondre par une redirection vers le stockage objet. null pour les types de registre dont l’URL de fichier ne peut pas être déduite de l’inventaire seul (Maven, par exemple) ; utilisez web_path pour ceux-là |
web_path | le lien de téléchargement du fichier sur la page de son paquet, pour un navigateur connecté |
Pour les images de conteneur, une version de paquet est un tag (ou, pour un manifeste sans tag, comme une plateforme d’une image multi-architecture, le digest lui-même). metadata/packages-container-tags.ndjson associe chaque tag au digest de son manifeste (owner, name, tag, manifest_digest), ce qu’utilisent docker pull <image>@sha256:… et les autres outils OCI. Les couches et la configuration de l’image apparaissent dans packages-files.ndjson comme des fichiers nommés d’après leur digest, avec un download_path qui pointe vers les points de terminaison /v2/…/blobs/… et /v2/…/manifests/… du registre.
Vérifier un fichier téléchargé par rapport à l’inventaire :
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 -L’inventaire figure toujours dans le bundle. Les fichiers des paquets eux-mêmes ne sont fournis que sur demande, dans une archive séparée : voir § « Contenu des paquets ».
Inventaire des composants
metadata/components.ndjson est l’inventaire des composants tiers de votre organisation : une ligne par composant et par endroit où il est ou a été utilisé, soit les mêmes lignes que renvoie GET /orgs/{slug}/components/usages. Les utilisations terminées sont conservées pendant 180 jours et sont incluses, si bien que l’historique part avec vous.
| Champ | Signification |
|---|---|
purl, ecosystem, name, version | le composant, sous la forme d’une package URL et de ses éléments |
licence, licence_source | l’expression de licence, et l’endroit où elle a été lue |
subject_kind, subject_name, subject_ref | l’endroit où il est utilisé : le dépôt, le paquet ou l’image, et la référence ou le digest |
image_tags | pour une image, les tags qui pointent vers elle ; vide sinon |
source_repo | le dépôt qui l’a construit, lorsqu’il est connu |
is_direct | true pour une dépendance directe, false pour une dépendance transitive, null lorsque le SBOM ne le précise pas |
environment, environment_source | la classe d’environnement (sandbox, development, test ou production) et la manière dont elle a été définie |
is_current, first_seen_at, last_seen_at, removed_at | si l’utilisation est actuelle, et quand elle a été vue pour la première et la dernière fois, puis retirée |
Déploiements
metadata/deployments.ndjson contient chaque déploiement que votre CI/CD a signalé avec POST /orgs/{slug}/repos/{repo}/deployments, une ligne par déploiement, triées par identifiant du plus ancien au plus récent.
| Champ | Signification |
|---|---|
id | l’identifiant du déploiement |
repository, environment, environment_class | le dépôt (owner/name), le nom d’environnement que vous avez indiqué et sa classe (sandbox, development, test, staging ou production) |
ref, sha, task, description | la référence et le commit déployés, la tâche (deploy, sauf si vous en avez indiqué une autre) et votre description |
image_digests, packages | les digests d’image et les package URLs que nomme le déploiement |
state | le dernier statut : pending, queued, in_progress, success, failure, error ou inactive |
creator_kind, creator, run_id | qui l’a signalé (job, robot, user ou token), son nom, et l’exécution Actions dans le cas d’un job |
created_at, updated_at | quand il a été signalé et modifié pour la dernière fois |
statuses | chaque statut, du plus récent au plus ancien : state, description, log_url, environment_url, creator_kind, creator, created_at |
Versions téléchargées
metadata/pulled-versions.ndjson est le recensement des téléchargements : une ligne par jour UTC, par version de paquet et par consommateur, pour les jours encore conservés selon la durée de rétention de votre journal d’accès. Depuis le 2026-10-13, c’est le seul enregistrement des téléchargements effectués par un job de CI via le proxy de dépendances et servis depuis son cache ; ceux-ci ne figurent pas dans access-log.ndjson. Ce sont les lignes que totalise GET /orgs/{slug}/components/pulled ; les avis de sécurité que ce point de terminaison y associe ne figurent pas dans le fichier.
| Champ | Signification |
|---|---|
day | le jour UTC, YYYY-MM-DD |
origin | registry pour vos propres paquets, proxy pour le proxy de dépendances |
ecosystem, name, version | le type de paquet (npm, pypi, maven, nuget, go, container, …), son nom et sa version |
consumer | qui l’a téléchargé : kind (job, robot, bot, user ou anonymous), name (le dépôt du job, le nom du robot ou l’identifiant ; null pour un accès anonyme), id, pour un robot son login, et pour un job run_ids, les exécutions Actions qui l’ont téléchargé ce jour-là (de la plus récente à la plus ancienne, 100 au maximum ; vide avant le 2026-10-13) |
pulls | les téléchargements réussis ce jour-là |
first_seen_at, last_seen_at | le premier et le dernier d’entre eux, en UTC avec les microsecondes |
Résultats d’analyse, politique, attestations et SBOM
Chaque export contient les données de sécurité que fremforge détient sur votre organisation, en NDJSON (un objet JSON par ligne), couvertes par le manifeste signé comme tous les autres fichiers. Chaque ligne est l’enregistrement complet que stocke fremforge, à l’exception de l’identifiant interne du tenant et des chemins de stockage ; les résultats écartés sont inclus, avec l’auteur de la décision, sa raison et sa date d’échéance. Les lignes qui concernent un paquet du registre portent un objet 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- Les signatures accompagnent les attestations. Chaque enveloppe se vérifie contre la même racine de confiance que le bundle, avec le script de la section § « Vérifier le manifeste signé » appliqué à l’enveloppe au lieu de
manifest.json.intoto.jsonl(ignorez les vérificationsmanifestSha256etpredicateType, qui ne s’appliquent qu’aux bundles d’export). Les bundles Sigstore sont signés par le Fulcio et l’autorité d’horodatage propres à fremforge, et non par le Sigstore public ; voir Provenance SLSA. - Une signature manquante est signalée, pas masquée. Une ligne avec
"envelope_status": "missing"correspond à une attestation dont l’objet de signature n’était plus dans le stockage au moment de l’export. Toute autre erreur de stockage fait échouer l’export. - Couches de conteneur. Le verdict antimalware d’une couche dépend de son contenu : une couche partagée avec une autre image est donc listée avec son verdict sous chacun de vos manifestes qui l’utilisent. Les images téléchargées via le proxy de dépendances ne sont listées que tant que votre organisation a activé l’analyse ClamAV des récupérations via le proxy ; lorsqu’elle est désactivée (par défaut), elles ne sont pas analysées par ClamAV et n’ont aucun verdict de couche.
- Les attestations de release existent pour les dépôts dotés de releases immuables. Une release dont le
statusn’est passignedn’a pas d’enveloppe (envelope_pathvautnull). - SBOM.
sboms/contient chaque SBOM que fremforge stocke pour vos dépôts (builds de release et de la branche par défaut, qu’ils aient été téléversés ou produits par l’analyse centrale) et pour vos images de conteneur (l’inventaire par manifeste du registre), sous la forme du document lui-même. Un build de dépôt dispose généralement à la fois d’un document CycloneDX et d’un document SPDX ; voir SBOM. Chaque ligne desboms/index.ndjsonest l’enregistrement SBOM stocké (id,subject_kindrepoouimage,format,repo_full_nameouartifact_name,release_tag,image_tags,manifest_digest,created_at,sha256_digestet le reste de l’enregistrement stocké, sans les chemins de stockage), plus trois champs relatifs au fichier dans ce bundle :document_path,document_sha256etdocument_status, qui vautoklorsque le document correspond au SHA-256 enregistré lors de son stockage,digest_mismatchdans le cas contraire (les octets sont tout de même exportés, et les deux digests figurent sur la ligne), etmissinglorsque le document n’était plus dans le stockage. Toute autre erreur de stockage fait échouer l’export. - Les SBOM des paquets ne sont pas dans
sboms/. Le SBOM de chaque fichier de paquet du registre accompagne le fichier dans l’archive facultative du contenu des paquets.