Zum Hauptinhalt springen

Vollständiger Datenexport

Du kannst die Daten deiner Organisation jederzeit über die Verwaltungsoberfläche exportieren: jedes Repository als Git-Bundle, die Issues, Pull Requests, Kommentare, Labels, Meilensteine und Releases jedes Repositorys, dein Paketinventar, deine Scan-Befunde und Entscheidungen der Paketrichtlinie, deine Build- und Release-Attestierungen mit ihren Signaturen, die SBOMs deiner Repositorys und Container-Images sowie den Audit-Trail der letzten 90 Tage. Alles liegt in Standardformaten vor und lässt sich als ein einziges .tar.gz mit einem signierten SHA-256-Manifest über jede Datei herunterladen.

Diese Seite beschreibt, was im Bundle steckt, wie du es prüfst und welche Grenzen gelten. Der Export ist im Plan für 30 € pro Nutzer enthalten; ein Enterprise-Tarif ist nicht nötig.

Was im Bundle steckt

Der Aufbau des Bundles, jede Datei darin und die Form jedes Datensatzes sind auf einer Seite beschrieben: Export-Schema. Kurz gesagt: ein Git-Bundle pro Repository; Issues, Pull Requests, Kommentare, Labels, Meilensteine, Releases und Einstellungen jedes Repositorys als NDJSON; dein Paketinventar und die Dateiliste; dein Inventar der Komponenten von Drittanbietern; dein Zugriffslog der Registry; deine Scan-Befunde, Entscheidungen der Paketrichtlinie und signierten Attestierungen; die SBOMs deiner Repositorys und Container-Images; und dein Audit-Trail, alles unter einem DSSE-signierten SHA-256-Manifest. Paketinhalte kommen auf Wunsch als zweites Archiv, siehe §„Paketinhalte“.

Paketinhalte

Setze beim Start eines Exports das Häkchen bei Paketinhalte einschließen (oder sende {"include_packages": true} an die API), dann erzeugt der Export neben dem Bundle ein zweites Archiv: jede Datei jeder Paketversion, die deiner Organisation gehört, zum Zeitpunkt des Exports aus dem Speicher der Registry gelesen.

export-<your-org-slug>-<timestamp>.packages.tar
└── packages/
    ├── npm/<name>/<version>/<file>               — e.g. npm/@acme/lib/1.2.0/lib-1.2.0.tgz
    ├── npm/<name>/<version>/<file>.cdx.json      — the file's SBOM (CycloneDX), and .spdx.json (SPDX)
    ├── maven/<group>/<artifact>/<version>/<file>
    ├── pypi/<name>/<version>/<file>
    ├── generic/<name>/<version>/<file>          — and the same shape for every other non-container type
    └── container/<image>/                        — one OCI image layout per image
        ├── oci-layout
        ├── index.json                            — one entry per tag
        └── blobs/sha256/<digest>                 — manifests, configs and layers
  • Mit dem Bundle signiert. Die manifest.json des Bundles verzeichnet Name, Größe und SHA-256 des Archivs (packages_archive) und jede Datei darin (objects), sodass die eine DSSE-Signatur beide Downloads abdeckt. VERIFY.md im Bundle enthält die Befehle; siehe auch §„Das Bundle prüfen“.
  • SBOMs. Jede Paketdatei kommt mit der Software-Stückliste, die fremforge beim Hochladen für sie erstellt hat: <file>.cdx.json (CycloneDX) und, wo eine erstellt wurde, <file>.spdx.json (SPDX), neben der Datei, für jeden Typ außer Containern. Sie stehen wie jede andere Datei in den objects des Manifests. Eine Datei, die der Scanner nicht verarbeiten konnte, hat keine. Liefert ein Paket selbst eine Datei mit genau diesem Namen, bleibt die Datei des Pakets erhalten und die SBOM entfällt. Container-Images bekommen hier keine SBOMs pro Datei; ihre SBOMs beschreibt SBOMs.
  • Container sind OCI-Image-Layouts, die skopeo, crane, oras und podman direkt lesen. Zum Beispiel, um einen Tag in eine andere Registry zu pushen: skopeo copy oci:packages/container/<image>:<tag> docker://<registry>/<image>:<tag>.
  • Einfaches .tar, nicht komprimiert: Paketdateien (.tgz, Wheels, JARs, Image-Layer) sind bereits komprimiert.
  • Download-Link: wird als Paketinhalte neben dem Link des Bundles angezeigt und von der API als packages_signed_url zurückgegeben. Wie der Link des Bundles 7 Tage gültig. Das Archiv selbst wird nach 7 Tagen gelöscht; starte einen neuen Export, wenn du es noch einmal brauchst.
  • Grenze von 50 GiB. Übersteigen die Paketinhalte deiner Organisation 50 GiB, wird die Anfrage sofort abgelehnt (export-too-large), und der Export ohne Paketinhalte bleibt verfügbar. Für einen begleiteten Export größerer Registries schreib an support@frem.sh.

