Gå til hovedinnhold

OIDC-tokenføderasjon

Hver CI-jobb i fremforge kan få et kortlivet OIDC-token: en RS256-signert JWT utstedt av fremforges runner-OIDC-utsteder. Skyleverandører (T Cloud Public, AWS, Azure, GCP) kan settes opp til å stole på dette tokenet og bytte det mot avgrenset, tidsbegrenset legitimasjon. Ingen utrullingsnøkler lagret som secrets, ingenting å rotere etter en tidsplan.

Referanse for claims

Runner-JWT-en fra fremforge inneholder disse claimene:

ClaimVerdi / formatEksempel
isshttps://frem.sh/_app/runner/oidc (én global utsteder for alle organisasjoner)https://frem.sh/_app/runner/oidc
subrepo:<org>/<repo>:ref:refs/heads/<branch>repo:acme/api:ref:refs/heads/main
audKan konfigureres; standard https://frem.shhttps://frem.sh
repository_ownerOrganisasjonens slug – lås betingelsene i tillitspolicyen til denne claimen for isolasjon per organisasjon under den delte utstederenacme
repository<org>/<repo>acme/api
refFull git-refrefs/heads/main
shaCommit-SHAa1b2c3d4...
environmentNavnet på utrullingsmiljøet (hvis jobben deklarerer et)production
job_workflow_refSti og ref for workflow-filenacme/api/.forgejo/workflows/deploy.yaml@refs/heads/main
deployer_group(Bare T Cloud Public) navnet på IAM-gruppen den fødererte brukeren skal knyttes til, satt per arbeidslast av fremforge – se Agency-tillit i T Cloud Publicacme-prod-deployers

sub-claimen er det primære tillitsankeret i de fleste tillitspolicyer hos leverandørene. Den identifiserer kombinasjonen av organisasjon, repository og branch entydig. For isolasjon per organisasjon i delte skykontoer legger du til en betingelse som låser på repository_owner (organisasjonens slug) – samme mønster som tillit i GitHub Actions på token.actions.githubusercontent.com. fremforge bruker én global utsteder for alle organisasjoner; isolasjonen håndheves på claim-nivå, ikke på nivået for utsteder-URL-en.

Hente tokenet i en workflow

Legg til id-token: write i jobbens permissions-blokk. Runneren fyller da miljøvariablene ACTIONS_ID_TOKEN_REQUEST_TOKEN og ACTIONS_ID_TOKEN_REQUEST_URL, som du bruker til å hente selve JWT-en:

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: fremforge
    steps:
      - name: Get OIDC token
        run: |
          TOKEN=$(curl -sS \
            -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://frem.sh" \
            | jq -r .value)
          echo "TOKEN=$TOKEN" >> $GITHUB_ENV

De fleste leverandørspesifikke stegene (AWS, Azure, GCP) henter tokenet internt. Du trenger bare å skrive den manuelle hentingen over hvis du trenger den rå JWT-en til en egen tillitsflyt.

Agency-tillit i T Cloud Public

IAM-føderasjonsmodellen i T Cloud Public er avledet fra OpenStack: du registrerer OIDC-utstederen som en identitetsleverandør, knytter til en mapping som oversetter claims i ID-tokenet til lokale IAM-grupper, og bytter deretter runnerens ID-token på OTCs OS-FEDERATION-endepunkt mot et Keystone-token i T Cloud Public som er avgrenset til gruppene mappingen knyttet til.

fremforge bruker claim-styrt gruppebinding (samme form som AWS Identity Center, GCP Workload Identity Federation og Azure Federated Credentials bruker): runnerens ID-token har en deployer_group-claim per arbeidslast, og OTC-mappingen din leser den claimen ordrett. Én mapping-regel dekker hele flåten – å legge til en arbeidslast rører ikke IAM-oppsettet ditt i det hele tatt.

Steg 1: opprett en OpenID Connect-identitetsleverandør

I konsollen til T Cloud Public går du til IAM → Identity Providers → Create Identity Provider.

  • Type: Virtual user
  • Protokoll: OpenID Connect
  • Tilgangstype: Programmatic access (program)

