Gå til hovedinnhold

fremforge CLI

fremforge CLI er en innpakning i én enkelt binærfil rundt det offentlige REST-API-et. Samme verb, samme autorisasjonsmodell, samme scopes. Den distribueres bare fra PoP-er i EU: ingen npm-register, ingen Docker Hub, ingen avhengighet til Sigstore Fulcio.

Støtteperiode, sikkerhetsoppdateringer og SBOM

Støtteperiode5 år fra lanseringsdatoen for hver minor-versjon. Dette er støtteperioden slik den er definert i art. 13 nr. 8 i Cyber Resilience Act (forordning (EU) 2024/2847), og den gjelder den lanserte versjonen, ikke abonnementet ditt.
SikkerhetsrettelserGratis, alltid, og aldri forbeholdt et bestemt abonnement. Rettelser leveres framover som en ny versjon på de samme URL-ene, dekket av den samme signerte SHA256SUMS. Kjører du en eldre versjon? Oppgrader for å få rettelsen.
Melde fra om en sårbarhetsecurity@frem.sh: koordinert offentliggjøring, detaljer på www.frem.sh/security.
SBOMCycloneDX JSON på cli.frem.sh/cli/SBOM.cdx.json, per versjon på cli.frem.sh/cli/v<version>/SBOM.cdx.json.
AvtalevilkårVilkår §7.5: lisens, garanti og ansvar spesifikt for binærfilen.

SBOM-en er kort, og det er hele poenget. CLI-et har null tredjepartsavhengigheter fra npm. Det har to avhengigheter, begge våre egne: @fremverk/audit-chain, den samme hashkjede-koden som API-et selv kjører (delt i stedet for skrevet på nytt, slik at audit-verify ikke kan gli fra det den kontrollerer), og @fremforge/tlog-verify, som kontrollerer inkludering i transparensloggen for attest-verify. Ingen av dem har egne avhengigheter; begge importerer bare innebygde moduler i Node, så hele tredjepartsflaten i den leverte binærfilen er Bun-runtimen som bygges inn ved kompilering. Fra v0.3.1 lister SBOM-en også de to førstepartspakkene, merket som våre, slik at den navngir alle komponenter og ikke bare tredjepartskomponenten.

SBOM-ens hash står i SHA256SUMS, så den er dekket av den samme Ed25519-signaturen som binærfilene. Kontroller den på samme måte (se §«Kontroller Ed25519-signaturen» nedenfor; den gjelder for alle filer som står i manifestet, ikke bare binærfilene):

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-et er valgfritt, med ett unntak. Alle handlinger det utfører, er tilgjengelige gjennom REST-API-et, så hvis policyen din er å ikke kjøre binærfiler fra leverandører, mister du ingen funksjonalitet ved å la være. Unntaket er audit-verify, som beregner revisjonsloggens hashkjede på nytt på din maskin. Det kan ikke et API gjøre for deg, for hele poenget med å beregne en hashkjede på nytt er å ikke stole på den parten som laget den. De rå radene leveres av GET /orgs/{org}/audit/chain, så du kan gjøre utregningen i dine egne verktøy i stedet. Det du ikke kan, er å la oss gjøre den og kalle resultatet en kontroll.

Installasjon

Én linje (anbefalt)

curl -sSfL https://cli.frem.sh/cli/install.sh | sh

Installasjonsprogrammet finner selv operativsystemet ditt (Linux eller macOS) og arkitekturen (arm64 eller x86_64), laster ned den tilsvarende binærfilen fra https://cli.frem.sh/cli/, laster ned den kanoniske SHA256SUMS fra https://trust.frem.sh/ (en egen vert med egen skrivelegitimasjon, slik at en kompromittert binærfilvert alene ikke kan forfalske et samsvar), kontrollerer SHA-256 og installerer til ~/.local/bin/fremforge eller /usr/local/bin/fremforge.

Overstyr installasjonsstedet med FREMFORGE_INSTALL_DIR:

curl -sSfL https://cli.frem.sh/cli/install.sh | FREMFORGE_INSTALL_DIR=/opt/fremforge/bin sh

Lås til en bestemt versjon:

curl -sSfL https://cli.frem.sh/cli/install.sh | FREMFORGE_VERSION=0.1.0 sh

Manuell nedlasting

Hvis du helst ikke vil sende et eksternt skript rett til sh, kan du hente binærfilene direkte. Velg riktig kombinasjon:

OSArkitekturURL
macOSarm64https://cli.frem.sh/cli/fremforge-darwin-arm64
macOSx86_64https://cli.frem.sh/cli/fremforge-darwin-x64
Linuxarm64https://cli.frem.sh/cli/fremforge-linux-arm64
Linuxx86_64https://cli.frem.sh/cli/fremforge-linux-x64
Windowsx86_64https://cli.frem.sh/cli/fremforge-windows-x64.exe

Arkitektursuffikset er x64 (ikke x86_64) og arm64; de samsvarer med Buns --target-verdier. uname -m rapporterer x86_64 på Intel/AMD, så gjør det om til x64 når du bygger URL-en for hånd (installasjonsprogrammet på én linje gjør dette for deg).