Jede Datei wird beim Schreiben gegen Größe und SHA-256 aus dem Inventar geprüft und jede SBOM gegen Größe und SHA-256, die bei ihrer Erstellung verzeichnet wurden. Ein Export, dessen Paketdateien nicht übereinstimmen, schlägt fehl, statt ein Archiv zu liefern, das seinem Manifest widerspricht.

Scan-Befunde, Richtlinie, Attestierungen und SBOMs

Jeder Export enthält außerdem die Sicherheitsdaten, die fremforge über deine Organisation führt, wie jede andere Datei vom signierten Manifest abgedeckt:

  • findings/: die Befunde jedes Scanners, je eine NDJSON-Datei (statische Analyse, Abhängigkeiten, Lizenzen, Container-Images, Secrets, Malware in Uploads, Abhängigkeiten und Container-Layern, Schwachstellen und Lizenzen von Registry-Paketen, nicht gepinnte Workflow-Actions), mit ihren Verwerfungen: wer einen Befund verworfen hat, warum und bis wann.
  • policy/: deine Paketrichtlinie, ihre Erlaubt- und Verbotsregeln und Genehmigenden, das aktuelle Urteil für jede Paketdatei, Gate-Entscheidungen (einschließlich derer, die der Schattenmodus blockiert hätte), Ausnahmen mit ihren Genehmigungen, Malware-Übersteuerungen und die Organisationseinstellungen jedes Scanners.
  • attestations/: deine Build-Provenienz, Release-Attestierungen und mit einer SBOM hochgeladene Attestierungen, jeweils mit ihrem DSSE-Umschlag und, wo eines erstellt wurde, ihrem schlüssellosen Sigstore-Bundle.
  • sboms/: jede SBOM, die fremforge für deine Repositorys (sboms/repos/, CycloneDX und, wo eine erstellt wurde, SPDX) und deine Container-Images (sboms/images/) speichert, als die Dokumente selbst, indiziert durch sboms/index.ndjson. Jede Indexzeile sagt, ob das Dokument mit dem beim Speichern verzeichneten SHA-256 übereinstimmte. Paket-SBOMs sind nicht hier: Sie liegen neben ihren Dateien im Archiv der Paketinhalte.

Die Dateien und ihre Felder sind im Export-Schema aufgeführt.