Etter opprettingen setter du opp OIDC-innstillingene:

  • Identity provider URL (idp_url): https://frem.sh/_app/runner/oidc (én global utsteder; matcher iss-claimen i alle ID-tokener fra fremforges runnere).
  • Client ID (client_id): https://frem.sh, må være lik aud-claimen i runnerens ID-token.
  • Signing key (signing_key): lim inn JSON-en med JWKS-offentlignøkkelen. Hent den én gang fra https://frem.sh/_app/runner/oidc/.well-known/openid-configuration → jwks_uri og kopier JSON-en. T Cloud Public henter ikke JWKS automatisk, så lim den inn på nytt når fremforge kunngjør en JWKS-rotasjon (kunngjøres på trust-siden; rotasjoner skjer høyst én gang i året).

Steg 2: legg til den claim-styrte mapping-regelen

Én regel, som skalerer for et hvilket som helst antall arbeidslaster:

[
  {
    "local": [
      { "user":  { "name": "fremforge-{0}-{1}" } },
      { "group": { "name": "{2}" } }
    ],
    "remote": [
      { "type": "repository_owner" },
      { "type": "repository" },
      { "type": "deployer_group" }
    ]
  }
]

Tillitsmodellen:

  • Den fødererte brukeren blir med i den IAM-gruppen som deployer_group-claimen i ID-tokenet oppgir ({2} setter inn verdien av claimen ordrett).
  • Claimen settes av fremforges runner-OIDC-utsteder ut fra tilordningen arbeidslast→gruppe som du avtaler ved oppstart. Den kan bare oppgis for arbeidslaster vi har en rad for, og bare for den ref-en raden låser (standard: main-branchen).
  • Samme låsing av JWT-signaturen, samme filtrering på iss + aud + repository_owner – det er bare beslutningen arbeidslast→gruppe som er flyttet fra «N mapping-regler i OTC» til «én claim utstedt av fremforge».

Steg 3: opprett IAM-gruppene arbeidslastene skal anta

Opprett én gruppe per utrullingsprofil du vil eksponere (f.eks. acme-prod-deployers, acme-staging-deployers). Knytt til de prosjekt- og EPS-rollene hver profil trenger – de er 100 % dine; fremforge rører aldri gruppekonfigurasjonen din. Gruppenavnene skal stemme med verdien fremforge legger i deployer_group-claimen, avtalt ved oppstart.

Steg 4: fortell fremforge hvilken arbeidslast som bruker hvilken gruppe

E-post eller kall til admin-API-et: «Repo acme/api, main-branch → gruppe acme-prod-deployers.» fremforge setter inn en rad i tabellen runner_deployer_groups. Fra neste workflow-kjøring har ID-tokener for den arbeidslasten deployer_group=acme-prod-deployers, og mappingen din knytter den fødererte brukeren til den gruppen.

Å legge til et nytt repository er bare enda en e-post – IAM-oppsettet i OTC forblir uendret.

Valgfritt: opprett en agency som skal antas

De fleste oppsett hopper over dette: gruppebindingen fra steg 2 er nok. Bruker du et mønster med antatte roller, oppretter du en agency (IAM → Agencies → Create Agency) med følgende:

  • Agency type: Account (skytjeneste fra en annen T Cloud Public-konto gjelder ikke her).
  • Delegated party: velg OpenID Connect-identitetsleverandøren du opprettet i steg 1.
  • Permissions: knytt til policyene CI-jobben trenger (f.eks. OBS Administrator avgrenset til arbeidslastens OBS-bøtte, eller CCE FullAccess avgrenset til arbeidslastens prosjekt).

Noter navnet på agencyen og prosjektet du avgrenser den til.

Steg 5: bruk legitimasjonen i en workflow

Runneren henter et ID-token, bytter det på OTCs OS-FEDERATION-endepunkt mot et uavgrenset Keystone-token og bytter deretter til et token avgrenset til et prosjekt. Både CLI-en for T Cloud Public (otc) og OpenTofu med opentelekomcloud-provideren godtar OS_AUTH_TOKEN fra miljøet uten videre konfigurasjon.

