Gå til hovedindhold

Secrets og miljøvariabler

Secrets er krypterede værdier, der sendes ind i workflow-jobs som miljøvariabler. De kan kun skrives, når de først er oprettet: værdien kan aldrig læses tilbage via brugerfladen eller API’et. Denne side dækker scopes, oprettelse, brug i workflows, rotation og grænser.

Secrets krypteres i hvile med T Cloud Public DEW KMS og dekrypteres først, når jobbet kører på runneren.

Secrets på organisationsniveau administreres i organisationens administration på frem.sh/<org>/_admin/secrets. Secrets på repo-niveau ligger under hvert repositorys Indstillinger → Handlinger → Hemmeligheder i Forgejo. Miljøer administreres med deres secrets, variabler, branch-regler og godkendere i organisationens administration på frem.sh/<org>/_admin/environments. fremforge giver et job dets miljøs secrets, når jobbet tildeles en runner, og anvender rækkefølgen (miljø, derefter repo, derefter organisation) dér.

Scopes

ScopeHvor den sættesTilgængelig for
Organisations-secretAdministration → SecretsAlle repositorier i organisationen
Repo-secretRepo-indstillinger → HemmelighederKun det pågældende repo
Scoped CI-secretAPI’et /orgs/<org>/ci-secrets (side i organisationsadministrationen: på vej)Jobs, hvis workflow, job, branch eller tag, hændelse og miljø secretens scope tillader, og kun når jobbet refererer til den (nedenfor)
Miljø-secretAdministration → Miljøer → <miljø>Jobs, der erklærer environment: <env>, på en branch eller et tag, som miljøet tillader, og kun de secrets, jobbet refererer til (nedenfor)

Rækkefølge: en miljø-secret går forud for en scoped secret bundet til et repository, som går forud for en scoped secret for hele organisationen, som går forud for en repo-secret, som går forud for en organisations-secret. Findes det samme navn i flere scopes, vinder det mest specifikke.

Oprettelse af secrets

Via brugerfladen: gå til det relevante scope, rul ned til Tilføj eller opdatér en secret, indtast navn (konventionen er UPPER_SNAKE_CASE) og værdi, og klik på Gem secret.

Via API’et:

# Org secret
curl -X PUT \
  -H "Authorization: Bearer <PAT>" \
  -H "Content-Type: application/json" \
  -d '{"name":"MY_SECRET","data":"the-value"}' \
  https://frem.sh/_app/api/v1/orgs/<org>/actions/secrets/MY_SECRET

# Repo secret
curl -X PUT \
  -H "Authorization: Bearer <PAT>" \
  -H "Content-Type: application/json" \
  -d '{"name":"MY_SECRET","data":"the-value"}' \
  https://frem.sh/api/v1/repos/<org>/<repo>/actions/secrets/MY_SECRET

Secrets kan kun skrives, når de er oprettet. Du kan ikke læse en secrets værdi tilbage via API’et eller brugerfladen; du kan kun overskrive eller slette den.

Brug af secrets i workflows

Henvis til secrets med ${{ secrets.NAME }}. Secrets er tilgængelige som miljøvariabler.

env:
  DATABASE_URL: ${{ secrets.DATABASE_URL }}

steps:
  - name: Deploy
    env:
      API_KEY: ${{ secrets.DEPLOY_API_KEY }}
    run: ./deploy.sh

Secrets maskeres i logs: al logoutput, der præcist matcher en secrets værdi, erstattes med ***. Maskeringen gælder kun præcise match; base64-kodede, URL-kodede eller på anden måde omformede varianter af værdien maskeres ikke automatisk.

Miljø-secrets og udrulningsgates

Jobs, der erklærer environment:, får kun de secrets, der hører til det miljø (plus repo- og organisations-secrets). Det er tilsigtet: miljø-secrets placerer produktionslegitimationsoplysninger bag miljøets godkendelsesflow.

jobs:
  deploy-prod:
    runs-on: fremforge
    environment: production   # triggers approval gate if reviewers are configured
    steps:
      - name: Deploy
        env:
          DB_URL: ${{ secrets.PROD_DB_URL }}   # environment secret on 'production'
        run: ./deploy.sh

Konfigurér påkrævede godkendere under Administration → Miljøer → <miljø>. Jobbet venter på godkendelse, før trinnet kører; secreten sendes først ind, når jobbet er godkendt og kører.

