Gå til hovedinnhold

Bruke fremforge-registre fra GitHub Actions og OpenShift

Kildekoden og CI-en din kan bli værende på GitHub, og klyngene dine på OpenShift, mens pakkene ligger i fremforge-organisasjonen din. Begge når registeret gjennom en registerrobot: en innlogging som tilhører organisasjonen, ikke en person.

En registerrobot:

  • leser, eller leser og publiserer, pakkene i én organisasjon, av alle pakketyper;
  • kan publisere, men ikke slette: sletting av en pakkeversjon, en fil, en container-tag eller et image avvises med 403 og registreres i revisjonsloggen som registry_robot.delete_refused. Sletting er forbeholdt en administrator i organisasjonen, i nettgrensesnittet eller med egen innlogging;
  • kan ikke lese kode, åpne nettgrensesnittet eller nå noen annen organisasjon;
  • er ikke en betalt bruker;
  • har en utløpstid på høyst 365 dager, og etter det slutter roboten og hvert token den har, å virke;
  • er oppført, med hvem som opprettet den, under Organisasjonsadministrasjon → Sikkerhet → Tilgang → Registerroboter, og hver opprettelse, rotasjon, sletting og avvist pakkesletting står i organisasjonens revisjonslogg.

I fremforges egen CI trenger du ingen: en Forgejo Actions-jobb har allerede et token for pakkene i sin egen organisasjon. Se Publisere fra Forgejo Actions.

Opprette en robot

I konsollen: Organisasjonsadministrasjon → Sikkerhet → Tilgang → Registerroboter → Opprett en robot. Velg Lese pakker for en pull secret og Lese og publisere pakker (kan ikke slette) for en CI-jobb som publiserer.

Siden viser deretter robotens brukernavn og token én gang. Kopier begge; tokenet vises ikke igjen. Hvis det går tapt, utsteder Roter token et nytt og tilbakekaller det gamle med en gang.

Eller med API-et, med et API-token som har scopet policy:write:

curl -sS -X POST "https://frem.sh/_app/api/v1/orgs/<org>/registry-robots" \
  -H "Authorization: Bearer $FREMFORGE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "github-publish", "access": "write", "expires_in_days": 90}'

Svaret inneholder username og token. access er read eller write, og expires_in_days er 1 til 365 (standard 90). Roter med POST /orgs/<org>/registry-robots/<id>/rotate, eventuelt med {"expires_in_days": n} for å sette en ny utløpstid, og slett med DELETE /orgs/<org>/registry-robots/<id>.

Brukernavnet har formen <org prefix>-fremforge-bot-reg-<8 hex characters>. Prefikset er navnet på organisasjonen din, forkortet ved behov slik at brukernavnet ikke blir lengre enn 40 tegn: en robot i acme-infrastructure-team får et navn som acme-infrastr-fremforge-bot-reg-1a2b3c4d. Kopier brukernavnet siden eller API-et viser, i stedet for å sette det sammen av organisasjonsnavnet. Hver klient nedenfor tar det som brukernavn og tokenet som passord.

GitHub Actions

Lagre roboten i GitHub-repositoryet eller -organisasjonen: brukernavnet som variabelen FREMFORGE_REGISTRY_USER og tokenet som secreten FREMFORGE_REGISTRY_TOKEN. Sett ORG til fremforge-organisasjonen din.

Containerimager

- name: Push to fremforge
  env:
    FREMFORGE_USER: ${{ vars.FREMFORGE_REGISTRY_USER }}
    FREMFORGE_TOKEN: ${{ secrets.FREMFORGE_REGISTRY_TOKEN }}
    ORG: <org>
  run: |
    echo "$FREMFORGE_TOKEN" | docker login frem.sh -u "$FREMFORGE_USER" --password-stdin
    docker build -t "frem.sh/$ORG/app:$GITHUB_SHA" .
    docker push "frem.sh/$ORG/app:$GITHUB_SHA"

Pull på samme måte, med docker pull frem.sh/<org>/app:<tag>. En pushet tag kan ikke overskrives når uforanderlige utgivelser er slått på for organisasjonen.

npm

npm sender et token bare til en register-URL som stemmer nøyaktig, så gi den scopets register og tokenet for den URL-en:

- name: Publish to fremforge
  env:
    FREMFORGE_TOKEN: ${{ secrets.FREMFORGE_REGISTRY_TOKEN }}
    ORG: <org>
  run: |
    printf '@<scope>:registry=https://frem.sh/api/packages/%s/npm/\n//frem.sh/api/packages/%s/npm/:_authToken=%s\n' \
      "$ORG" "$ORG" "$FREMFORGE_TOKEN" > .npmrc
    npm publish

