Toegangslog van de registry
De auditlog legt beheeracties vast. De toegangslog
van de registry legt iets anders vast: elk verzoek dat een client doet aan de
pakket- en containerregistry van je organisatie. Dat omvat elke download,
elke metadata-leesactie (een npm-packument, een PyPI simple index, een Maven
maven-metadata.xml), elke upload en elke verwijdering, en ook verzoeken die
door een beleid zijn geblokkeerd. Er wordt niets gesampled, met twee
uitzonderingen voor routinematig CI-verkeer via de
dependency proxy. Beide gelden alleen voor
een verzoek van een Forgejo Actions-job dat de proxy heeft toegestaan en zonder
fout heeft beantwoord:
- Metadata-leesacties van CI worden niet vastgelegd (sinds 2026-10-12). Een
pakketindex of versielijst (een npm-packument, een PyPI simple index, een
Maven
maven-metadata.xml) die een job leest, wordt niet opgeslagen. Eén pakketinstallatie doet honderden van die leesacties, en ze vertellen niets wat de download erna niet ook vertelt. - CI-downloads uit de proxycache worden geteld, niet één voor één gelogd (sinds 2026-10-13). Downloadt een job een pakketbestand dat de proxy al heeft, dan wordt de download bij de pull-telling opgeteld in plaats van als gebeurtenis opgeslagen: één telling per UTC-dag, pakketversie en repository, met de id’s van de Actions-runs die het pakket ophaalden. Zo kun je in de telling nog steeds per run zien welke versie van welk pakket in welke build terechtkwam.
Al het andere blijft één gebeurtenis, ook voor CI:
- elke download die de proxy bij de upstream-registry ophaalde (een cache miss), en elke download uit je eigen registry
- elk verzoek dat een beleid weigerde, blokkeerde of zou hebben geblokkeerd
- elk verzoek dat mislukte (een status van 400 of hoger)
- elk verzoek van een persoon, een bot, een registryrobot of anoniem, inclusief metadata-leesacties en cache hits
Een CI-download die in de telling wordt meegeteld, bewaart het pakket, de
versie, de dag, de repository en de run, en het aantal pulls. Wat een
gebeurtenis daarnaast bevat, wordt niet bewaard: de bestandsnaam, de grootte,
het precieze tijdstip van elke pull (de telling heeft de eerste en laatste van
de dag), het clientadres, de user agent en de request-id. Zo’n download wordt
niet afgeleverd bij een SIEM-endpoint en staat niet in access-log.ndjson; hij
staat in de API van de telling en in metadata/pulled-versions.ndjson in de
data-export. Gebeurtenissen die vóór deze datums zijn opgeslagen, worden
bewaard volgens de normale bewaartermijn.
Wat een gebeurtenis bevat
| Veld | Betekenis |
|---|---|
occurred_at | Wanneer fremforge het verzoek beantwoordde (UTC). |
origin | Welk onderdeel het verzoek zag: registry voor de package registry. De dependency proxy schrijft proxy. |
surface | api (/api/packages/…), oci (/v2/…, de containerregistry) of web (een bestand gedownload via de webinterface). |
org, package.type, package.name, package.version, package.file | Wat er werd gevraagd. |
repo | Bij een verzoek met een jobtoken van Forgejo Actions: de repository van de job, <owner>/<repo>. Anders leeg. |
actions | Bij een verzoek met een jobtoken van Forgejo Actions: de run waar het vandaan kwam, {repo_id, run_id, run_number, job_id}. run_number is de pagina van de run, /<owner>/<repo>/actions/runs/<run_number>; run_id is GITHUB_RUN_ID. null bij elk ander verzoek, en bij verzoeken die vóór 2026-10-08 zijn vastgelegd. |
package.digest | sha256:<hex> van het bestand of manifest dat werd uitgeleverd of opgeslagen, als de registry het noemde. |
action | download, metadata, upload, delete of other. |
actor | Wie de registry heeft geauthenticeerd: {type: "user" | "bot" | "anonymous", id, login}. Een token of sessie wordt herleid tot de gebruiker van wie het is, en jobs van Forgejo Actions verschijnen als bot. |
client_ip | Het clientadres zoals de edge van fremforge het zag. Het is leeg als fremforge het adres niet kon verifiëren, bijvoorbeeld bij een verzoek dat niet via de edge binnenkwam. |
user_agent | De User-Agent van de client, afgekapt op 256 tekens. |
http.method, http.status, http.bytes | De requestmethode, het antwoord en de grootte als die bekend is. De grootte is onbekend bij een download die naar objectopslag wordt doorgestuurd. Een HEAD-verzoek verschijnt als GET, omdat het CDN HEAD-verzoeken als GET naar de registry doorstuurt. |
decision, decision_reason | allowed; blocked; would_block (een beleid in schaduwmodus, of de blokkeeractie warn van je imagescan, zou het hebben geweigerd, en het verzoek ging door); of pending_refused (je pakketbeleid weigert bestanden waarvan de scan nog niet klaar is, en die van dit bestand was dat nog niet; de client kreeg 503 met Retry-After, en een nieuwe poging na afloop van de scan slaagt). decision_reason noemt de regel die besliste, bijvoorbeeld malware, image_malware, image_cve, registry_scan:<reason> of immutable_retired (zie onveranderlijke pakketversies). |
Nooit vastgelegd: een toegangstoken, een Authorization-header, een cookie
of een querystring. Een presigned opslag-URL verschijnt bijvoorbeeld nooit in
een gebeurtenis.
Uitlezen
Met een token dat audit:read heeft:
curl -sS -H "Authorization: Bearer $FFP_TOKEN" \
"https://frem.sh/_app/api/v1/orgs/acme/access-log?action=download&type=npm&since=2026-10-01"Resultaten komen nieuwste eerst. Geef de waarde next van een pagina mee als
cursor om de volgende pagina te krijgen, en stop als next null is. De
cursor is een keyset, dus gebeurtenissen die binnenkomen terwijl je bladert,
verschuiven of herhalen nooit een rij. Filters: since, until, origin,
action, decision, type, name, version, actor (een login, of
anonymous) en ip. Een pagina bevat maximaal 500 gebeurtenissen. Zie de
API-referentie voor de volledige structuur.
Welke kwetsbare versies worden opgehaald
De pull-telling telt de geslaagde downloads in
deze log per pakketversie en afnemer, samen met de CI-cache hits die daar
worden geteld in plaats van gelogd, en koppelt ze aan de advisory’s die je
pakketbeleid gebruikt. Ze beantwoordt “welke kwetsbare versies zijn de
afgelopen 30 dagen opgehaald, en door wie” zonder dat je door de ruwe
gebeurtenissen hoeft te bladeren, en run_id beantwoordt “welke versies heeft
deze build opgehaald”.
Doorsturen naar je SIEM
Toegangsgebeurtenissen kunnen worden afgeleverd bij een
SIEM-endpoint, in dezelfde ondertekende envelop als
auditgebeurtenissen. De actie is registry.access.<action> (bijvoorbeeld
registry.access.download), en hash_chain is null, omdat
toegangsgebeurtenissen geen deel uitmaken van de hashketen van de auditlog.
Aflevering staat standaard uit, omdat downloadverkeer veel groter is dan
auditverkeer. Zet het per endpoint aan met include_access_log:
curl -sS -X PATCH -H "Authorization: Bearer $FFP_TOKEN" -H 'Content-Type: application/json' \
-d '{"include_access_log": true}' \
https://frem.sh/_app/api/v1/orgs/acme/siem/endpoints/$ENDPOINT_IDDe actieprefixen van een endpoint gelden ook voor toegangsgebeurtenissen.
registry.access.upload stuurt bijvoorbeeld alleen uploads door. Het
CI-verkeer dat niet als gebeurtenis wordt opgeslagen (zie boven), wordt ook
niet afgeleverd.
In de data-export
Een data-export bevat access-log.ndjson met elke
toegangsgebeurtenis die fremforge nog voor de organisatie bewaart, één
JSON-object per regel in dezelfde structuur als de API teruggeeft, en
metadata/pulled-versions.ndjson met de pull-telling, waarin CI-cache hits
worden geteld. Beide bestanden vallen onder het ondertekende manifest van de
export.
Hoe lang het wordt bewaard
Toegangsgebeurtenissen worden bewaard volgens de
bewaartermijn voor bewijs access_log van
je organisatie: 30 tot 730 dagen. Is die niet ingesteld, dan volgt ze de
bewaartermijn van de auditlog (90, 180, 365 of 730 dagen, in te stellen bij
Authenticatiebeleid → Bewaartermijn auditlog; standaard 90). Oudere
gebeurtenissen worden eens per dag verwijderd. Zolang er een legal hold geldt,
wordt er niets verwijderd.
Wie de adressen kan zien
De toegangslog bevat persoonsgegevens: de logins en IP-adressen van je gebruikers. De API, de SIEM-aflevering en de export tonen beide zoals ze zijn vastgelegd, omdat dit het eigen register van je organisatie is. Tooling van fremforge-medewerkers ziet beide alleen als gesleutelde pseudoniemen. Logregels die het platform voor zijn eigen werking schrijft, bevatten geen van beide.
Beperkingen
- Git clone en fetch, en leesacties via de REST API (
/api/v1), zijn geen registryverzoeken en staan nog niet in deze log. - Het verwijderen van een pakketversie via de REST API
(
DELETE /api/v1/packages/...) of de webinterface wordt hier niet vastgelegd. Verwijderingen die een registryclient onder/api/packagesdoet, worden wel vastgelegd. - Een verzoek dat het platform weigerde voordat de registry antwoordde, zoals
een upload die door de malwarescanner is afgewezen, heeft geen
geauthenticeerde actor en verschijnt als
anonymous. - Aflevering van de registry aan de log gebeurt in batches, elke 2 seconden of per 500 gebeurtenissen. Wordt het platform midden in een batch herstart, dan kunnen de gebeurtenissen van de laatste paar seconden verloren gaan. Bewuste drops worden aan onze kant gelogd en gealarmeerd.