Was NICHT im Bundle steckt (und warum)

  • Paketinhalte und Container-Image-Layer, außer du forderst sie an: Dann kommen sie als separates Archiv, siehe §„Paketinhalte“.
  • Inhalte von LFS-Dateien, siehe §„LFS-Inhalte“.
  • Release-Assets: releases.ndjson enthält die Metadaten jedes Releases einschließlich der Download-URL jedes Assets; lade die Assets von diesen URLs.
  • Logs und Artefakte von Forgejo-Actions-Läufen werden nicht exportiert. Lade die Logs und Artefakte eines Laufs von der Seite des Laufs oder über die Actions-API herunter, solange du sie brauchst.
  • Paket-SBOMs, außer du forderst Paketinhalte an: Die SBOM jeder Paketdatei der Registry liegt neben der Datei im Archiv der Paketinhalte. SBOMs von Repositorys und Container-Images sind im Bundle, unter sboms/ (siehe §„Scan-Befunde, Richtlinie, Attestierungen und SBOMs“).
  • Rechnungen und Abrechnungsdaten sind nicht Teil des Bundles; sie stehen in der Verwaltungsoberfläche unter Abrechnung.
  • Daten anderer Mandanten: Der Ausschnitt des Audit-Logs enthält nur die Audit-Ereignisse deiner eigenen Organisation.

So startest du einen Export

  1. Verwaltungsoberfläche der Organisation → Tab Datenexport.
  2. Setze optional das Häkchen bei Paketinhalte einschließen (siehe §„Paketinhalte“).
  3. Klicke auf Neuen Export starten.
  4. Der Export-Runner übernimmt den Job innerhalb von 5 Minuten. Eine kleine Organisation ist wenige Minuten später fertig; die Dauer wächst mit der Größe deiner Repositorys. Der Tab Datenexport zeigt den Status des Jobs und, sobald er fertig ist, den Download-Link.
  5. Der Download-Link ist 7 Tage ab Fertigstellung des Bundles gültig, und die Bundle-Datei wird 7 Tage nach ihrer Erstellung gelöscht, einschließlich ihrer Kopie für die Notfallwiederherstellung. Unter einer Aufbewahrungspflicht (Legal Hold) bleibt die Datei erhalten.

Schlägt ein Export fehl, bekommt die Person, die ihn angefordert hat, eine E-Mail mit dem Grund, und du kannst sofort einen neuen starten.

Ratenlimit

Ein Export pro Organisation alle 24 Stunden. Feste Grenze. Ein fehlgeschlagener Export zählt nicht, du kannst es also sofort erneut versuchen. Der Grund: Ein Repository von mehreren GB per git bundle zu verpacken und die Hashes des Manifests zu berechnen, kostet etwas, und ein Fehlklick soll über Nacht keine hundert Exporte auslösen.

Brauchst du wirklich einen zweiten Export innerhalb von 24 Stunden, schreib an support@frem.sh. Wir können die Grenze auf Anfrage aufheben.

Größengrenzen

Das Archiv wird während der Erstellung in den Speicher gestreamt, seine Größe ist also weder durch den Arbeitsspeicher noch durch eine Grenze für einzelne Uploads beschränkt. Was einen Export heute begrenzt:

  • Etwa 10 GB an Repository-Bundles und Metadaten, der Arbeitsbereich, in dem der Export-Runner Dateien vor dem Archivieren ablegt.
  • Eine Stunde für den gesamten Export.
  • 50 GiB an Paketinhalten, wenn du sie anforderst; wird bereits bei der Anfrage abgelehnt, siehe §„Paketinhalte“.

Eine Organisation über einer dieser Grenzen bekommt einen Fehler statt eines unvollständigen Bundles. Schreib an support@frem.sh, dann führen wir stattdessen einen begleiteten Export durch (meist eine direkte Synchronisierung in deinen eigenen Bucket).

Bei den meisten Organisationen machen die Repository-Inhalte mit Abstand den größten Teil aus; Metadaten und Audit-Daten sind im Vergleich klein.

Das Bundle prüfen

Ob jede Datei unversehrt bei dir angekommen ist, prüfst du mit einem einzigen sha256sum-Aufruf. Voraussetzung: jq (das SHA-256-Werkzeug bringt jedes aktuelle Betriebssystem mit, sha256sum unter Linux, shasum -a 256 unter macOS).

Entpacke das Archiv und führe dann im entpackten Verzeichnis aus:

# Linux
sha256sum --check <(jq -r '.files[] | "\(.sha256)  \(.path)"' manifest.json)