Kontroller mot den kanoniske hashen på trust.frem.sh før du kjø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/fremforge

Kontroller Ed25519-signaturen (valgfritt, anbefalt)

I tillegg til SHA-256-samsvaret signeres hver versjon som et in-toto Statement pakket i DSSE, under den samme tillitsroten som fremforges SLSA-byggeproveniens. Kontrollen laster ned den offentlige tillitsroten fra www.frem.sh/.well-known/slsa-trust-root.json og kontrollerer Ed25519-signaturen på bytene i SHA256SUMS.

Ikke bruk slsa-verifier verify-artifact. Den underkommandoen har ikke noe --trusted-root-flagg, og den kan ikke lese fremforges JSON-tillitsrot eller en ren Ed25519-DSSE-konvolutt; den forventer en bundle i Sigstore-stil. Denne siden viste tidligere en slik kommando; den kunne aldri ha fungert. Kontroller direkte i stedet, med verktøy distribusjonen din allerede har.

SHA256SUMS.intoto.jsonl er JSON Lines: én DSSE-konvolutt per publisert binærfil. Kontroller hver linje du bryr deg om.

# 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.jsonl

Hver kontrollerte konvolutt skriver ut alle artefaktene den dekker, og digesten fremforge signerte for hver av dem. Sammenlign den digesten med binærfilen du lastet ned. Det er den sammenligningen som er poenget; signaturen forteller deg bare at digesten er vår.

Tillitsroten er den samme som brukes for byggeproveniens på artefakter runneren din produserer: samme Ed25519-nøkkel, samme builderId, samme framgangsmåte for kontroll. Vi oppgir ikke noe SLSA-nivå; sikkerhetssiden forklarer hvorfor.

Autentisering

CLI-et støtter tre typer legitimasjon, som brukes i denne rekkefølgen: flagget --token=…, miljøvariabelen FREMFORGE_TOKEN, og deretter den lagrede innloggingen i ~/.config/fremforge/auth.json.

Anbefalt: innlogging i nettleseren (ingen innliming)

fremforge auth login

Åpner frem.sh i nettleseren din, du godkjenner enheten, tokenet havner i ~/.config/fremforge/auth.json (modus 600), og alle senere kjøringer laster det automatisk. Det er den samme OAuth2 + PKCE-flyten som git push allerede bruker, så når du tilbakekaller tokenet på frem.sh/user/settings/applications, tilbakekaller du tilgangen for både git og CLI i ett steg.

fremforge auth status      # show current login + expiry
fremforge auth logout      # revoke + delete the local file

Tokenet fungerer mot både fremforges REST-API (/_app/api/v1/orgs/…) OG Forgejos eget API (/api/v1/repos/…). Forgejo godtar sine egne OAuth-bearer-tokener direkte, og fremforge-API-et kontrollerer dem via introspeksjon mot Forgejos /api/v1/user. Samme identitet på begge flatene.

CI / skriptbruk: PAT

For sammenhenger som ikke er interaktive (CI-jobber, skript, agenter) oppretter du et PAT med begrensede scopes. Det enkleste er å bruke CLI-et selv når du har logget inn interaktivt én gang (fremforge auth tokens create --name=… --scopes=…; se Opprett et PAT med begrenset scope for CI), eller du kan opprette et på https://frem.sh/user/settings/applications. Deretter:

export FREMFORGE_TOKEN='<your PAT>'
fremforge whoami