# Forgejo-specific: opts the task into the OIDC envelope.
# Forgejo jobparser only reads this top-level key — it does NOT
# auto-derive from `permissions: id-token: write` like GitHub does.
enable-openid-connect: true

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: fremforge
    steps:
      - name: Exchange OIDC for T Cloud Public token
        run: |
          # 1. Fetch the runner OIDC JWT
          JWT=$(curl -sS --fail \
            -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://frem.sh" \
            | jq -r .value)

          # 2. Exchange at OTC's OS-FEDERATION endpoint (NOT /v3/auth/tokens
          #    with methods=["id_token"] — OTC's Keystone fork doesn't support
          #    that. Use the IdP-scoped URL with Bearer header instead).
          UNSCOPED=$(curl -sS -i \
            -X POST -H "Authorization: Bearer $JWT" \
            "https://iam.eu-de.otc.t-systems.com/v3/OS-FEDERATION/identity_providers/fremforge-runner-oidc/protocols/oidc/auth" \
            | awk 'BEGIN{IGNORECASE=1} /^x-subject-token:/ { sub(/^x-subject-token:[ \t]*/,"",$0); gsub(/\r/,"",$0); print }')

          # 3. Swap for project-scoped (the unscoped token gives you no
          #    permissions on its own; you need a project scope to do anything).
          SCOPED=$(curl -sS -i -X POST \
            -H "Content-Type: application/json" \
            -d "{\"auth\":{\"identity\":{\"methods\":[\"token\"],\"token\":{\"id\":\"$UNSCOPED\"}},\"scope\":{\"project\":{\"name\":\"eu-de\"}}}}" \
            "https://iam.eu-de.otc.t-systems.com/v3/auth/tokens" \
            | awk 'BEGIN{IGNORECASE=1} /^x-subject-token:/ { sub(/^x-subject-token:[ \t]*/,"",$0); gsub(/\r/,"",$0); print }')

          echo "::add-mask::$SCOPED"
          echo "OS_AUTH_TOKEN=$SCOPED" >> $GITHUB_ENV

      - name: Tofu plan
        run: tofu plan
        # opentelekomcloud provider picks up OS_AUTH_TOKEN automatically

Merknader om det spesifikke for T Cloud Public

  • OTC bruker /v3/OS-FEDERATION/identity_providers/{idp}/protocols/oidc/auth, IKKE /v3/auth/tokens med methods=["id_token"]. Autentiseringsmetoden fra OpenStack upstream returnerer 400 "Unsupported method: id_token" på OTCs Keystone-fork. Verifisert i praksis og i henhold til OTCs API-dokumentasjon iam_13_0606.
  • OTC roterer ikke JWKS automatisk. Du limer inn signeringsnøkkelen én gang når leverandøren opprettes, og limer den inn på nytt når fremforge kunngjør en rotasjon. AWS / Azure / GCP henter alle automatisk fra discovery-dokumentet – bare T Cloud Public krever at du limer inn eksplisitt.
  • Det utvekslede tokenet ligger i svarheaderen X-Subject-Token, ikke i bodyen – konvensjon i OpenStack Keystone.
  • Avgrensningen av arbeidslasten kommer fra deployer_group-claimen (mappingen knytter den fødererte brukeren til den gruppen) OG prosjektrollene på den gruppen. Claimen hindrer at feil arbeidslast antar feil gruppe; rollen begrenser hva gruppen kan gjøre.
  • Valgfritt: agencies for mønstre med antatte roller støttes også, men de fleste brukstilfeller trenger dem ikke – gruppebindingen fra steg 2 er nok.

AWS IAM

Steg 1: opprett en OIDC-identitetsleverandør

I AWS-konsollen går du til IAM → Identity providers → Add provider.

  • Provider type: OpenID Connect
  • Provider URL: https://frem.sh/_app/runner/oidc (én global utsteder; filtrering per organisasjon gjøres i betingelsen i tillitspolicyen, ikke i leverandør-URL-en)
  • Audience: https://frem.sh

AWS henter JWKS fra discovery-dokumentet for å verifisere tokener.

Steg 2: opprett en IAM-rolle med en tillitspolicy for web identity

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<account-id>:oidc-provider/frem.sh/_app/runner/oidc"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "frem.sh/_app/runner/oidc:aud": "https://frem.sh",
          "frem.sh/_app/runner/oidc:repository_owner": "<your-org>",
          "frem.sh/_app/runner/oidc:sub": "repo:<your-org>/<your-repo>:ref:refs/heads/main"
        }
      }
    }
  ]
}