# macOS
shasum -a 256 -c <(jq -r '.files[] | "\(.sha256)  \(.path)"' manifest.json)

Meldet jede Zeile OK, stimmt jede Datei im Bundle mit dem SHA-256-Hash überein, den fremforge verzeichnet hat. Ein abgeschnittener oder beschädigter Download lässt sich nicht sauber entpacken oder fällt bei dieser Prüfung durch.

Was diese Prüfung erkennt und was nicht

Die SHA-256-Prüfung erkennt Manipulationen nach dem Export (beschädigte Downloads, MITM-Veränderungen an einem unsignierten Mirror) und gleicht das Bundle mit dem Manifest ab, das fremforge erzeugt hat. Um nachzuweisen, dass das Manifest selbst von fremforge stammt (und nicht von Dritten, die dein Bundle gegen ihres ausgetauscht haben), führe die Prüfung des signierten Manifests im nächsten Abschnitt aus. Sie bindet die Bytes des Manifests kryptografisch an den veröffentlichten Ed25519-Builder-Schlüssel von fremforge.

Das signierte Manifest prüfen

Das Bundle enthält unter manifest.json.intoto.jsonl ein DSSE-signiertes in-toto-Statement über manifest.json. Die Signatur wird mit dem Ed25519-Schlüssel des SLSA-Builders von fremforge erzeugt, demselben Schlüssel, der die SLSA-Build-Provenienz für Artefakte des gehosteten Runners signiert, und lässt sich gegen die öffentliche Vertrauensbasis unter https://www.frem.sh/.well-known/slsa-trust-root.json prüfen. Der aktive Schlüssel ist fremforge-slsa-builder-v2, im Einsatz seit dem Schlüsselwechsel vom 12.09.2026; die Befehle unten wählen ihn aus. VERIFY.md in deinem Bundle enthält dieselben Befehle, bereits mit dem Schlüssel, der dieses Bundle signiert hat.

Nimm den Schlüssel, den der Umschlag nennt. Die keyid in manifest.json.intoto.jsonl (jq -r '.signatures[0].keyid' manifest.json.intoto.jsonl) ist der Schlüssel, der ihn signiert hat. Ein Bundle, das vor dem 12.09.2026 exportiert wurde, ist mit fremforge-slsa-builder-v1 signiert. Dieser bleibt zur Prüfung alter Signaturen in der Vertrauensbasis (er signiert nichts mehr); wähle für ein solches Bundle in Schritt 1 fremforge-slsa-builder-v1. Ein aktuelles Bundle lässt sich nicht mit v1 prüfen: Schritt 2 gibt dann DSSE signature verification FAILED aus.

Du prüfst mit curl, jq, openssl und python3, die alle in Distributionen standardmäßig vorhanden sind. Keine CLI von fremforge. Keine Abhängigkeit von Sigstore Fulcio, Rekor oder einem TUF-CDN.

1. Die öffentliche Vertrauensbasis abrufen und den öffentlichen Schlüssel herausziehen

curl -sSfL https://www.frem.sh/.well-known/slsa-trust-root.json -o trust-root.json
jq -r '.trusted_keys[] | select(.kid=="fremforge-slsa-builder-v2") | .pem' \
  trust-root.json > builder.pub

2. Die Signatur des DSSE-Umschlags prüfen

python3 - <<'PY'
import base64, json, hashlib, subprocess, sys, pathlib

env = json.loads(pathlib.Path("manifest.json.intoto.jsonl").read_text().strip())
payload_type = env["payloadType"]
payload_b64  = env["payload"]
payload      = base64.b64decode(payload_b64)

# Reconstruct the DSSE pre-authentication encoding.
pae = (
    b"DSSEv1 "
    + str(len(payload_type)).encode() + b" "
    + payload_type.encode() + b" "
    + str(len(payload)).encode() + b" "
    + payload
)
pathlib.Path("pae.bin").write_bytes(pae)