Overstyr grunn-URL-en med FREMFORGE_URL= (må 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.

Kjør fremforge --help for den kanoniske referansen, eller legg til --human på kommandoer som støtter det, for å få utdata formatert som tabell.

Eksempler

Kontroller revisjonskjeden selv (bruk i CI)

audit-verify spør ikke oss om revisjonsloggen din er intakt. Den laster ned de rå radene, beregner hver hash og hver lenke på nytt på din maskin, og sammenligner først deretter resultatet med vårt. Avslutningskoden er ditt resultat, ikke vår påstand. Hvis de to er uenige, rapporteres selve uenigheten, og kommandoen feiler.

Det skillet er grunnen til at kommandoen finnes. Fram til august 2026 leste den feltet integrity_status fra et API-svar og gjorde det om til en avslutningskode. Det betyr at parten som ble revidert, regnet ut svaret, og «kontroll»-verktøyet bare videreformidlet det. Ingenting du kunne kjøre, ville ha avslørt et kompromittert eller uærlig API. Nå finnes det noe som gjør det.

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 --human

Slik leser du resultatene ærlig, for et kontrollverktøy som overdriver, er verre enn ingen:

  • partial er ikke bestått. Det betyr at en avkorting skjulte deler av kjeden, så radene utenfor vinduet er ikke kontrollert. Vi rapporterer ok i det tilfellet, men CLI-et gjør det bevisst ikke.
  • Slettede og sladdede rader gir ikke samme hash, og det er tilsiktet. GDPR-sletting og 90-dagers-ryddingen av nyttelast skriver om radinnholdet i ettertid, så disse radene samsvarer ikke lenger med sin egen hash. De telles for seg (tenant_erased_count, payload_redacted_count) og er ikke manipulering. Lenkene deres kontrolleres fortsatt.
  • WORM-ankeret er signert, og CLI-et kontrollerer det mot en tillitsrot det henter selv. audit-verify henter www.frem.sh/.well-known/slsa-trust-root.json direkte (aldri en nøkkel fra API-et), kontrollerer Ed25519-DSSE-signaturen og bekrefter at konvolutten er knyttet til dette ankeret og ikke et annet. Avslutningskode 6 betyr at signaturen ble kontrollert og feilet; behandle det som en hendelse. NOT CHECKED (avslutningskoden endres ikke) betyr enten at ankeret er eldre enn signeringen (2026-08-04), eller at tillitsroten ikke kunne nås fra maskinen din. Ingen av delene er en feil, og CLI-et sier hvilken det er.

For å gjøre det samme uten binærfilen leser du radene fra GET /orgs/{org}/audit/chain og hasher den kanoniske JSON-en for hver rad med nøklene i rekkefølgen action, actor, created_at_iso, fields_json, prev_hash, tenant_id. Behold fields_json byte for byte: ikke parse og serialiser den på nytt, ellers vil ikke digestene dine samsvare.

Se integritet i revisjonskjeden for den fullstendige garantien.

Dataeksport med selvbetjening

# Kick off
fremforge data-export start acme | jq .

# Poll
fremforge data-export list acme | jq '.[] | {id, status, created_at}'

Se dataeksport for artefaktformatet, oppbevaringen og nedlastingsflyten med signert URL.

Avhengighetsoppdateringer (hostet Renovate)

fremforge dependency-updates enable acme
fremforge dependency-updates run-now acme   # 1/h rate-limit applies

Se avhengighetsoppdateringer for hva som tas med, og hvordan du avgrenser det per repo.

Nedlasting av SBOM

fremforge sbom acme/api v1.4.0 --format=spdx > sbom.spdx.json
fremforge sbom acme/api v1.4.0 --format=cyclonedx > sbom.cyclonedx.json

Utdrag av revisjonsloggen

fremforge audit-log acme --since=2026-05-01 --action=push-protection-override | jq .

CI-kjøringer + logger

List opp de siste kjøringene, og hent deretter alle loggene for en kjøring (alle jobber satt sammen) med den globale kjørings-ID-en:

# 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 den globale kjørings-ID-en som fremforge runs viser (feltet .workflow_runs[].id), ikke kjøringsnummeret per workflow i URL-en i nettgrensesnittet. Logg-endepunktet returnerer text/plain med alle jobber i ett svar; du trenger ikke laste ned artefakter per jobb.

Opprett et PAT med begrenset scope for CI

Etter den første fremforge auth login kan du opprette undertokener med smale scopes for CI uten å forlate terminalen. Tokenet skrives ut én gang, så ta vare på det med en gang:

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 bare gi scopes som ditt eget token allerede har, og jokertegnet (*) kan ikke brukes her.

Administrer 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_TOKEN

Brukere / 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 jane

Legger du til et medlem utover det avtalte antallet brukere, returneres 409 med en lenke til fakturering. Kjøp flere brukere først.

Utdataformat

Som standard skriver alle kommandoer JSON til stdout, egnet for skript og pipes. Legg til --human på kommandoene som støtter det (audit-verify, attest-verify, release verify, runs, auth tokens list, seats list og work) for et formatert sammendrag.

Oppdatere CLI-et

Installasjonsprogrammet på én linje er idempotent: kjører du det igjen, henter det den nyeste binærfilen, kontrollerer sjekksummen på nytt og overskriver den gamle binærfilen på stedet:

curl -sSfL https://cli.frem.sh/cli/install.sh | sh

Om suverenitet

Distribusjonsveien for CLI-et er fullt ut EU-suveren:

  • Binærfiler: T Cloud Public OBS (eu-de, Magdeburg / Biere, Tyskland), bak en Bunny pull-sone som er begrenset til PoP-er i EU.
  • SHA256SUMS + DSSE-konvolutt: en egen T Cloud Public OBS-bøtte (trust.frem.sh) med egen skrivelegitimasjon. Når binærfilverten er skilt fra integritetsverten, kan et kompromiss av den ene ikke forfalske et samsvar mot den andre.
  • Tillitsrot: en statisk JSON-fil som leveres fra www.frem.sh (samme ruting via Bunny bare i EU).
  • Ingen avhengighet til npm-registeret: registry.npmjs.com kjører i AWS i USA; CLI-et berører det aldri, verken ved installasjon eller bruk.
  • Ingen avhengighet til Docker Hub: av samme grunn.
  • Ingen Sigstore Fulcio / Rekor: Sigstores transparenslogg driftes i USA. fremforge kjører sin egen Ed25519-signerer og en statisk tillitsrot i stedet for å være avhengig av Fulcio.

Underdatabehandlerne som er involvert i installasjonsveien, står i det offentlige registeret over underdatabehandlere og er de samme som allerede dekker kundens personopplysninger i henhold til DPA-ens vedlegg B.