Knytt tillatelsene CI-jobben trenger, til denne rollen (f.eks. AmazonS3FullAccess, AmazonECRPowerUser).

Steg 3: bruk i en workflow

Bruk den offisielle actionen aws-actions/configure-aws-credentials:

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: fremforge
    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::<account-id>:role/<role-name>
          aws-region: eu-central-1
          audience: https://frem.sh

      - name: Deploy
        run: aws s3 sync ./dist s3://my-bucket/

Actionen håndterer hentingen av tokenet, kallet til sts:AssumeRoleWithWebIdentity og innleggingen av legitimasjonen automatisk.

Azure (Entra Workload Identity)

Steg 1: opprett fødererte legitimasjoner på en app-registrering

  1. I Azure-portalen går du til Entra ID → App registrations → <your app> → Certificates & secrets → Federated credentials.
  2. Klikk på Add credential.
  3. Scenario: Other issuer.
  4. Fyll inn:
    • Issuer: https://frem.sh/_app/runner/oidc (én global utsteder; isolasjon per organisasjon håndheves av Subject identifier nedenfor)
    • Subject identifier: repo:<your-org>/<your-repo>:ref:refs/heads/main
    • Audience: https://frem.sh
  5. Lagre.

Steg 2: bruk i en workflow

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: fremforge
    steps:
      - uses: actions/checkout@v4

      - name: Get OIDC token
        run: |
          TOKEN=$(curl -sS \
            -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
            "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://frem.sh" \
            | jq -r .value)
          echo "OIDC_TOKEN=$TOKEN" >> $GITHUB_ENV

      - name: Azure login via federated token
        run: |
          az login \
            --service-principal \
            --tenant <tenant-id> \
            --client-id <client-id> \
            --federated-token "$OIDC_TOKEN"

      - name: Deploy
        run: az webapp deploy --resource-group my-rg --name my-app --src-path ./dist

Klient-ID-en til app-registreringen og Entra-tenant-ID-en din er ikke hemmeligheter. De kan lagres som vanlige workflow-variabler. Bare OIDC-tokenet er sensitivt, og det utløper når jobben er ferdig.

GCP Workload Identity

Steg 1: opprett en Workload Identity-pool og en OIDC-leverandør

# Create the pool
gcloud iam workload-identity-pools create fremforge-pool \
  --location global \
  --display-name "fremforge CI"

# Create the OIDC provider inside the pool
gcloud iam workload-identity-pools providers create-oidc fremforge-provider \
  --location global \
  --workload-identity-pool fremforge-pool \
  --issuer-uri "https://frem.sh/_app/runner/oidc" \
  --allowed-audiences "https://frem.sh" \
  --attribute-mapping "google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner"

Steg 2: gi tillatelse til å opptre som tjenestekontoen

# Allow the pool to impersonate a service account, scoped by sub claim
gcloud iam service-accounts add-iam-policy-binding <sa>@<project>.iam.gserviceaccount.com \
  --role roles/iam.workloadIdentityUser \
  --member "principalSet://iam.googleapis.com/projects/<project-number>/locations/global/workloadIdentityPools/fremforge-pool/attribute.sub/repo:<your-org>/<your-repo>:ref:refs/heads/main"

Steg 3: bruk i en workflow

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: fremforge
    steps:
      - uses: actions/checkout@v4

      - name: Authenticate to GCP via OIDC
        uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: projects/<project-number>/locations/global/workloadIdentityPools/fremforge-pool/providers/fremforge-provider
          service_account: <sa>@<project>.iam.gserviceaccount.com
          audience: https://frem.sh

      - name: Deploy
        run: gcloud run deploy my-service --image gcr.io/my-project/my-image

Actionen google-github-actions/auth virker på fremforges runnere. Den bruker den samme mekanismen med ACTIONS_ID_TOKEN_REQUEST_TOKEN / ACTIONS_ID_TOKEN_REQUEST_URL.

Feilsøking

Audience stemmer ikke.