Den samme .npmrc installerer @<scope>/…-pakker med npm install.

PyPI

- name: Publish to fremforge
  env:
    FREMFORGE_USER: ${{ vars.FREMFORGE_REGISTRY_USER }}
    FREMFORGE_TOKEN: ${{ secrets.FREMFORGE_REGISTRY_TOKEN }}
    ORG: <org>
  run: |
    python -m pip install twine
    twine upload --repository-url "https://frem.sh/api/packages/$ORG/pypi" \
      -u "$FREMFORGE_USER" -p "$FREMFORGE_TOKEN" dist/*

Installer med robotens legitimasjon i indeks-URL-en:

pip install --index-url "https://$FREMFORGE_USER:$FREMFORGE_TOKEN@frem.sh/api/packages/$ORG/pypi/simple/" <package>

Maven

Legg til en server med den ID-en pom.xml bruker for fremforge-repositoryet, og les roboten fra miljøet:

<settings>
  <servers>
    <server>
      <id>fremforge</id>
      <username>${env.FREMFORGE_USER}</username>
      <password>${env.FREMFORGE_TOKEN}</password>
    </server>
  </servers>
</settings>
- name: Publish to fremforge
  env:
    FREMFORGE_USER: ${{ vars.FREMFORGE_REGISTRY_USER }}
    FREMFORGE_TOKEN: ${{ secrets.FREMFORGE_REGISTRY_TOKEN }}
  run: mvn --batch-mode -s .ci/settings.xml deploy

med repositoryet i pom.xml som under Maven: https://frem.sh/api/packages/<org>/maven.

Uten lagret secret: GitHubs OIDC-token

En robot kan også godta GitHub Actions’ eget OIDC-token i stedet for et lagret registertoken. Gi roboten den numeriske ID-en til GitHub-organisasjonen din (eller brukeren), og eventuelt ett repository, under GitHub Actions på roboten, eller med github_repository_owner_id og github_repository i API-et. En jobb hos den eieren ber da om OIDC-tokenet sitt med målgruppen https://frem.sh/<org> (permissions: id-token: write) og bytter det på POST https://frem.sh/_app/api/v1/registry/oidc-token (org, robot, id_token) mot robotens brukernavn og et token som varer i 1 time. Byttet er beskrevet i API-referansen under Registerroboter; hvert token det utsteder, står i revisjonsloggen med repository, ref og kjørings-ID.

SBOM-er

SBOM-er går til fremforge-API-et, ikke til registeret, med et API-token som har scopet sboms:write. Se Last opp SBOM-er fra GitHub Actions.

OpenShift og Kubernetes

Pull imager fra fremforge med en robot med lesetilgang som image pull secret:

kubectl create secret docker-registry frem-sh \
  --docker-server=frem.sh \
  --docker-username=<robot username> \
  --docker-password=<robot token> \
  --namespace=<namespace>

og vis til den fra arbeidslasten:

spec:
  imagePullSecrets:
    - name: frem-sh
  containers:
    - name: app
      image: frem.sh/<org>/app:1.4.2

OpenShift leser den samme kubernetes.io/dockerconfigjson-secreten. Roter roboten før den utløper, og erstatt secreten med en som er laget av det nye tokenet.

Verter som må slippes gjennom en brannmur for utgående trafikk

VertPortBrukes til
frem.sh443Alle forespørsler til registeret: innlogginger, indekser, opplastinger og manifester og lag for containerimager
obs.eu-de.otc.t-systems.com443Nedlasting av andre pakkefiler enn containerimager: npm-tarballer, wheels, JAR-filer og så videre

En nedlasting av en annen pakkefil enn et containerimage svarer med 303 og en kortlivet signert lenke til filen i objektlageret på obs.eu-de.otc.t-systems.com, som klienten følger. Det navnet er en CNAME for obs.lz01.eu-de.otc.t-systems.com, så en brannmur som sjekker hvert navn i kjeden, trenger begge. Lag i containerimager leveres av frem.sh selv.

frem.sh leveres gjennom et CDN, så adressene endres: tillat den med navn, ikke med IP-adresse.

Avhengighetsproxy

En robot med lesetilgang puller også gjennom organisasjonens avhengighetsproxy (Docker Hub, npm, PyPI og de andre offentlige registrene), med det samme tokenet. Se Autentisering.