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:
| Claim | Verdi / format | Eksempel |
|---|---|---|
iss | https://frem.sh/_app/runner/oidc (én global utsteder for alle organisasjoner) | https://frem.sh/_app/runner/oidc |
sub | repo:<org>/<repo>:ref:refs/heads/<branch> | repo:acme/api:ref:refs/heads/main |
aud | Kan konfigureres; standard https://frem.sh | https://frem.sh |
repository_owner | Organisasjonens slug – lås betingelsene i tillitspolicyen til denne claimen for isolasjon per organisasjon under den delte utstederen | acme |
repository | <org>/<repo> | acme/api |
ref | Full git-ref | refs/heads/main |
sha | Commit-SHA | a1b2c3d4... |
environment | Navnet på utrullingsmiljøet (hvis jobben deklarerer et) | production |
job_workflow_ref | Sti og ref for workflow-filen | acme/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 Public | acme-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_ENVDe 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; matcheriss-claimen i alle ID-tokener fra fremforges runnere). - Client ID (
client_id):https://frem.sh, må være likaud-claimen i runnerens ID-token. - Signing key (
signing_key): lim inn JSON-en med JWKS-offentlignøkkelen. Hent den én gang frahttps://frem.sh/_app/runner/oidc/.well-known/openid-configuration→jwks_uriog 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 Administratoravgrenset til arbeidslastens OBS-bøtte, ellerCCE FullAccessavgrenset 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 automaticallyMerknader om det spesifikke for T Cloud Public
- OTC bruker
/v3/OS-FEDERATION/identity_providers/{idp}/protocols/oidc/auth, IKKE/v3/auth/tokensmedmethods=["id_token"]. Autentiseringsmetoden fra OpenStack upstream returnerer400 "Unsupported method: id_token"på OTCs Keystone-fork. Verifisert i praksis og i henhold til OTCs API-dokumentasjoniam_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
- I Azure-portalen går du til Entra ID → App registrations →
<your app>→ Certificates & secrets → Federated credentials. - Klikk på Add credential.
- Scenario: Other issuer.
- 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
- Issuer:
- 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 ./distKlient-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-imageActionen 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 (
mainellermaster). - 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). BrukStringLikemed 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 overaud-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åsubenn 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 overaud-verdier som utstederen vil signere. En forespørsel medaudutenfor 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åsubenn 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/federationEtter 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/federationDe fire støttede innsettingene er:
| Token | Blir til | Eksempel |
|---|---|---|
{{tenant}} | Organisasjonens slug | acme |
{{repo}} | <org>/<repo> | acme/api |
{{branch}} | Branch-navn (bare når ref_type=branch; tomt for tagger) | main |
{{ref_type}} | branch eller tag | branch |
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/federationAlle 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.shFormen 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,
openider 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.shAvveining
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