Udrulnings-secrets: OIDC-føderation
fremforge vil helst ikke opbevare dine produktions-secrets. Langlivede udrulningslegitimationsoplysninger (AWS_ACCESS_KEY_ID, AZURE_CLIENT_SECRET, GCP_SA_KEY, …), der gemmes i CI-systemers secret-lagre, er en evig rotationsopgave og en evig risiko ved et brud. Den moderne løsning er OIDC-føderation: dit workflow beder CI-serveren om et kortlivet identitetstoken, din clouds IAM verificerer tokenet og giver en kortlivet legitimationsoplysning tilbage. fremforge leverer det hele vejen.
Sådan virker det
Hvert CI-job, der kører på fremforge, får et nyudstedt JSON Web Token signeret af fremforges runner-OIDC-udsteder på https://frem.sh/_app/runner/oidc. Tokenet indeholder claims, der beskriver jobbets kontekst, repository, ref, workflow og eventuelt miljø, og din clouds IAM-tillidspolitik afgør ud fra de claims, om der skal udstedes legitimationsoplysninger.
sequenceDiagram
autonumber
actor User
participant FF as fremforge<br/>runner-OIDC issuer
participant Pod as runner VM
participant Cloud as Your cloud's<br/>IAM • STS / WIF / …
User->>FF: git push
FF->>Pod: dispatch job — mint OIDC JWT
Pod->>Cloud: "Here's my JWT, give me credentials"
Cloud->>Cloud: Verify JWT against fremforge JWKS<br/>+ check trust policy claims
Cloud->>Pod: 1h credentials
Pod->>Cloud: deploy / read / write
Claims, som din clouds tillidspolitik kan matche på:
| Claim | Eksempel | Hvad det identificerer |
|---|---|---|
iss | https://frem.sh/_app/runner/oidc | fremforge selv |
aud | sts.amazonaws.com | hvilken cloud du godkender dig over for |
sub | repo:my-org/my-repo:environment:production (når environment: er erklæret)repo:my-org/my-repo:ref:refs/heads/main (uden miljø) | hvilken workflow-kørsel |
repository | my-org/my-repo | repoets navn |
repository_owner | my-org | organisationens slug |
ref | refs/heads/main | git-ref |
environment | production | miljønavn erklæret i workflowet |
actor | alice | Forgejo-brugernavnet, der startede kørslen |
De følger formen på GitHub Actions’ claims, så eksisterende tillidspolitikker og actions som actions/configure-aws-credentials / azure/login / google-github-actions/auth virker uden ændringer.
Discovery-URL
Peg din cloud på:
- Udsteder-URL:
https://frem.sh/_app/runner/oidc - JWKS-URL:
https://frem.sh/_app/runner/oidc/.well-known/jwks.json - Discovery-dokument:
https://frem.sh/_app/runner/oidc/.well-known/openid-configuration
Alle tre kan læses anonymt.
Mønstre for workflows
Erklæring af et miljø
jobs:
deploy:
runs-on: fremforge-runner
environment: production
permissions:
id-token: write # required to mint the OIDC JWT
contents: read
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/fremforge-deploy-prod
aws-region: eu-central-1
- run: aws s3 sync ./build s3://my-prod-bucket/environment: production ændrer OIDC-claimet sub til repo:my-org/my-repo:environment:production, så din tillidspolitik kun kan give adgang til jobs, der er erklæret som production.
Uden et miljø
Når du ikke erklærer environment:, falder sub tilbage til repo:<owner>/<repo>:ref:<ref>. Tillidspolitikker, der matcher på ref, virker på samme måde som på GitHub. fremforges miljøgate gælder ikke (den gater kun workflows, der erklærer et miljø), så tillidspolitikken på cloudsiden er dit eneste værn.
Eksempler på tillidspolitikker
AWS
IAM-tillidspolitik for en OIDC-fødereret rolle:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/frem.sh/_app/runner/oidc"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"frem.sh/_app/runner/oidc:aud": "sts.amazonaws.com"
},
"StringLike": {
"frem.sh/_app/runner/oidc:sub": "repo:my-org/my-repo:environment:production"
}
}
}]
}Opsætning én gang: registrér fremforge som OIDC-udbyder:
aws iam create-open-id-connect-provider \
--url https://frem.sh/_app/runner/oidc \
--client-id-list sts.amazonaws.com \
--thumbprint-list $(curl -s https://frem.sh/_app/runner/oidc/.well-known/jwks.json | jq -r '.keys[0].x5t')Azure (Workload Identity Federation)
Registrér den fødererede legitimationsoplysning på en App Registration i Entra ID:
az ad app federated-credential create \
--id $APP_OBJECT_ID \
--parameters '{
"name": "fremforge-prod-deploy",
"issuer": "https://frem.sh/_app/runner/oidc",
"subject": "repo:my-org/my-repo:environment:production",
"audiences": ["api://AzureADTokenExchange"]
}'Workflow:
- uses: azure/login@v2
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}GCP (Workload Identity Federation)
gcloud iam workload-identity-pools providers create-oidc fremforge-provider \
--workload-identity-pool=fremforge-pool \
--issuer-uri="https://frem.sh/_app/runner/oidc" \
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.environment=assertion.environment" \
--attribute-condition="attribute.environment == 'production'"Workflow:
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/fremforge-pool/providers/fremforge-provider
service_account: deploy@my-project.iam.gserviceaccount.comT Cloud Public (OTC IAM Identity Provider)
T Cloud Public bruger IAM Identity Providers og token-udveksling:
- Identity Provider i OTC Console → IAM → Identity Providers → Create:
- Name:
fremforge-runner-oidc - Protocol:
OpenID Connect - Issuer URL:
https://frem.sh/_app/runner/oidc - JWKS URL:
https://frem.sh/_app/runner/oidc/.well-known/jwks.json - Client ID:
iam.eu-de.otc.t-systems.com(eller dit projekts STS-audience)
- Name:
- Mapping-regler, der oversætter claims til en fødereret bruger. Eksempel, der mapper et
repo:my-org/my-repo:environment:production-subject til OTC-gruppendeploy-prod:
[
{
"local": [
{ "user": { "name": "{0}" } },
{ "group": { "name": "deploy-prod" } }
],
"remote": [
{ "type": "sub" },
{ "type": "environment", "any_one_of": ["production"] }
]
}
]- Workflow: udveksl JWT’et til et OTC-token via IAM’s endpoint til token-udveksling, og brug derefter den returnerede
X-Subject-Tokentil ethvert OTC API-kald.
Styr, hvilke refs der kan udrulle hvorhen
OIDC-føderation fjerner behovet for at GEMME langlivede secrets, men du skal stadig beslutte, hvilke branches der kan udrulle til hvilket miljø. Et workflow på en feature-branch KAN udstede et JWT, der hævder environment: production; det er gaten, der forhindrer, at JWT’et accepteres.
fremforge tilbyder to gates, og du bør bruge begge som forsvar i dybden.
Gate 1: tillidspolitik på cloudsiden (altid påkrævet)
Din clouds IAM-tillidspolitik er den endelige autoritet. Lås sub-claimet til formen repo+miljø, OG lås ref-claimet til den eller de branches, miljøet må udrulles fra. Eksempel for AWS:
{
"Condition": {
"StringEquals": {
"frem.sh/_app/runner/oidc:sub": "repo:my-org/my-repo:environment:production"
},
"StringLike": {
"frem.sh/_app/runner/oidc:ref": "refs/heads/main"
}
}
}En feature-branch KAN udstede JWT’et, men AWS nægter at udstede legitimationsoplysninger, fordi ref er refs/heads/feature/foo i stedet for refs/heads/main. Det er det grundmønster, GitHub anbefaler, og det virker fra dag ét.
Gate 2: fremforges mønstre for udrulningsbranches pr. miljø (anbefalet)
Under Administration → Miljøer (frem.sh/<org>/_admin/environments) konfigurerer du hvert miljø på GitHub-vis. Tre sektioner pr. miljø:
Branches og tags til udrulning: glob-mønstre, der matches mod den git-ref, der startede kørslen. Eksempler (får automatisk præfikset refs/heads/ som kortform for branches):
| Navn | Mønstre | Virkning |
|---|---|---|
production | main | kun main-branchen |
staging | maindeveloprelease/* | main, develop og release/*-branches |
pr-preview | * | enhver branch (gaten på cloudsiden er den reelle autoritet) |
release | refs/tags/v[0-9]+.* | kun versionstags (eksplicit præfiks refs/tags/) |
Workflows, der erklærer environment: production, afvises ved afsendelse, når den ref, der startede dem, ikke matcher. Workflows UDEN en environment:-erklæring kører uden begrænsning, så almindelig CI på feature-branches fortsat virker.
Miljøsecrets: krypterede, afgrænset til miljøet og injiceret som workflow-${{ secrets.NAME }} OG som almindelige miljøvariabler, når workflowets environment: matcher. Dækker de secrets uden for cloud-IAM (API-nøgler til tredjeparter, signeringsnøgler, webhook-secrets), som OIDC-føderation ikke løser.
Miljøvariabler: værdier, der ikke er hemmelige, afgrænset til miljøet. Samme injektionsmodel.
Hvad med godkendelsesgates?
GitHub Actions Environments har funktionen “Required reviewers”: et job sættes på pause efter merge, indtil N personer klikker Approve i Actions-brugerfladen. fremforge leverer bevidst ikke dette, fordi Forgejo allerede har en stærkere gate på samme tidspunkt i forløbet: branch-beskyttelse på main med CODEOWNERS på .forgejo/workflows/* kræver review af en pull request, før et workflow, der kan udrulle, lander. I 99 %-tilfældet (1 pull request = 1 udrulning) ER Forgejos review af pull requesten godkendelsen af udrulningen. Kunder, der har brug for GitHub-tilfældet (1 pull request kan give N uafhængige udrulninger med separate godkendere pr. udrulning), kan oprette en issue, og vi prioriterer godkendere ved udrulning (planlagt) ud fra den faktiske efterspørgsel.
fremforges gate forhindrer, at JWT’et overhovedet udstedes. Gaten på cloudsiden forhindrer, at et udstedt JWT accepteres. Kombinér begge: selv hvis en fremtidig fejl i fremforge lod en afvist afsendelse slippe igennem, nægter cloudens IAM stadig at udstede legitimationsoplysninger. Og selv hvis en kundes tillidspolitik i cloudsiden har en tastefejl og accepterer et bredere ref-mønster end tiltænkt, har fremforge stadig nægtet at udstede JWT’et.
Doven onboarding
Når du erklærer environment: x i et workflow, men endnu ikke har konfigureret en environments-række for x, tillader fremforge afsendelsen i stedet for at afvise den. Det er bevidst, så en ny kundes workflows ikke går i stykker i det øjeblik, de erklærer et miljø; din tillidspolitik på cloudsiden er sikkerhedsnettet, indtil du tilføjer rækken i fremforge. Når en række findes, håndhæves gaten.
Låst tilstand: kun beskyttede branches
I miljøer med høje sikkerhedskrav, hvor du vil forbyde CI-kørsel på ubeskyttede refs HELT (ikke kun gate udrulningslegitimationsoplysninger), skal du slå Administration → Miljøer → Organisationsdækkende lukning → Kør kun workflows på beskyttede branches til:
Kør kun workflows på beskyttede branches
Når den er slået til, nægter platformen at sende ETHVERT workflow af sted, hvis udløsende branch IKKE står på repoets liste over beskyttede branches (konfigureret via Forgejos indbyggede Indstillinger → Grene → Tilføj ny regel). Det omfatter almindelig CI (tests, lint): intet kører på ubeskyttede branches. Nyttigt i regulerede miljøer, hvor du vil have nul kodekørsel uden for gennemgåede refs; anbefales ikke til almindelig udvikling, fordi det ødelægger test af feature-branches.
Slår du det til, vil du typisk beskytte mønstrene main, develop og release/* i Forgejo, så dine almindelige udviklingsbranches stadig kan køre CI.
Anbefalet opsætning
For typiske SaaS- og produktteams:
- Slå ikke udrulningsgaten med kun beskyttede branches til; lad almindelig CI køre på feature-branches.
- Konfigurér miljøer under Administration → Miljøer med passende mønstre for branches og tags til udrulning for hvert (production, staging osv.).
- Konfigurér tillidspolitikker i cloud med både
sub-betingelser (låst til miljø) OGref-betingelser (låst til branch). - Branch-beskyt
maini Forgejo med CODEOWNERS-dækning af.forgejo/workflows/*, så ændringer i workflows kræver review.
For regulerede miljøer og låste miljøer (bank, forsvar, sundhed):
- Slå udrulningsgaten med kun beskyttede branches til.
- Konfigurér miljøer til finkornet gating pr. miljø oven i.
- Samme opsætning af tillidspolitikker på cloudsiden som ovenfor.
Denne kombination svarer til den model for udrulningsgates, som GitHub Enterprise og AWS anbefaler (kræv miljøer ved udrulning + kun beskyttede branches), plus den valgfri låsekontakt for regulerede tenants.
Sammenligning: hvad fremforge gemmer, og hvad din cloud gemmer
| Langlivede secrets | OIDC-føderation (denne side) | |
|---|---|---|
| Hvor udrulningslegitimationsoplysninger ligger | Indstillinger → Secrets i fremforge | Din clouds IAM. fremforge ser dem aldrig. |
| Levetid for legitimationsoplysninger | Indtil du roterer | 1 time (kan konfigureres pr. tillidspolitik) |
| Hvis fremforge kompromitteres | Angriberen har dine AWS-nøgler | Angriberen kan udstede OIDC-JWT’er, men tillidspolitikken på cloudsiden begrænser, hvad de JWT’er kan (pr. miljø, pr. repo, pr. ref) |
| Rotationsopgave | Hvert kvartal pr. secret pr. cloud | Ingen, nøgler roteres for hvert job |
| Revisionsspor | Manuelt: hvem eksporterede secreten hvornår | Hver OIDC-udstedelse står i audit_events + din clouds CloudTrail/Activity Log |
Begrænsninger
environment:i objektform (medname:+url:) understøttes efter navn;url:fortolkes, men vises i øjeblikket ikke som claim.- Miljønavne udfoldet fra en matrix (
environment: ${{ matrix.target }}) opløses ikke på tidspunktet for OIDC-udstedelsen, og der udsendes intetenvironment-claim. Brug en hardkodetenvironment:pr. matrix-job, hvis du har brug for tillidspolitikker baseret på miljø-claimet. - Gates med påkrævede godkendere pr. miljø (som GitHub Environments’ funktion “wait for approval”) er planlagt som opfølgning i fase 2; i dag er håndhævelsen binær (beskyttet branch ja/nej).
Se også
- Integritet i revisionskæden: hver OIDC-udstedelse udsender en revisionshændelse i hash-kæden pr. tenant
- Sikkerhedsmodel for hostede runners: hvad der isolerer én kundes runner fra en andens