OIDC-tokenfederation
Varje CI-jobb i fremforge kan få en kortlivad OIDC-token: en RS256-signerad JWT som utfärdas av fremforges runner-OIDC-utfärdare. Molnleverantörer (T Cloud Public, AWS, Azure, GCP) kan konfigureras att lita på den här token och byta den mot avgränsade, tidsbegränsade inloggningsuppgifter. Inga deploy keys lagrade som secrets, inget att rotera enligt schema.
Referens för anspråk
fremforges runner-JWT innehåller följande anspråk (claims):
| Anspråk | Värde / format | Exempel |
|---|---|---|
iss | https://frem.sh/_app/runner/oidc (en enda global utfärdare för alla tenants) | https://frem.sh/_app/runner/oidc |
sub | repo:<org>/<repo>:ref:refs/heads/<branch> | repo:acme/api:ref:refs/heads/main |
aud | Konfigurerbart; standard är https://frem.sh | https://frem.sh |
repository_owner | Organisationens slug. Lås villkoren i trust-policyn till det här anspråket för isolering per tenant under den delade utfärdaren | acme |
repository | <org>/<repo> | acme/api |
ref | Fullständig git-ref | refs/heads/main |
sha | Commitens SHA | a1b2c3d4... |
environment | Namnet på driftsättningsmiljön (om jobbet anger en) | production |
job_workflow_ref | Arbetsflödesfilens sökväg och ref | acme/api/.forgejo/workflows/deploy.yaml@refs/heads/main |
deployer_group | (Endast T Cloud Public) Namnet på den IAM-grupp som den federerade användaren binds till, satt per arbetslast av fremforge. Se Förtroende via T Cloud Public-agency | acme-prod-deployers |
Anspråket sub är det primära förtroendeankaret i de flesta leverantörers trust-policyer. Det identifierar unikt kombinationen av organisation, repo och branch. För isolering per tenant i delade molnkonton lägger du till ett villkor som låser på repository_owner (din organisations slug), samma mönster som GitHub Actions förtroende för token.actions.githubusercontent.com. fremforge har en enda global utfärdare för alla tenants; isoleringen av förtroendet upprätthålls i anspråken, inte i utfärdarens URL.
Hämta token i ett arbetsflöde
Lägg till id-token: write i jobbets permissions-block. Runnern fyller då i ACTIONS_ID_TOKEN_REQUEST_TOKEN och ACTIONS_ID_TOKEN_REQUEST_URL som miljövariabler, och med dem hämtar du själva JWT:n:
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 flesta leverantörsspecifika steg (AWS, Azure, GCP) hämtar token internt. Den manuella hämtningen ovan behöver du bara om du behöver den råa JWT:n för ett eget förtroendeflöde.
Förtroende via T Cloud Public-agency
T Cloud Publics modell för IAM-federation kommer från OpenStack: du registrerar OIDC-utfärdaren som en identitetsleverantör, kopplar en mappning som översätter anspråken i ID-token till lokala IAM-grupper och byter sedan runnerns ID-token mot en T Cloud Public Keystone-token, avgränsad till de grupper mappningen band, via OTC:s OS-FEDERATION-endpoint.
fremforge använder anspråksstyrd gruppbindning (samma form som AWS Identity Center, GCP Workload Identity Federation och Azure Federated Credentials använder): runnerns ID-token bär ett deployer_group-anspråk per arbetslast, och din OTC-mappning läser det anspråket ordagrant. En enda mappningsregel täcker hela din flotta: när du lägger till en arbetslast rörs din IAM inte alls.
Steg 1: Skapa en OpenID Connect-identitetsleverantör
I T Cloud Public-konsolen går du till IAM → Identity Providers → Create Identity Provider.
- Type: Virtual user
- Protocol: OpenID Connect
- Access type: Programmatic access (
program)
När den har skapats konfigurerar du OIDC-inställningarna:
- Identity provider URL (
idp_url):https://frem.sh/_app/runner/oidc(en enda global utfärdare; stämmer mediss-anspråket i varje ID-token från fremforges runners). - Client ID (
client_id):https://frem.sh, måste vara lika medaud-anspråket i runnerns ID-token. - Signing key (
signing_key): klistra in JWKS-JSON:en med den publika nyckeln. Hämta den en gång frånhttps://frem.sh/_app/runner/oidc/.well-known/openid-configuration→jwks_urioch kopiera JSON:en. T Cloud Public hämtar inte JWKS automatiskt, så klistra in den igen när fremforge aviserar en JWKS-rotation (aviseras på förtroendesidan; rotationer sker högst en gång per år).
Steg 2: Lägg till den anspråksstyrda mappningsregeln
En enda regel, som räcker för hur många arbetslaster som helst:
[
{
"local": [
{ "user": { "name": "fremforge-{0}-{1}" } },
{ "group": { "name": "{2}" } }
],
"remote": [
{ "type": "repository_owner" },
{ "type": "repository" },
{ "type": "deployer_group" }
]
}
]Förtroendemodellen:
- Den federerade användaren går med i den IAM-grupp vars namn ID-tokens
deployer_group-anspråk anger ({2}ersätts ordagrant med anspråkets värde). - Anspråket sätts av fremforges runner-OIDC-utfärdare enligt den mappning mellan arbetslast och grupp som du kommer överens om vid onboarding. Det kan bara anges för arbetslaster vi har en rad för, och bara för den ref som raden låser (standard: main-branchen).
- Samma låsning av JWT-signaturen, samma filtrering på
iss+aud+repository_owner. Det enda som har flyttats är beslutet om arbetslast→grupp, från ”N mappningsregler i OTC” till ”ett anspråk som fremforge sätter”.
Steg 3: Skapa de IAM-grupper dina arbetslaster ska anta
Skapa en grupp per driftsättningsprofil du vill exponera (t.ex. acme-prod-deployers, acme-staging-deployers). Koppla de projekt- och EPS-roller varje profil behöver. De är helt och hållet dina; fremforge rör aldrig din gruppkonfiguration. Gruppnamnen motsvarar värdet som fremforge kommer att sätta i deployer_group-anspråket, och det kommer du överens om vid onboarding.
Steg 4: Tala om för fremforge vilken arbetslast som använder vilken grupp
Via mejl eller ett anrop till admin-API:et: ”Repo acme/api, main-branchen → gruppen acme-prod-deployers.” fremforge lägger in en rad i sin tabell runner_deployer_groups. Från nästa körning av arbetsflödet bär ID-tokens för den arbetslasten deployer_group=acme-prod-deployers, och din mappning binder den federerade användaren till den gruppen.
Att lägga till ett nytt repo är bara ytterligare ett mejl; din IAM i OTC förblir oförändrad.
Valfritt: Skapa en agency att anta
De flesta konfigurationer hoppar över detta: gruppbindningen från steg 2 räcker. Om du använder ett mönster med antagna roller skapar du en agency (IAM → Agencies → Create Agency) med följande:
- Agency type: Account (molntjänst från ett annat T Cloud Public-konto är inte aktuellt här).
- Delegated party: välj den OpenID Connect-identitetsleverantör du skapade i steg 1.
- Permissions: koppla de policyer som CI-jobbet behöver (t.ex.
OBS Administratoravgränsat till arbetslastens OBS-bucket, ellerCCE FullAccessavgränsat till arbetslastens projekt).
Anteckna agencyns namn och det projekt du avgränsar den till.
Steg 5: Använd inloggningsuppgifterna i ett arbetsflöde
Runnern hämtar en ID-token, byter den mot en oavgränsad Keystone-token via OTC:s OS-FEDERATION-endpoint och byter sedan den mot en projektavgränsad token. Både T Cloud Publics CLI (otc) och OpenTofu med providern opentelekomcloud tar OS_AUTH_TOKEN från miljön utan ytterligare konfiguration.
# 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 automaticallyOm det som är specifikt för T Cloud Public
- OTC använder
/v3/OS-FEDERATION/identity_providers/{idp}/protocols/oidc/auth, INTE/v3/auth/tokensmedmethods=["id_token"]. Metoden i auth-bodyn från OpenStack upstream returnerar400 "Unsupported method: id_token"i OTC:s Keystone-fork. Verifierat empiriskt och enligt OTC:s API-dokumentiam_13_0606. - OTC roterar inte JWKS automatiskt. Du klistrar in signeringsnyckeln en gång när leverantören skapas, och klistrar in den igen när fremforge aviserar en rotation. AWS, Azure och GCP hämtar den alla automatiskt från discovery-dokumentet; bara T Cloud Public kräver att den klistras in uttryckligen.
- Den utbytta token finns i svarshuvudet
X-Subject-Token, inte i bodyn, enligt OpenStack Keystones konvention. - Avgränsningen av arbetslasten kommer från
deployer_group-anspråket (mappningen binder den federerade användaren till den gruppen) OCH projektrollerna på den gruppen. Anspråket hindrar fel arbetslast från att anta fel grupp; rollen begränsar vad gruppen kan göra. - Valfritt: agencies för mönster med antagna roller stöds också, men de flesta fall behöver dem inte; gruppbindningen från steg 2 räcker.
AWS IAM
Steg 1: Skapa en OIDC-identitetsleverantör
I AWS-konsolen går du till IAM → Identity providers → Add provider.
- Provider type: OpenID Connect
- Provider URL:
https://frem.sh/_app/runner/oidc(en enda global utfärdare; filtreringen per tenant görs i trust-policyns villkor, inte i leverantörens URL) - Audience:
https://frem.sh
AWS hämtar JWKS från discovery-dokumentet för att verifiera tokens.
Steg 2: Skapa en IAM-roll med en trust-policy för 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"
}
}
}
]
}Koppla de behörigheter CI-jobbet behöver till rollen (t.ex. AmazonS3FullAccess, AmazonECRPowerUser).
Steg 3: Använd i ett arbetsflöde
Använd den officiella 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 sköter hämtningen av token, anropet till sts:AssumeRoleWithWebIdentity och injiceringen av inloggningsuppgifterna automatiskt.
Azure (Entra Workload Identity)
Steg 1: Skapa federerade autentiseringsuppgifter på en appregistrering
- I Azure-portalen går du till Entra ID → App registrations →
<your app>→ Certificates & secrets → Federated credentials. - Klicka på Add credential.
- Scenario: Other issuer.
- Fyll i:
- Issuer:
https://frem.sh/_app/runner/oidc(en enda global utfärdare; isoleringen per tenant upprätthålls av Subject identifier nedan) - Subject identifier:
repo:<your-org>/<your-repo>:ref:refs/heads/main - Audience:
https://frem.sh
- Issuer:
- Spara.
Steg 2: Använd i ett arbetsflöde
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 ./distAppregistreringens klient-id och ditt Entra-tenant-id är inte hemliga. De kan lagras som vanliga arbetsflödesvariabler. Bara OIDC-token är känslig, och den går ut när jobbet är klart.
GCP Workload Identity
Steg 1: Skapa en Workload Identity-pool och en OIDC-leverantö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: Ge rätt att agera som tjänstekontot
# 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: Använd i ett arbetsflöde
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 fungerar på fremforges runners. Den använder samma mekanism med ACTIONS_ID_TOKEN_REQUEST_TOKEN / ACTIONS_ID_TOKEN_REQUEST_URL.
Felsökning
Audience stämmer inte.
Anspråket aud i token måste stämma med det leverantören förväntar sig. Om trust-policyn eller leverantören är konfigurerad för en annan audience (t.ex. sts.amazonaws.com i stället för https://frem.sh) misslyckas utbytet med ett valideringsfel för audience. Ange audience: https://frem.sh uttryckligen i leverantörens konfiguration och i begäran om token (använd &audience=https://frem.sh i curl-URL:en).
Anspråket sub stämmer inte med villkoret i trust-policyn.
Formatet för sub är exakt: repo:<org>/<repo>:ref:refs/heads/<branch>. Vanliga avvikelser:
- Felstavat branch-namn (
mainellermaster). - Trust-policyn använder en tagg-ref (
refs/tags/v1.0) men jobbet körs på en branch. - Policyn använder
refs/heads/mainmen jobbet körs på en PR-branch (refs/pull/42/head). AnvändStringLikemed ett jokertecken om du behöver tillåta PR:er:"repo:acme/api:ref:refs/pull/*".
Token har gått ut, jobb som tar längre än 1 timme.
OIDC-token har en livslängd på 1 timme. Jobb som kör längre än 1 timme får en ny token varje gång de anropar token-endpointen. Varje steg som anropar ACTIONS_ID_TOKEN_REQUEST_URL får en ny token. Om du cachar token mellan steg som sträcker sig över mer än 1 timme går den ut. Hämta en ny token i varje steg som behöver inloggningsuppgifter.
Behörigheten id-token: write saknas.
Om permissions: inte är satt i arbetsflödet eller jobbet använder runnern standarduppsättningen med enbart läsbehörighet, som inte innehåller id-token: write. Variabeln ACTIONS_ID_TOKEN_REQUEST_TOKEN saknas då, och begäran om token returnerar 403. Lägg till id-token: write i permissions:-blocket på jobbnivå (eller på arbetsflödesnivå om alla jobb behöver det).
Federationsåsidosättanden per organisation
Sidan i tenant-administrationen på https://frem.sh/<org>/_admin/runner-federation är platsen där du läser organisationens federationsinställningar och skärper dem vid behov.
För de flesta konfigurationer behöver du bara utfärdar-URL:en: kopiera den från sidan till ditt molns trust-policy (fältet Provider/Issuer URL i AWS, Azure, GCP, Scaleway osv.). Sidan visar också JWKS-URL:en för leverantörer som inte hämtar discovery-dokumentet automatiskt (T Cloud Public kräver att den klistras in uttryckligen; AWS, Azure och GCP hämtar den automatiskt).
Under Avancerade åsidosättanden på samma sida kan du:
- Låsa
allowed_audiences, en strikt lista över tillåtnaaud-värden som utfärdaren signerar. Använd den när du bara vill skapa tokens för specifika trust-policyer i molnet och blockera en audience som av misstag är bredare. - Ange en egen mall för
sub-anspråket, när din befintliga trust-policy förväntar sig en annan form påsubän fremforges standard.
De flesta kunder låter de avancerade åsidosättandena stå kvar på standardvärdena och använder bara utfärdar-URL:en. Samma inställningar finns också programmatiskt, se nedan.
Federationsåsidosättanden per organisation via API:et
Som standard signerar utfärdaren tokens med plattformens form på anspråken (sub = repo:<org>/<repo>:ref:<ref>, ingen begränsning av aud). Två reglage låter dig låsa striktare villkor per tenant:
allowed_audiences, en strikt lista över tillåtnaaud-värden som utfärdaren signerar. En begäran om att skapa en token med enaudutanför listan avvisas innan JWT:n skapas. Användbart när du vill skapa tokens för trust-policyer i AWS och T Cloud Public men blockera ettaud-anspråk som av misstag är bredare. Tom lista = ingen begränsning (plattformens standard).sub_claim_template, en mall i Mustache-form som fylls i med fyra värden ({{tenant}},{{repo}},{{branch}},{{ref_type}}) när token skapas. Användbart när din befintliga trust-policy för GitHub Actions eller Bitbucket Pipelines förväntar sig en annan form påsubän fremforges standard.
Läsa de nuvarande åsidosättandena
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åsa 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/federationDärefter avvisas varje försök att skapa en token med en aud som inte finns i listan, och jobbet misslyckas säkert med ett fel om avvisad audience. PAT-scope som krävs: runners:write.
Anpassa 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 fyra ersättningar som stöds är:
| Platshållare | Ersätts med | Exempel |
|---|---|---|
{{tenant}} | Organisationens slug | acme |
{{repo}} | <org>/<repo> | acme/api |
{{branch}} | Branch-namn (bara när ref_type=branch; tomt för taggar) | main |
{{ref_type}} | branch eller tag | branch |
Okända platshållare lämnas kvar bokstavligt i resultatet, till exempel blir {{nope}} kvar som {{nope}} i den färdiga sub. Det är avsiktligt: en felkonfigurerad mall misslyckas tydligt när trust-policyn ska matcha, i stället för att tyst ge en tom sträng.
Återställa till standard
Skicka en tom allowed_audiences och 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/federationAlla ändringar registreras i tenantens granskningslogg under runner_federation.updated. Ögonblicksbilden av bodyn utelämnar den fullständiga sub_claim_template men registrerar om en sådan var satt.
Scaleway IAM External App
Scaleway är ett EU-suveränt moln med huvudkontor i Frankrike och datalagring i FR / NL / PL. Deras IAM-funktion External Apps (GA i oktober 2024) tar emot en OIDC-IdP uppströms och låter dig binda arbetslastens principaler via JWT-anspråk, samma federationsform som AWS, GCP och Azure erbjuder.
Steg 1: Skapa en IAM External App
I Scaleway-konsolen: IAM → External Apps → Add an External App. Konfigurera:
- Issuer URL: fremforges utfärdar-URL från guiden (t.ex.
https://frem.sh/_app/runner/oidc). - JWKS URI: fremforges JWKS-URI.
- Subject mapping: bind på
sub. Begränsa till ett repo om möjligt (repo:<your-slug>/<repo>:*). - Audience: din Scaleway-organisations URN (
scw:org:<org-id>).
Steg 2: Koppla en Policy
Koppla en Scaleway-Policy till External App som ger de åtgärder din CI behöver. Avgränsa till ett enda Project för minsta möjliga behörighet.
Steg 3: Använd i ett arbetsflöde
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å endpointen för tokenutbyte är dokumenterad i Scaleways IAM-dokumentation; External App ger kortlivade nycklar i STS-stil, kopplade till OIDC-subjektet.
Generisk OIDC-broker (Authentik, Keycloak)
För konfigurationer där molnet inte talar arbetslast-OIDC direkt (äldre företagsmål som bara stöder SAML, driftsättare on-prem, förtroendekartor för flera moln som underhålls centralt) använder du en broker: Authentik, Keycloak eller någon OIDC-RP med en RP nedströms.
När du ska använda en broker
- Du kör redan Authentik eller Keycloak för SSO för människor och vill ha CI-arbetslaster under samma federationsyta.
- Du vill ha en enda registrering av trust-policy att hantera, inte N, en per moln. Att lägga till ett nytt moln blir då ”lägg till en ny Authentik-provider”, inte ”gör om trust-policyn i varje moln”.
- Ditt mål stöder bara SAML (vissa reglerade system on-prem). Brokern överbryggar OIDC → SAML.
- Du riktar dig mot ett moln utan förstklassigt stöd för arbetslast-OIDC (Stackit, OVH, Hetzner): federera via brokern i stället för att vänta på förstklassigt stöd.
Steg 1: Lägg till fremforge som källa uppströms
I Authentik: Directory → Federation → OAuth/OIDC Source. Ange:
- OIDC Provider: utfärdar-URL:en från guiden.
- Audience: lämna tomt eller ange enligt din provider nedströms.
- Scopes:
openidräcker; fremforges tokens bär inga profil- eller e-postscopes.
Motsvarigheten i Keycloak är Identity Providers → OpenID Connect v1.0 med Use JWKS URL påslaget.
Steg 2: Mappa anspråk till lokala grupper eller roller
I Authentik: Customisation → Property Mappings → OIDC. Mappa runner-JWT:ns sub (formen repo:<slug>/<repo>:ref:refs/heads/<branch>) till lokala grupper med ett litet Python-uttryck:
# 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: Använd brokern som utfärdare för molnet nedströms
Ditt molns trust-policy matchar då en token som signerats av Authentik, inte direkt av fremforge. Audience = Authentik-providerns client_id. Byt fremforge-JWT:n mot en Authentik-signerad JWT via Authentiks endpoint /application/o/token/:
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.shAvvägning
Brokern är ett extra steg i vägen runner→moln (mer latens, ytterligare ett ställe att felsöka). Den lönar sig om du har tre eller fler moln, reglerade SAML-mål eller redan kör en broker för SSO för människor. Vid ett enda moln federerar du direkt mot molnet (avsnitten ovan).
Korsreferenser
- CI-runners: referens för hostade runners och egna runners (BYO)
- Secrets: lagra och avgränsa långlivade inloggningsuppgifter
- Säkerhet: runnerns isoleringsmodell och säkerhet i leveranskedjan