Miljønavne matches uden hensyn til store og små bogstaver, som i Forgejo og GitHub: environment: Production er miljøet production med dets branch-regel, godkendere og secrets. Hvis to miljøer kun adskiller sig ved store og små bogstaver, bruges det, der er stavet præcis som i jobbets erklæring; hvis ingen af dem er, får jobbet intet miljø, og dets udrulningsgate afviser det (environment_case_ambiguous). Omdøb et af dem.

En pull_request_target-kørsel fra en fork får intet miljø, ingen af dets secrets og ingen OIDC-claim, uanset hvad jobbet erklærer. Det er strengere end GitHub. Se Fork-PR secret reach.

Miljø-secrets når kun de jobs, der refererer til dem

Siden 2026-10-26 får et job kun en miljø-secret, når jobbet refererer til den: i sine egne trin, env:, with: eller if:, eller i env: på workflow-niveau, som ${{ secrets.NAME }} eller ${{ secrets['NAME'] }}. En secret, jobbet ikke refererer til, sendes slet ikke til dets runner og findes derfor ikke på den maskine, jobbet kører på.

${{ toJSON(secrets) }}, et beregnet navn som ${{ secrets[format('{0}_KEY', 'DEPLOY')] }} og secrets: inherit ved kald af et genbrugeligt workflow refererer til alle miljøets secrets, som på GitHub.

Et trin kan kun læse en secret gennem et sådant udtryk, så et workflow, der virker i dag, bliver ved med at virke: ændringen fjerner kun secrets, som intet trin kunne læse.

Hvis fremforge ikke kan læse jobbets workflowfil i jobbets commit eller ikke kan finde jobbet i den, får jobbet ingen af miljøets secrets. Jobbet kører stadig, med sit OIDC-token og sine variabler.

Hvem fik hvilken secret: læseauditten

Hvert CI-job, der får en miljø-secret eller en scoped secret, eller som refererer til en, det bliver nægtet, skriver én post i organisationens auditlog med handlingen ci.secret.read:

FeltVærdi
actorden person, der startede kørslen (organisationen, for en planlagt kørsel)
repository, repository_id, workflow, jobhvor det kørte
run_id, run_number, run_attempt, ref, eventhvilken kørsel
environmentdet miljø, jobbet erklærede
secretsNAVNENE på de secrets, jobbet fik, hver med sit scope (environment, repo eller org)
withheldnavne, jobbet refererede til, men ikke kunne få, hver med en årsag: workflow-unreadable eller job-not-found, og for en scoped secret det scope-felt, der afviste den (scope-workflow, scope-job, scope-ref, scope-event, scope-environment), eller undecryptable

En secrets værdi registreres aldrig, heller ikke som hash. Et job, der ikke refererer til nogen af miljøets secrets, får ingen og skriver ingen post.

Posten skrives, før secrets overdrages til runneren. Kan den ikke gemmes, får jobbet ingen af dem: ingen secret forlader fremforge uden at være registreret. fremforges vagt bliver tilkaldt, når det sker.

Forespørg posterne via API’et:

curl -H "Authorization: Bearer $FREMFORGE_TOKEN" \
  "https://frem.sh/_app/api/v1/orgs/<org>/audit?action=ci.secret.read&since=2026-10-26"

Posterne indgår i auditloggens hashkæde, dens opbevaring og dens SIEM-strøm, ligesom alle andre auditposter.

Repo- og organisations-secrets, der er sat i Forgejo, er ikke omfattet: Forgejo giver dem stadig til alle repositoriets jobs, og læsningen af dem registreres ikke. Brug i stedet en scoped CI-secret, og slet Forgejo-kopien med samme navn: så længe den findes, når den stadig de jobs, som scopet afviser.

Scoped CI-secrets

En scoped CI-secret opbevares af fremforge, for hele organisationen eller for ét repository, og gives kun til et job, når alle de felter i scopet, du har sat, matcher (inden for et felt er det nok, at én af de angivne værdier matcher):

FeltMatcherEksempel
workflowsworkflowfilens navndeploy.yaml, release-*.yml
jobsjob-id’et (nøglen under jobs:)deploy, publish-*
refsbranchen eller taggetrefs/heads/main, refs/tags/v*
eventsworkflowets triggerpush, workflow_dispatch, schedule, pull_request, pull_request_target, release
environmentjobbet erklærer dette miljø, på en branch eller et tag, som miljøet tilladerproduction