sig_b64 = env["signatures"][0]["sig"]
pathlib.Path("sig.bin").write_bytes(base64.b64decode(sig_b64))

# Ed25519 verify with openssl: pkeyutl -verify needs the SAME bytes
# the signer hashed. EdDSA is "pure" — no pre-hash — so feed the
# raw PAE buffer.
r = subprocess.run(
    ["openssl", "pkeyutl", "-verify", "-pubin",
     "-inkey", "builder.pub",
     "-rawin", "-in", "pae.bin",
     "-sigfile", "sig.bin"],
    capture_output=True, text=True,
)
if r.returncode != 0 or "Signature Verified Successfully" not in r.stdout:
    print("DSSE signature verification FAILED:", r.stdout, r.stderr, file=sys.stderr)
    sys.exit(1)
print("DSSE signature: OK")

# Cross-check the signed manifestSha256 matches the on-disk manifest.json.
stmt = json.loads(payload)
claimed = stmt["predicate"]["manifestSha256"]
actual  = hashlib.sha256(pathlib.Path("manifest.json").read_bytes()).hexdigest()
if claimed != actual:
    print(f"manifestSha256 mismatch: signed={claimed} actual={actual}", file=sys.stderr)
    sys.exit(1)
print(f"manifestSha256: OK ({actual})")

# Sanity-check the predicate type.
if stmt["predicateType"] != "https://fremforge.eu/spec/export-bundle/v1":
    print(f"unexpected predicateType: {stmt['predicateType']}", file=sys.stderr)
    sys.exit(1)
print("predicateType: OK")
PY

3. Den SHA-256 jeder Datei gegen das (nun vertrauenswürdige) Manifest prüfen

# Linux:
sha256sum --check <(jq -r '.files[] | "\(.sha256)  \(.path)"' manifest.json)

# macOS:
shasum -a 256 -c <(jq -r '.files[] | "\(.sha256)  \(.path)"' manifest.json)

Bestehen alle drei Schritte, ist das Bundle durchgängig manipulationssicher nachweisbar: Jede Datei stimmt mit dem von fremforge verzeichneten SHA-256 überein, das Manifest stimmt mit dem überein, was fremforge signiert hat, und die Signatur stammt vom veröffentlichten Builder-Schlüssel.

4. Paketinhalte (nur wenn du sie angefordert hast)

Lade das .packages.tar in dasselbe Verzeichnis herunter und prüfe dann das Archiv und jede Datei darin gegen dasselbe signierte Manifest:

echo "$(jq -r '.packages_archive.sha256' manifest.json)  $(jq -r '.packages_archive.name' manifest.json)" | sha256sum --check
tar -xf "$(jq -r '.packages_archive.name' manifest.json)"
sha256sum --check <(jq -r '.objects[] | "\(.sha256)  \(.path)"' manifest.json)