aud-claimen i tokenet må stemme med det leverandøren forventer. Hvis tillitspolicyen eller leverandøren er satt opp for en annen audience (f.eks. sts.amazonaws.com i stedet for https://frem.sh), feiler utvekslingen med en valideringsfeil for audience. Sett audience: https://frem.sh eksplisitt i leverandørkonfigurasjonen og i forespørselen om tokenet (bruk &audience=https://frem.sh i curl-URL-en).

sub-claimen stemmer ikke med betingelsen i tillitspolicyen.

Formatet på sub-claimen er eksakt: repo:<org>/<repo>:ref:refs/heads/<branch>. Vanlige avvik:

  • Skrivefeil i branch-navnet (main eller master).
  • Tillitspolicyen bruker en tag-ref (refs/tags/v1.0), men jobben kjører på en branch.
  • Policyen bruker refs/heads/main, men jobben kjører på en PR-branch (refs/pull/42/head). Bruk StringLike med et jokertegn hvis du må tillate PR-er: "repo:acme/api:ref:refs/pull/*".

Tokenet er utløpt, jobber som varer lenger enn 1 time.

OIDC-tokenet har en TTL på 1 time. Jobber som kjører i mer enn 1 time, får et nytt token hver gang de kaller token-endepunktet. Hvert steg som kaller ACTIONS_ID_TOKEN_REQUEST_URL, får et nytt token. Hvis du bufrer tokenet på tvers av steg som strekker seg over mer enn 1 time, utløper det. Hent et nytt token i hvert steg som trenger legitimasjon.

Tillatelsen id-token: write mangler.

Hvis permissions: ikke er satt i workflowen eller jobben, bruker runneren standardsettet med bare lesetilgang, som ikke inneholder id-token: write. Variabelen ACTIONS_ID_TOKEN_REQUEST_TOKEN mangler da, og forespørselen om tokenet returnerer 403. Legg til id-token: write i permissions:-blokken på jobbnivå (eller på workflow-nivå hvis alle jobbene trenger det).

Overstyringer av føderasjonen per organisasjon

Siden i organisasjonsadministrasjonen på https://frem.sh/<org>/_admin/runner-federation er stedet der du leser organisasjonens føderasjonsinnstillinger og strammer dem inn ved behov.

I de fleste oppsett trenger du bare utsteder-URL-en – kopier den fra denne siden inn i tillitspolicyen i skyen din (feltet Provider/Issuer URL for AWS, Azure, GCP, Scaleway osv.). Siden viser også JWKS-URL-en for leverandører som ikke henter discovery-dokumentet automatisk (T Cloud Public krever at du limer inn eksplisitt; AWS / Azure / GCP henter den automatisk).

Under Advanced overrides på samme side kan du:

  • Låse allowed_audiences – en absolutt tillatelsesliste over aud-verdier som utstederen vil signere. Bruk den når du bare vil utstede tokener for bestemte tillitspolicyer i skyen og blokkere enhver audience som ved et uhell er for bred.
  • Sette en egen mal for sub-claimen – når den eksisterende tillitspolicyen din forventer en annen form på sub enn fremforges standard.

De fleste kunder lar Advanced overrides stå på standardverdiene og bruker bare utsteder-URL-en. De samme innstillingene er også tilgjengelige programmatisk – se nedenfor.

Overstyringer av føderasjonen per organisasjon via API-et

Som standard signerer utstederen tokener med plattformens form på claimene (sub = repo:<org>/<repo>:ref:<ref>, ingen begrensning på aud). To innstillinger lar deg låse strengere kontrakter per organisasjon:

  • allowed_audiences, en absolutt tillatelsesliste over aud-verdier som utstederen vil signere. En forespørsel med aud utenfor listen avvises før JWT-en opprettes. Nyttig når du vil utstede tokener for tillitspolicyer i AWS og T Cloud Public, men blokkere enhver audience-claim som ved et uhell er for bred. Tom liste = ingen begrensning (plattformens standard).
  • sub_claim_template, en mal i Mustache-form som fylles ut med fire verdier ({{tenant}}, {{repo}}, {{branch}}, {{ref_type}}) når tokenet utstedes. Nyttig når den eksisterende tillitspolicyen din for GitHub Actions / Bitbucket Pipelines forventer en annen form på sub enn fremforges standard.

Lese gjeldende overstyringer

curl -H "Authorization: Bearer $FREMFORGE_PAT" \
  https://frem.sh/_app/api/v1/orgs/acme/runners/federation
# {
#   "issuer": "https://frem.sh/runner/oidc",
#   "jwks_uri": "https://frem.sh/runner/oidc/.well-known/jwks.json",
#   "tenant_org_slug": "acme",
#   "allowed_audiences": [],
#   "sub_claim_template": null
# }

Låse allowed_audiences

curl -X PUT -H "Authorization: Bearer $FREMFORGE_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "allowed_audiences": [
      "sts.amazonaws.com",
      "sts.eu-west-1.amazonaws.com"
    ]
  }' \
  https://frem.sh/_app/api/v1/orgs/acme/runners/federation