* er det eneste jokertegn. Et felt, du udelader, tillader alt, med én undtagelse: uden angivne events får en kørsel på en pull requests ref (refs/pull/...) aldrig secreten. Vil du give kode i en pull request en scoped secret, skal du eksplicit angive pull_request (eller pull_request_target).

Jobbet skal også referere til secreten (som ovenfor). Hver levering, og hver afvisning af en secret, jobbet refererede til, registreres i jobbets ci.secret.read-post. En pull request fra en fork får aldrig en.

Hvilke felter er en sikkerhedsgrænse. Alle, der kan pushe til repositoriet, kan oprette en branch, hvis workflow har et job ved navn deploy i en fil ved navn deploy.yaml, og starte det. workflows og jobs begrænser altså, hvilke kodestier der normalt får secreten, men de beskytter den ikke mod personer med skriveadgang. Det gør refs (peg den på beskyttede branches eller tags) og environment (med en branch-regel og påkrævede godkendere). Det er det samme som på GitHub.

En kørsel i merge-køen (refs/heads/fremforge-queue/...) er et build i samme repository, som en maintainer har sat i kø, og et tomt refs-scope tillader den ligesom enhver anden branch. Begræns refs, hvis en secret ikke må nå kørsler i merge-køen.

Jobs i et genbrugeligt workflow får endnu ikke scoped secrets, og det samme gælder, på en Forgejo-version der endnu ikke sender job-id’et, jobs med deres eget name: eller en matrix.

Opret eller erstat en (værdien kan kun skrives; hver ændring auditeres sammen med det scope, den erstattede):

curl -X PUT -H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
  -d '{"value":"...","workflows":["deploy.yaml"],"jobs":["deploy"],"refs":["refs/heads/main"],"events":["push","workflow_dispatch"]}' \
  "https://frem.sh/_app/api/v1/orgs/<org>/ci-secrets/DEPLOY_KEY?repository_id=<forgejo repository id>"

Udelad repository_id for en secret for hele organisationen. Et ukendt felt, et environment, der ikke er et navn, og et tomt listeelement afvises (400) i stedet for at blive ignoreret, så en tastefejl aldrig kan udvide en secret til alle jobs. GET /orgs/<org>/ci-secrets viser navne, scopes og hvornår hver blev læst sidst; DELETE .../ci-secrets/<NAME>[?repository_id=] fjerner en. Token-scopes: ci-secrets:read, ci-secrets:write. Grænser: 500 pr. organisation, 100 pr. repository, 20 mønstre pr. felt, 64 KB pr. værdi.

Vil du styre scoped CI-secrets som kode, så brug fremforge_ci_secret i fremforge-provideren (fra 0.9.0). Værdien er et write-only-argument og når aldrig Terraform-state.

Rotation af secrets

  1. Opret først den nye legitimationsoplysning i det eksterne system.
  2. Overskriv secreten i fremforge med den nye værdi. Slet og genopret den ikke.
  3. Start en ny workflow-kørsel for at bekræfte, at den nye legitimationsoplysning virker hele vejen igennem.
  4. Tilbagekald den gamle legitimationsoplysning i det eksterne system.

Overskrivning bevarer audit-sporet og undgår et vindue, hvor secreten mangler for jobs, der kører mellem sletning og genoprettelse.

Grænser

ElementGrænse
Maks. størrelse på en secrets værdi64 KB
Organisations-secrets1.000
Repo-secrets100 pr. repo
Miljø-secrets100 pr. miljø
Scoped CI-secrets500 pr. organisation, 100 pr. repository
Mønster for secret-navneBogstaver, tal og understregning; skal starte med et bogstav; må ikke starte med FORGEJO_ eller GITHUB_

OIDC som alternativ til secrets

Til udrulning hos cloududbydere (T Cloud Public, AWS, Azure, GCP) bør du overveje OIDC-tokenføderation i stedet for langtidsholdbare legitimationsoplysninger gemt som secrets. OIDC udsteder kortlivede tokens pr. job, afgrænset til den konkrete workflow-kørsel. Intet at rotere, intet at lække.

OIDC er det anbefalede mønster for alle jobs, der udruller til cloudinfrastruktur.

Krydshenvisninger