Was die Signatur beweist

  • Die Bytes des Bundles, die du erhalten hast, sind identisch mit dem, was fremforge zum Zeitpunkt des Exports erzeugt hat.
  • Das Manifest wurde mit dem Builder-Schlüssel von fremforge erzeugt, nicht von Dritten.
  • Das signierte Prädikat (https://fremforge.eu/spec/export-bundle/v1) nennt den Slug der Organisation, die ID der Exportanfrage, die Anzahl der Dateien und die Gesamtzahl der Bytes; ein untergeschobenes Bundle eines anderen Mandanten würde die Prüfung nicht bestehen.

Was sie nicht beweist

  • Zeitpunkt: Das signierte exportedAt ist eine Angabe von fremforge. Für Zeitstempel, die Dritte bezeugen können, gleiche den Audit-Log-Ausschnitt des Bundles mit der öffentlichen, WORM-verankerten Audit-Kette ab.
  • Schlüsselwiderruf: Das JSON der Vertrauensbasis ist maßgeblich. Widerruft fremforge später den Builder-Schlüssel, lassen sich alte Signaturen nicht mehr prüfen, sobald der Schlüssel aus trusted_keys verschwindet. Ruf die Vertrauensbasis erneut ab, wenn du lange nach dem Export prüfst.

Ein Repository aus einem Bundle neu klonen

Jedes bundles/<repo>.bundle ist ein gewöhnliches git bundle. Zum Wiederherstellen:

git clone bundles/<repo>.bundle <repo>
cd <repo>
git remote remove origin                  # bundle URL is local
git remote add origin <new-fremforge-or-elsewhere-url>
git push -u --mirror origin

--mirror erhält alle Branches, Tags und Refs. Das Bundle stellt die vollständige Historie des Repositorys mit identischen SHAs wieder her; auf einem neuen Remote ist kein Force-Push nötig.

LFS-Inhalte

Die Inhalte von LFS-Dateien sind nicht im Bundle. Das Git-Bundle enthält den Pointer jeder LFS-Datei (ihre oid und size), die Historie ist also vollständig; die Inhalte selbst bleiben auf dem LFS-Server von fremforge. Viele Gigabyte an binären Anhängen in jeden Export zu packen, würde ihn für alle aufblähen.

metadata/<repo>/lfs-manifest.ndjson ist das LFS-Inventar pro Repository: eine Zeile pro LFS-Objekt, auf das irgendein Branch, Tag oder Pull Request im Repository verweist.

FeldBedeutung
oidder SHA-256 des Objekts, wie in seinem LFS-Pointer
sizeGröße in Bytes
storedtrue, wenn der LFS-Server von fremforge das Objekt hat; false für einen Pointer, der committet wurde, ohne dass sein Inhalt je hochgeladen wurde
pathein Pfad, unter dem das Repository auf das Objekt verweist (ein Pfad pro Objekt, auch wenn es an mehreren Stellen committet ist)
download_pathPfad auf frem.sh, der die Bytes des Objekts ausliefert (HTTP Basic Auth, Benutzername token, ein API-Token als Passwort); null, wenn stored false ist

Das Inventar wird aus der Historie des Repositorys erstellt; Objekte, die auf den LFS-Server hochgeladen wurden, auf die aber kein Branch, Tag oder Pull Request verweist, sind daher nicht aufgeführt. Ein Repository ohne LFS bekommt eine leere Datei. Verweist die Historie eines Repositorys auf LFS-Objekte, lässt sich der LFS-Server von fremforge aber nicht abfragen, schlägt der Export fehl, statt ein unvollständiges Inventar auszuliefern.

Um LFS-Inhalte herunterzuladen, nachdem du das Repository aus dem Bundle neu geklont hast:

git lfs install
git lfs fetch --all

Das lädt vom LFS-Server von fremforge, solange du zahlender Kunde bist (LFS-Bandbreite ist enthalten). Nach einer Kündigung bewahren wir deine Daten 90 Tage auf; in diesem Zeitraum funktionieren LFS-Downloads.

Für einen Enterprise-Export, der die LFS-Bytes direkt enthält, wende dich an den Support. Wir schätzen die Größe des Bundles ab und führen den Export unter Umständen als Synchronisierung von OBS zu OBS statt als herunterladbares Archiv durch.

Zu einem anderen Anbieter wechseln (EU Data Act)

Dieser Abschnitt ist die nach Art. 26 des EU Data Act (Verordnung (EU) 2023/2854) vorgeschriebene Information. Die zugehörigen Vertragsbedingungen stehen in Nutzungsbedingungen §16.6.

Du kannst jederzeit zu einem anderen Anbieter wechseln, alles auf deine eigene Infrastruktur übertragen oder alles löschen lassen, mit oder ohne Kündigung.

So startest duVerwaltungsoberfläche → Datenexport oder eine E-Mail an support@frem.sh. Kein Formular, kein Rückhalteanruf.
KündigungsfristNach dem Data Act höchstens zwei Monate. Wir beginnen bei Eingang, du wartest nicht.
ÜbergangszeitraumHöchstens 30 Kalendertage. Verlängerbar nur, wo es technisch tatsächlich nicht machbar ist, und nur mit einer schriftlichen Begründung an dich innerhalb von 14 Arbeitstagen.
Während des ÜbergangsDer Dienst läuft mit demselben Service-Level und zum selben Preis weiter. Nichts wird schlechter, weil du gehst.
Abrufzeitraum30 Tage nach Ende des Übergangs oder der oben genannte 90-Tage-Zeitraum nach der Kündigung, je nachdem, was länger ist.
KostenKeine. Keine Wechselgebühr, keine Egress-Gebühr, keine Vertragsstrafe bei vorzeitiger Beendigung. Der Data Act erlaubt kostenbasierte Gebühren bis zum 12. Januar 2027; wir erheben sie nicht.

Formate. Alles im Bundle liegt in offenen Standardformaten vor (git bundle, JSONL, in-toto DSSE, JSON), beschrieben auf der Seite Export-Schema. Kein proprietäres Format von fremforge, und du brauchst kein Werkzeug von fremforge, um irgendetwas davon zu lesen.

Import in ein selbst gehostetes Forgejo. fremforge betreibt einen angepassten Forgejo-Build, aber die Patch-Serie ändert das Datenmodell von Forgejo nicht, ein Export lässt sich also direkt in eine unveränderte, selbst gehostete Forgejo-Instanz importieren. Klone jedes Repository aus seinem Bundle neu (§„Ein Repository aus einem Bundle neu klonen“) und pushe es mit --mirror auf den neuen Host. Issues und Pull Requests ziehen über die unten genannten, zur GitHub-API kompatiblen Endpunkte um.

Stattdessen löschen. Sollen die Daten verschwinden statt umzuziehen, sag es in derselben Anfrage. Wir löschen alle exportierbaren Daten und digitalen Assets gemäß AVV §9 und bestätigen es schriftlich.

Hilfe gehört dazu. Nach §16.6(h) der Nutzungsbedingungen unterstützen wir den Wechsel nach Treu und Glauben, auch indem wir technische Fragen des Anbieters beantworten, zu dem du wechselst. Frag einfach.

Kündigung und Export

Wenn du dein fremforge-Abonnement kündigst:

  • Dein letztes 7-Tage-Fenster für den Export bleibt gültig. Die signierte URL funktioniert weiter.
  • Während der 90-tägigen Aufbewahrung mit Lesezugriff nach der Kündigung kannst du jederzeit einen neuen Export auslösen. Derselbe Ablauf, dieselbe Oberfläche, dasselbe Bundle.
  • Ein Export, der spät im 90-Tage-Zeitraum in die Warteschlange kommt, selbst bei +89 T 23 Std., wird ausgeführt: fremforge hält die physische Löschung deiner Forgejo-Organisation bis zu 7 Tage über die 90-Tage-Marke hinaus zurück, solange ein Export in der Warteschlange steht oder läuft. Nach Abschluss des Exports erfolgt die Löschung beim nächsten geplanten Durchlauf.
  • Nach 90 Tagen (plus der oben genannten Nachfrist für den Export) werden die Daten gemäß AVV §9 gelöscht; damit endet auch die Verfügbarkeit des Exports.

Kündigst du gerade, weil du einen letzten Export willst, exportiere zuerst, prüfe den Export lokal und kündige dann. Der Zeitraum ist großzügig, aber erst prüfen und dann löschen ist der sorgfältige Weg.

Nur ein Repository?

Der vollständige Export umfasst die ganze Organisation: jedes Repository mit seinen Issues, Pull Requests und Releases, das Paketinventar und den Audit-Ausschnitt in einem signierten Bundle. Brauchst du nur ein einzelnes Repository, gibt es einfachere Wege:

  • git clone --mirror: vollständige Git-Historie, Branches und Tags als offline klonbares Bare-Repository. fremforge stellt Port 22 nicht öffentlich bereit; nutze entweder den SSH-über-443-Endpunkt (ssh.frem.sh:443) oder die HTTPS-Variante:

    # SSH over port 443 (single endpoint for all orgs; uses your registered SSH key):
    git clone --mirror ssh://git@ssh.frem.sh:443/<org>/<repo>.git
    
    # OR HTTPS clone with a PAT (`ffp_…`) from Settings → API tokens:
    git clone --mirror "https://x-access-token:${FREMFORGE_PAT}@frem.sh/<org>/<repo>.git"
    
    cd <repo>.git
    git lfs fetch --all   # if the repo uses LFS

    Die Fingerabdrücke der Host-Schlüssel für ssh.frem.sh sind unter www.frem.sh/ssh-fingerprints veröffentlicht; prüfe sie bei der ersten Verbindung. Das Ergebnis ist ein Verzeichnis, aus dem sich direkt ein git bundle erstellen lässt; pack es mit tar -czf in eine einzelne, portable Datei.

  • Repository als Zip oder Tarball herunterladen: frem.sh/<org>/<repo>/archive/<branch>.zip oder .tar.gz für einen Schnappschuss eines einzelnen Refs. Keine Historie, kein LFS, nur der Arbeitsbaum dieses Branches.

  • Issues und PRs pro Repository als JSON über die API: GET /api/v1/repos/<org>/<repo>/issues?state=all&type=issues und ?type=pulls. Die Migrationsanleitungen zeigen die Form des Aufrufs; die Antwort ist zur GitHub-API kompatibles JSON.

Der signierte Export der ganzen Organisation ist das richtige Werkzeug, wenn du alles willst (jedes Repository, seine Metadaten, den Audit-Log-Ausschnitt, das signierte Manifest); die Wege pro Repository oben passen für den Alltagsfall „Ich muss dieses eine Repository jemandem schicken“.

Programmatische API

Derselbe Export ist über die REST-API erreichbar:

# Start a new export
curl -X POST \
  -H "Authorization: Bearer <your-PAT>" \
  https://frem.sh/_app/api/v1/orgs/<your-org>/exports

# ... or with package contents (separate archive, 50 GiB limit)
curl -X POST \
  -H "Authorization: Bearer <your-PAT>" -H "Content-Type: application/json" \
  -d '{"include_packages": true}' \
  https://frem.sh/_app/api/v1/orgs/<your-org>/exports

# Poll for status
curl -H "Authorization: Bearer <your-PAT>" \
  https://frem.sh/_app/api/v1/orgs/<your-org>/exports/<job-id>

# When status=ready, follow the signed_url field
# (and packages_signed_url, if you asked for package contents)

OpenAPI-Spezifikation: docs.frem.sh/reference/api/.

Datenschutzgarantien

Der Export ist in beide Richtungen nachvollziehbar:

  • Wer exportiert hat: Jede Exportanfrage wird in deinem eigenen Audit-Log festgehalten (data-export.requested aus der Verwaltungsoberfläche, data-export.queue.api aus der API), mit dem anfragenden Nutzer oder Token. Aktionen, die der Support von fremverk an deiner Organisation vornimmt, sind im selben Log als solche gekennzeichnet.
  • Wessen Daten: Der Audit-Log-Ausschnitt wird über die Mandanten-ID deiner Organisation ausgewählt und enthält daher nur die Audit-Ereignisse deiner eigenen Organisation.
  • Sauberer Umgang mit signierten URLs: Die Download-URL ist ein vorab signierter Link nur zum Lesen, der auf genau dein Archiv zeigt und 7 Tage gültig ist. Danach funktioniert die URL nicht mehr, und der Export verschwindet aus dem Tab Datenexport.

Querverweise

  • Preise: im Plan für 30 € pro Nutzer enthalten, kein eigener Tarif.
  • AVV §9: die Zusage zur Datenrückgabe, die hiermit erfüllt wird.
  • Trust: wie sich das in das größere Bild von Souveränität und Kontrolle einfügt.