Etter dette avvises ethvert forsøk på å utstede et token med en aud som ikke står i listen, og jobben feiler lukket med en feil om avvist audience. Påkrevd PAT-scope: runners:write.

Tilpasse sub_claim_template

curl -X PUT -H "Authorization: Bearer $FREMFORGE_PAT" \
  -H "Content-Type: application/json" \
  -d '{
    "sub_claim_template": "tenant:{{tenant}}:repo:{{repo}}:branch:{{branch}}"
  }' \
  https://frem.sh/_app/api/v1/orgs/acme/runners/federation

De fire støttede innsettingene er:

TokenBlir tilEksempel
{{tenant}}Organisasjonens slugacme
{{repo}}<org>/<repo>acme/api
{{branch}}Branch-navn (bare når ref_type=branch; tomt for tagger)main
{{ref_type}}branch eller tagbranch

Ukjente plassholdere blir stående bokstavelig i resultatet; for eksempel blir {{nope}} stående som {{nope}} i den ferdige sub. Dette er med vilje: en feilkonfigurert mal feiler tydelig når tillitspolicyen skal matche, i stedet for å gi en tom streng i det stille.

Tilbakestille til standard

Send en tom allowed_audiences og null som sub_claim_template:

curl -X PUT -H "Authorization: Bearer $FREMFORGE_PAT" \
  -H "Content-Type: application/json" \
  -d '{ "allowed_audiences": [], "sub_claim_template": null }' \
  https://frem.sh/_app/api/v1/orgs/acme/runners/federation

Alle oppdateringer registreres i organisasjonens revisjonslogg under runner_federation.updated. Øyeblikksbildet av bodyen utelater hele sub_claim_template, men registrerer om den var satt.

Scaleway IAM External App

Scaleway er en suveren EU-sky med hovedkontor i Frankrike og datalokalisering i FR / NL / PL. Byggeklossen External Apps i IAM-tjenesten deres (GA i oktober 2024) godtar en OIDC-identitetsleverandør oppstrøms og lar deg binde arbeidslastprinsipaler via JWT-claims – samme føderasjonsform som AWS / GCP / Azure tilbyr.

Steg 1: opprett en IAM External App

