fremforge CLI
fremforge CLI er en enkelt binærfil, der pakker det offentlige REST API ind. Samme verber, samme autorisationsmodel, samme scopes. Distribueres kun fra PoP’er i EU; ingen afhængighed af npm-registryet, Docker Hub eller Sigstore Fulcio.
Supportperiode, sikkerhedsopdateringer og SBOM
| Supportperiode | 5 år fra udgivelsesdatoen for hver minor-version. Det er supportperioden i henhold til artikel 13, stk. 8, i Cyber Resilience Act (forordning (EU) 2024/2847), og den knytter sig til den udgivne version, ikke til dit abonnement. |
| Sikkerhedsrettelser | Gratis, altid, og aldrig forbeholdt et bestemt abonnement. Rettelser udgives fremad som en ny version på de samme URL’er og er dækket af den samme signerede SHA256SUMS. Kører du en version, der er afløst? Opgradér for at få rettelsen. |
| Rapportering af sårbarheder | security@frem.sh – koordineret offentliggørelse, detaljer på www.frem.sh/security. |
| SBOM | CycloneDX JSON på cli.frem.sh/cli/SBOM.cdx.json, pr. version på cli.frem.sh/cli/v<version>/SBOM.cdx.json. |
| Kontraktvilkår | Vilkårenes §7.5 – licens, garanti og ansvar specifikt for binærfilen. |
SBOM’en er kort, og det er hele pointen. CLI’en erklærer nul npm-afhængigheder fra tredjeparter. Den har to afhængigheder, begge vores egne: @fremverk/audit-chain, den samme hashkæde-kode, som API’et selv kører (delt i stedet for genimplementeret, så audit-verify ikke kan glide væk fra det, den verificerer), og @fremforge/tlog-verify, som kontrollerer optagelse i transparensloggen for attest-verify. Ingen af dem har egne afhængigheder; begge importerer kun Nodes indbyggede moduler, så hele overfladen fra tredjeparter i den leverede binærfil er Bun-runtimen, der indlejres ved kompilering. Fra v0.3.1 viser SBOM’en også de to førstepartspakker, markeret som vores, så den nævner alle komponenter og ikke kun tredjepartskomponenten.
SBOM’ens hash står i SHA256SUMS, så den er dækket af den samme Ed25519-signatur som binærfilerne – verificér den på samme måde (se §“Verificér Ed25519-signaturen” nedenfor – det gælder alle filer, der står i manifestet, ikke kun binærfilerne):
curl -fsSL https://cli.frem.sh/cli/SBOM.cdx.json -o SBOM.cdx.json
curl -fsSL https://trust.frem.sh/SHA256SUMS -o SHA256SUMS
grep SBOM.cdx.json SHA256SUMS | shasum -a 256 -c -CLI’en er valgfri, med én undtagelse. Alle de handlinger, den udfører, er tilgængelige via REST API’et, så er din politik ikke at køre leverandørers binærfiler, mister du ingen funktionalitet ved at springe den over. Undtagelsen er audit-verify, som genberegner din revisions-hashkæde på din maskine – det kan et API ikke gøre for dig, for hele pointen med at genberegne en hashkæde er ikke at stole på den part, der har lavet den. De rå rækker leveres af GET /orgs/{org}/audit/chain, så du kan lave regnestykket i dine egne værktøjer i stedet; det, du ikke kan, er at lade os gøre det og kalde resultatet en verifikation.
Installation
Én linje (anbefalet)
curl -sSfL https://cli.frem.sh/cli/install.sh | shInstallationsscriptet finder selv dit operativsystem (Linux eller macOS) og din arkitektur (arm64 eller x86_64), henter den matchende binærfil fra https://cli.frem.sh/cli/, henter den kanoniske SHA256SUMS fra https://trust.frem.sh/ (en separat vært med separate skriverettigheder, så et kompromis af værten for binærfiler alene ikke kan forfalske et match), verificerer SHA-256 og installerer til ~/.local/bin/fremforge eller /usr/local/bin/fremforge.
Tilsidesæt installationsstedet med FREMFORGE_INSTALL_DIR:
curl -sSfL https://cli.frem.sh/cli/install.sh | FREMFORGE_INSTALL_DIR=/opt/fremforge/bin shFastlås en bestemt version:
curl -sSfL https://cli.frem.sh/cli/install.sh | FREMFORGE_VERSION=0.1.0 shManuel download
Vil du hellere lade være med at sende et script fra nettet direkte til sh, kan du hente binærfilerne direkte. Vælg det passende par:
| OS | Arkitektur | URL |
|---|---|---|
| macOS | arm64 | https://cli.frem.sh/cli/fremforge-darwin-arm64 |
| macOS | x86_64 | https://cli.frem.sh/cli/fremforge-darwin-x64 |
| Linux | arm64 | https://cli.frem.sh/cli/fremforge-linux-arm64 |
| Linux | x86_64 | https://cli.frem.sh/cli/fremforge-linux-x64 |
| Windows | x86_64 | https://cli.frem.sh/cli/fremforge-windows-x64.exe |
Arkitektursuffikset er x64 (ikke x86_64) og arm64 – de svarer til Buns --target-betegnelser. uname -m rapporterer x86_64 på Intel/AMD, så omsæt det til x64, når du bygger URL’en i hånden (installationsscriptet på én linje gør det for dig).
Verificér mod den kanoniske hash på trust.frem.sh, før du kører binærfilen:
# 0. Map uname -m's x86_64 to the published x64 token
arch=$(uname -m); [ "$arch" = x86_64 ] && arch=x64
# 1. Download the binary
curl -fsSL https://cli.frem.sh/cli/fremforge-$(uname -s | tr A-Z a-z)-$arch \
-o fremforge
# 2. Download the canonical SHA256SUMS (separate host, separate credential)
curl -fsSL https://trust.frem.sh/SHA256SUMS -o SHA256SUMS
# 3. Verify
sha256sum --check --ignore-missing SHA256SUMS
# 4. Install
chmod +x fremforge
sudo install -m 0755 fremforge /usr/local/bin/fremforgeVerificér Ed25519-signaturen (valgfrit, anbefalet)
Ud over SHA-256-matchet er hver udgivelse signeret som en DSSE-indpakket in-toto Statement under den samme tillidsrod som fremforges SLSA-build-provenance. Verifikationen henter den offentlige tillidsrod fra www.frem.sh/.well-known/slsa-trust-root.json og kontrollerer Ed25519-signaturen på bytes i SHA256SUMS.
Brug ikke
slsa-verifier verify-artifact. Den underkommando har intet--trusted-root-flag, og den kan hverken læse fremforges JSON-tillidsrod eller en ren Ed25519-DSSE-konvolut – den forventer en bundle i Sigstore-stil. Denne side viste tidligere en sådan kommando; den kunne aldrig have kørt. Verificér i stedet direkte med værktøjer, din distribution allerede har.
SHA256SUMS.intoto.jsonl er JSON Lines: én DSSE-konvolut pr. udgivet binærfil. Verificér
hver linje, du interesserer dig for.
# Pull the trust root and the signed envelopes
curl -fsSL https://www.frem.sh/.well-known/slsa-trust-root.json -o slsa-trust-root.json
curl -fsSL https://trust.frem.sh/SHA256SUMS.intoto.jsonl -o SHA256SUMS.intoto.jsonl
# Extract the builder public key: v2, the active key since 2026-09-12. An envelope's
# .signatures[0].keyid names its key; one signed before 2026-09-12 needs ...-v1.
jq -r '.trusted_keys[] | select(.kid=="fremforge-slsa-builder-v2") | .pem' \
slsa-trust-root.json > builder.pub
# Verify every envelope: rebuild the DSSE pre-authentication encoding and check it
while read -r line; do
pt=$(printf '%s' "$line" | jq -r .payloadType)
printf '%s' "$line" | jq -r .payload | base64 -d > payload.bin
printf '%s' "$line" | jq -r '.signatures[0].sig' | base64 -d > sig.bin
{ printf 'DSSEv1 %s %s %s ' "${#pt}" "$pt" "$(wc -c < payload.bin)"; cat payload.bin; } > pae.bin
openssl pkeyutl -verify -pubin -inkey builder.pub -rawin -in pae.bin -sigfile sig.bin \
&& jq -r '.subject[] | .name + " " + .digest.sha256' payload.bin
done < SHA256SUMS.intoto.jsonlHver verificeret konvolut udskriver alle de artefakter, den dækker, og den digest, fremforge har signeret for hver af dem. Sammenlign den digest med den binærfil, du har hentet – det er sammenligningen, der er pointen; signaturen fortæller dig kun, at digesten er vores.
Tillidsroden er den samme, som bruges til build-provenance for artefakter, som din runner producerer – samme Ed25519-nøgle, samme builderId, samme opskrift på verifikation. Vi angiver ikke et SLSA-niveau; sikkerhedssiden forklarer hvorfor.
Godkendelse
CLI’en understøtter tre slags legitimationsoplysninger, som slås op i denne rækkefølge: flaget --token=…, miljøvariablen FREMFORGE_TOKEN og derefter det gemte login i ~/.config/fremforge/auth.json.
Anbefalet – login i browseren (intet at indsætte)
fremforge auth loginÅbner din browser på frem.sh, du godkender enheden, tokenet lander i ~/.config/fremforge/auth.json (tilstand 600), og alle efterfølgende kald indlæser det automatisk. Det er samme OAuth2 + PKCE-flow, som dit git push allerede bruger, så tilbagekalder du tokenet på frem.sh/user/settings/applications, tilbagekalder du adgangen for både git og CLI i ét trin.
fremforge auth status # show current login + expiry
fremforge auth logout # revoke + delete the local fileTokenet virker på både fremforges REST API (/_app/api/v1/orgs/…) OG Forgejos eget API (/api/v1/repos/…) – Forgejo accepterer sine egne OAuth-bearer-tokens direkte, og fremforges API validerer dem via introspektion mod Forgejos /api/v1/user. Samme identitet på begge flader.
CI og scripts – PAT
Til sammenhænge uden brugerinteraktion (CI-jobs, scripts, agenter) opretter du et PAT med afgrænsede scopes. Det nemmeste er at bruge selve CLI’en, når du først har logget ind interaktivt én gang (fremforge auth tokens create --name=… --scopes=… – se Opret et PAT med afgrænsede scopes til CI); eller opret et på https://frem.sh/user/settings/applications. Derefter:
export FREMFORGE_TOKEN='<your PAT>'
fremforge whoamiTilsidesæt basis-URL’en med FREMFORGE_URL= (skal være HTTPS); standard er https://frem.sh.
Kommandoer
fremforge auth login Browser-based OAuth2+PKCE login.
fremforge auth logout Revoke + delete the stored token.
fremforge auth status Show current login + expiry.
fremforge whoami Print the user the token authenticates as.
fremforge data-export start <slug> Queue a full data export for the org.
fremforge data-export list <slug> List recent export jobs.
fremforge dependency-updates enable <slug> Enable hosted Renovate for the org.
fremforge dependency-updates disable <slug> Disable hosted Renovate for the org.
fremforge dependency-updates run-now <slug> Trigger an out-of-cycle Renovate run (1/h cap).
fremforge audit-log <slug> Fetch the org audit-log slice.
[--since=DATE] [--actor=…] [--action=…] [--limit=N]
fremforge audit-verify <slug> RECOMPUTE the per-tenant audit hash chain
[--human] [--full] locally, then cross-check our own verdict.
Exit 0=ok, 2=partial, 3=broken,
4=anchor_mismatch, 5=local ok but we
disagreed. --full walks from the chain
epoch instead of the latest anchor.
fremforge sbom <owner>/<repo> <tag> Download a release SBOM.
[--format=spdx|cyclonedx]
fremforge runs <owner>/<repo> List recent CI runs (JSON; --human for a table).
[--limit=N] [--status=…] [--event=…]
fremforge runs logs <owner>/<repo> <run-id> Fetch a run's logs (text/plain, all jobs).
fremforge auth tokens create Mint a scoped PAT (printed once).
--name=N --scopes=a,b [--ttl-days=N]
fremforge auth tokens list List your PATs (--human for a table).
fremforge auth tokens revoke <token-id> Revoke a PAT.
fremforge findings <type> <slug> Security findings. type ∈ secrets |
[--status=…] [--repo=…] dependencies | signed-commits | attestations.
fremforge secrets list <slug> List org Actions/CI secret names.
fremforge secrets set <slug> <NAME> Set a secret (value via FREMFORGE_SECRET_VALUE).
fremforge secrets delete <slug> <NAME> Delete a secret.
fremforge seats list <slug> List org members + seat usage.
fremforge seats add <slug> --email=E Add a member (--username=, --full-name= optional).
fremforge seats remove <slug> <username> Remove a member.
fremforge work start <org>/<repo> Declare work before the first push (Active work).
--title=TEXT [--intent=TEXT] Prints the branch to create and related work.
[--areas=a,b] [--branch=NAME]
fremforge work list <org>/<repo> Who is building what in a repository.
[--area=AREA]
fremforge version Print the CLI version.Kør fremforge --help for den kanoniske reference, eller tilføj --human på en kommando, der understøtter det, for at få output formateret som tabel.
Eksempler
Verificér selv din revisionskæde (brug i CI)
audit-verify spørger ikke os, om din revisionslog er intakt. Den henter de rå rækker,
genberegner hver eneste hash og hvert eneste led på din maskine og sammenligner først derefter sit resultat
med vores. Exitkoden er dit resultat, ikke vores påstand – og er de to uenige, rapporteres
uenigheden i sig selv, og kommandoen fejler.
Den forskel er grunden til, at kommandoen findes. Indtil august 2026 læste den et
integrity_status-felt i et svar fra API’et og omsatte det til en exitkode, hvilket betyder, at
den part, der blev revideret, beregnede svaret, og “verifikations”-værktøjet bare videregav det. Intet, du
kunne køre, ville have opdaget et kompromitteret eller uærligt API. Nu er der noget, der gør.
export FREMFORGE_TOKEN='<your PAT, audit:read scope>'
# Human-readable, for terminals
fremforge audit-verify acme --human
# Script-friendly. The exit code reflects the LOCAL walk:
# 0 = ok
# 2 = partial — some of the chain could not be checked (see below)
# 3 = broken — a row's content or its link does not match. Investigate.
# 4 = anchor_mismatch — the WORM-anchored tip is not present in your chain
# 5 = we disagreed — your walk was clean but our verdict was not
# 6 = bad signature — the anchor's signature failed against our published key
fremforge audit-verify acme || {
echo "audit verification failed with exit code $?"
exit 1
}
# Walk the entire chain from its first row instead of just the tail since the
# last anchor. Slower and much larger; appropriate for a quarterly review.
fremforge audit-verify acme --full --humanSådan læser du resultaterne ærligt, for et verifikationsværktøj, der overdriver, er værre end intet:
partialer ikke bestået. Det betyder, at en afskæring skjulte en del af kæden, så rækkerne uden for vinduet ikke er verificeret. Vi rapportereroki det tilfælde, og CLI’en gør det bevidst ikke.- Slettede og redigerede rækker giver ikke samme hash igen, og det er bevidst. GDPR-sletning og oprydningen af
payloads efter 90 dage omskriver rækkernes indhold bagefter, så de rækker ikke længere matcher deres egen hash.
De tælles separat (
tenant_erased_count,payload_redacted_count) og er ikke manipulation. Deres led kontrolleres stadig. - WORM-ankeret er signeret, og CLI’en kontrollerer det mod en tillidsrod, den selv
henter.
audit-verifyhenterwww.frem.sh/.well-known/slsa-trust-root.jsondirekte – aldrig en nøgle fra API’et – verificerer Ed25519-DSSE-signaturen og bekræfter, at konvolutten er bundet til dette anker og ikke et andet. Exitkode 6 betyder, at signaturen blev kontrolleret og fejlede; behandl det som en hændelse.NOT CHECKED(exitkoden uændret) betyder enten, at ankeret er ældre end signeringen (2026-08-04), eller at tillidsroden ikke kunne nås fra din maskine – ingen af delene er en fejl, og CLI’en fortæller, hvilken det er.
Vil du gøre det samme uden binærfilen, så læs rækkerne fra
GET /orgs/{org}/audit/chain, og hash hver rækkes kanoniske JSON med nøglerne
i rækkefølgen action, actor, created_at_iso, fields_json, prev_hash, tenant_id. Bevar fields_json
byte for byte – lad være med at parse og serialisere det igen, ellers matcher dine digests ikke.
Se integritet i revisionskæden for den fulde garanti.
Dataeksport via selvbetjening
# Kick off
fremforge data-export start acme | jq .
# Poll
fremforge data-export list acme | jq '.[] | {id, status, created_at}'Se dataeksport for artefaktets format, opbevaring og download via signeret URL.
Afhængighedsopdateringer (hostet Renovate)
fremforge dependency-updates enable acme
fremforge dependency-updates run-now acme # 1/h rate-limit appliesSe opdateringer af afhængigheder for, hvad der tilmeldes, og hvordan du afgrænser det pr. repository.
Download af SBOM
fremforge sbom acme/api v1.4.0 --format=spdx > sbom.spdx.json
fremforge sbom acme/api v1.4.0 --format=cyclonedx > sbom.cyclonedx.jsonUdsnit af revisionsloggen
fremforge audit-log acme --since=2026-05-01 --action=push-protection-override | jq .CI-kørsler + logs
Vis de seneste kørsler, og hent derefter en kørsels fulde logs (alle jobs sat sammen) via dens globale kørsels-id:
# List the 20 most recent runs as a table
fremforge runs acme/api --human
# Script-friendly: grab the newest run id, then fetch its logs
run_id=$(fremforge runs acme/api --limit=1 | jq -r '.workflow_runs[0].id')
fremforge runs logs acme/api "$run_id"
# Tail just the failing step
fremforge runs logs acme/api "$run_id" | grep -iE "error|failed|exit code" | tail<run-id> er det globale kørsels-id, som fremforge runs viser (feltet .workflow_runs[].id) – ikke kørselsnummeret pr. workflow i webbrugerfladens URL. Log-endpointet returnerer text/plain med alle jobs i ét svar; der er ikke brug for at hente artefakter pr. job.
Opret et PAT med afgrænsede scopes til CI
Efter dit første fremforge auth login kan du oprette underordnede tokens med snævre scopes til CI uden at forlade terminalen. Tokenet udskrives én gang – gem det med det samme:
fremforge auth tokens create --name=ci-readonly --scopes=findings:read,orgs:read --ttl-days=30 \
| jq -r .token
fremforge auth tokens list --human
fremforge auth tokens revoke <token-id>Du kan kun give scopes, som dit eget token allerede har, og wildcard (*) kan ikke oprettes her.
Administrér CI-secrets
fremforge secrets list acme
# Pass the value via env (preferred — not in shell history or `ps`)
FREMFORGE_SECRET_VALUE="$(cat ./deploy-key)" fremforge secrets set acme DEPLOY_KEY
fremforge secrets delete acme OLD_TOKENBrugere / medlemmer
fremforge seats list acme --human # cap + usage + roster
fremforge seats add acme --email=jane@acme.example --full-name="Jane Doe"
fremforge seats remove acme janeTilføjer du et medlem ud over det aftalte antal brugere, får du en 409 med et link til fakturering – køb flere brugere først.
Outputformat
Som standard skriver alle kommandoer JSON til stdout, så det er nemt at bruge i scripts og pipes. Angiv --human på de kommandoer, der understøtter det (audit-verify, attest-verify, release verify, runs, auth tokens list, seats list og work), for at få et formateret resumé.
Opdatering af CLI’en
Installationsscriptet på én linje kan køres igen og igen: kører du det igen, hentes den nyeste binærfil, checksummen verificeres igen, og den gamle binærfil overskrives på stedet:
curl -sSfL https://cli.frem.sh/cli/install.sh | shOm suverænitet
CLI’ens distributionsvej er fuldt EU-suveræn:
- Binærfiler: T Cloud Public OBS (eu-de, Magdeburg / Biere, Tyskland) bag en Bunny-pull-zone, der er begrænset til PoP’er i EU.
- SHA256SUMS + DSSE-konvolut: En separat T Cloud Public OBS-bucket (
trust.frem.sh) med separate skriverettigheder; når værten for binærfiler er adskilt fra værten for integritet, kan et kompromis af den ene ikke forfalske et match mod den anden. - Tillidsrod: Statisk JSON-fil, der leveres fra
www.frem.sh(samme Bunny-routing kun i EU). - Ingen afhængighed af npm-registryet: registry.npmjs.com kører i AWS i USA; CLI’en rører det aldrig, hverken ved installation eller brug.
- Ingen afhængighed af Docker Hub: samme grund.
- Ingen Sigstore Fulcio / Rekor: Sigstores transparenslog er hostet i USA. fremforge kører sin egen Ed25519-signering + en statisk tillidsrod i stedet for at være afhængig af Fulcio.
Underdatabehandlerne på installationsvejen står i det offentlige register over underdatabehandlere og er de samme, som allerede dækker kundernes personoplysninger i henhold til databehandleraftalens bilag B.