Naar de hoofdinhoud

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

VeldBetekenis
occurred_atWanneer fremforge het verzoek beantwoordde (UTC).
originWelk onderdeel het verzoek zag: registry voor de package registry. De dependency proxy schrijft proxy.
surfaceapi (/api/packages/…), oci (/v2/…, de containerregistry) of web (een bestand gedownload via de webinterface).
org, package.type, package.name, package.version, package.fileWat er werd gevraagd.
repoBij een verzoek met een jobtoken van Forgejo Actions: de repository van de job, <owner>/<repo>. Anders leeg.
actionsBij 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.digestsha256:<hex> van het bestand of manifest dat werd uitgeleverd of opgeslagen, als de registry het noemde.
actiondownload, metadata, upload, delete of other.
actorWie 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_ipHet 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_agentDe User-Agent van de client, afgekapt op 256 tekens.
http.method, http.status, http.bytesDe 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_reasonallowed; 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_ID

De 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/packages doet, 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.