I Scaleway-konsollen: IAM → External Apps → Add an External App. Sett opp:

  • Issuer URL, utsteder-URL-en for fremforge fra veiviseren (f.eks. https://frem.sh/_app/runner/oidc).
  • JWKS URI, JWKS-URI-en for fremforge.
  • Subject mapping, bind på sub. Begrens til ett repository om mulig (repo:<your-slug>/<repo>:*).
  • Audience, URN-en for Scaleway-organisasjonen din (scw:org:<org-id>).

Steg 2: knytt til en policy

Knytt en Scaleway-Policy til External App-en som gir de handlingene CI-en trenger. Avgrens til ett enkelt prosjekt for minst mulig tilgang.

Steg 3: bruk i en workflow

permissions:
  id-token: write
steps:
  - name: Get the fremforge OIDC token
    run: |
      TOKEN=$(curl -sS \
        -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
        "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=scw:org:<org-id>" \
        | jq -r .value)
      echo "::add-mask::$TOKEN"
      echo "FF_TOKEN=$TOKEN" >> $GITHUB_ENV
  - name: Exchange for Scaleway STS keys
    run: |
      # POST $FF_TOKEN to Scaleway's External-App token endpoint and export the
      # returned short-lived keys. See the Scaleway IAM docs for the exact shape.
      ./scripts/scw-sts-exchange.sh          # writes SCW_ACCESS_KEY / SCW_SECRET_KEY
  - name: Deploy
    run: ./deploy.sh

Formen på endepunktet for tokenutveksling er dokumentert i Scaleways IAM-dokumentasjon; External App-byggeklossen utsteder kortlivede nøkler i STS-stil knyttet til OIDC-subjektet.

Generisk OIDC-megler (Authentik, Keycloak)

For oppsett der skyen ikke støtter OIDC for arbeidslaster direkte (eldre virksomhetsmål som bare støtter SAML, utrullere on-prem, tillitsoppsett for flere skyer som vedlikeholdes sentralt), bruker du en megler: Authentik, Keycloak eller et hvilket som helst oppsett med en OIDC-RP som har en RP nedstrøms.

Når du bør bruke en megler

  • Du kjører allerede Authentik / Keycloak for SSO for mennesker og vil ha CI-arbeidslaster under den samme føderasjonsflaten.
  • Du vil administrere én registrering av tillitspolicy, ikke N per sky. Å legge til en ny sky blir da «legg til en ny leverandør i Authentik», ikke «gjør tillitspolicyen på nytt i hver sky».
  • Målet ditt støtter bare SAML (noen regulerte systemer on-prem). Megleren bygger bro fra OIDC til SAML.
  • Du retter deg mot en sky uten førsteklasses OIDC for arbeidslaster (Stackit, OVH, Hetzner); føderer via megleren i stedet for å vente på førsteklasses støtte.

Steg 1: legg til fremforge som kilde oppstrøms

I Authentik: Directory → Federation → OAuth/OIDC Source. Sett:

  • OIDC Provider, utsteder-URL-en fra veiviseren.
  • Audience, la stå tom eller sett den etter leverandøren nedstrøms.
  • Scopes, openid er nok; tokener fra fremforge har ingen profil- eller e-post-scopes.

Tilsvarende i Keycloak er Identity Providers → OpenID Connect v1.0 med Use JWKS URL slått på.

Steg 2: tilordne claims til lokale grupper / roller

I Authentik: Customisation → Property Mappings → OIDC. Tilordne sub fra runner-JWT-en (formen repo:<slug>/<repo>:ref:refs/heads/<branch>) til lokale grupper med et lite Python-uttrykk:

# Example: anyone deploying main → 'prod-deploy' group
import re
if re.match(r'^repo:[^/]+/[^:]+:ref:refs/heads/main$', token.get('sub', '')):
    return ['prod-deploy']
return []

Steg 3: bruk megleren som utsteder for skyen nedstrøms

Tillitspolicyen i skyen din matcher da på et token signert av Authentik, ikke direkte av fremforge. Audience = client_id for leverandøren i Authentik. Bytt JWT-en fra fremforge mot en JWT signert av Authentik via endepunktet /application/o/token/ i Authentik:

permissions:
  id-token: write
steps:
- name: Get fremforge runner OIDC token
  run: |
    TOKEN=$(curl -sS \
      -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
      "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=<authentik-provider-client-id>" \
      | jq -r .value)
    echo "::add-mask::$TOKEN"
    echo "FF_TOKEN=$TOKEN" >> $GITHUB_ENV
- name: Exchange for Authentik token
  id: ak-token
  run: |
    curl -fsS -X POST https://idp.acme.com/application/o/token/ \
      -d grant_type=urn:ietf:params:oauth:grant-type:token-exchange \
      -d subject_token=$FF_TOKEN \
      -d subject_token_type=urn:ietf:params:oauth:token-type:jwt \
      -d audience=<downstream-rp> \
      | jq -r .access_token > /tmp/ak-token
- name: Deploy
  env:
    BROKER_TOKEN: $(cat /tmp/ak-token)
  run: ./deploy.sh

Avveining

Megleren er et ekstra ledd på veien fra runner til sky (mer ventetid, ett sted til å feilsøke). Den lønner seg hvis du har minst 3 skyer, regulerte SAML-mål eller allerede kjører en megler for SSO for mennesker. For oppsett med én sky føderer du direkte til skyen (avsnittene over).

Se også

  • CI-runnere: referanse for hostede og egne runnere
  • Secrets: lagring og avgrensning av langlivet legitimasjon
  • Sikkerhet: isolasjonsmodell for runnere og sikkerhet i forsyningskjeden