Röviden: A hosszú életű AWS access key a CI-ben időzített bomba. Megmutatom, hogyan cseréld le rövid életű, OIDC-alapú tokenekre: OIDC provider, IAM-role bizalmi feltétellel és egy biztonságos deploy-workflow — végig Terraformmal.
Ha a CI/CD pipeline-od egy AWS_ACCESS_KEY_ID és AWS_SECRET_ACCESS_KEY párra épül a repo titkaiban, egy időzített bombán ülsz. Ezek hosszú életű kulcsok: ha kiszivárognak (log, fork, elgépelt secret), a támadó a lejáratig hozzáfér a fiókodhoz. A modern megoldás az OIDC: a GitHub Actions futásidőben, aláírt tokennel igazolja magát az AWS-nek, cserébe rövid életű, percekig élő credentialt kap. Nincs tárolt titok, nincs mit ellopni. Ebben a cikkben végigállítjuk ezt — Terraformmal.
Hogyan működik az OIDC bizalom?
Az AWS-ben létrehozol egy OIDC identity providert, ami megbízik a GitHub token-kibocsátójában. Amikor egy workflow fut, a GitHub kiállít egy JWT-t, amiben benne van, melyik repóból és melyik branchről/környezetből indult. Az AWS ezt ellenőrzi egy IAM-role bizalmi feltétele alapján, és csak akkor ad ideiglenes credentialt, ha a feltétel illeszkedik.
Miért jobb ez a hosszú életű kulcsnál?
A különbség nem árnyalatnyi, hanem kategóriabeli: nincs mit ellopni, és ha mégis, percekig ér valamit.
| Szempont | Hosszú életű access key | OIDC + rövid token |
|---|---|---|
| Tárolt titok | igen (repo secret) | nincs |
| Élettartam | amíg nem forgatod | ~1 óra |
| Szivárgás hatása | teljes hozzáférés lejáratig | percekig, szűk scope |
| Hatókör szűkítése | manuális | repo/branch/env szinten |
| Forgatás | kézi / ütemezett | nem kell |
Az OIDC provider és a role Terraformban
Először az OIDC providert hozzuk létre, ami megbízik a GitHub kibocsátójában. A thumbprintet a modern AWS már maga is kezeli, de a client_id_list-ben a sts.amazonaws.com audience kell.
data "tls_certificate" "github" {
url = "https://token.actions.githubusercontent.com/.well-known/openid-configuration"
}
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = [data.tls_certificate.github.certificates[0].sha1_fingerprint]
}Most jön a lényeg: a role bizalmi feltétele. Ez pontosan megköti, hogy CSAK a te repód main ágáról indított futás veheti fel a role-t.
data "aws_iam_policy_document" "trust" {
statement {
actions = ["sts:AssumeRoleWithWebIdentity"]
effect = "Allow"
principal {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.github.arn]
}
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
values = ["repo:${var.github_org}/${var.github_repo}:ref:refs/heads/main"]
}
}
}
resource "aws_iam_role" "deploy" {
name = "${var.project}-gha-deploy"
assume_role_policy = data.aws_iam_policy_document.trust.json
max_session_duration = 3600
tags = local.tags
}A deploy-jogosultság szűkre szabása
A role csak azt tudja, amire a pipeline-nak valóban szüksége van. Példaként egy statikus site deployhoz S3-írás és CloudFront-invalidáció kell — semmi több. Ne csábulj el a kényelmes AdministratorAccess-hez.
data "aws_iam_policy_document" "deploy_perms" {
statement {
sid = "S3Sync"
actions = ["s3:PutObject", "s3:DeleteObject", "s3:ListBucket"]
resources = [
var.site_bucket_arn,
"${var.site_bucket_arn}/*",
]
}
statement {
sid = "CloudFrontInvalidate"
actions = ["cloudfront:CreateInvalidation"]
resources = [var.distribution_arn]
}
}
resource "aws_iam_role_policy" "deploy_perms" {
name = "deploy-perms"
role = aws_iam_role.deploy.id
policy = data.aws_iam_policy_document.deploy_perms.json
}A GitHub Actions workflow
A workflow oldalán a kulcs a permissions: id-token: write (e nélkül a GitHub nem állít ki OIDC tokent) és a hivatalos aws-actions/configure-aws-credentials action, ami elvégzi az AssumeRoleWithWebIdentity hívást. Sehol egy tárolt kulcs.
name: deploy
on:
push:
branches: [main]
permissions:
id-token: write # OIDC token kiállításához kötelező
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: AWS credential OIDC-vel
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/myproj-gha-deploy
aws-region: eu-central-1
- name: Build
run: npm ci && npm run build
- name: Deploy S3-ba
run: aws s3 sync ./dist s3://my-site-bucket --delete
- name: CloudFront invalidáció
run: |
aws cloudfront create-invalidation \
--distribution-id E123ABC456DEF \
--paths "/*"Gyakori buktatók
- **Hiányzó
id-token: write** — a leggyakoribb hiba; enélkül nincs OIDC token, és rejtélyes hitelesítési hibát kapsz. - **Túl tág
subfeltétel** —repo:org/*vagy hiányzó ref: bárki felveheti a role-t. - Régió-eltérés — a
configure-aws-credentialsrégiója és a deploy-célok régiója nem stimmel. - **
AdministratorAccessa role-on** — kényelmes, de pontosan az a széles hatókör, amit az OIDC-vel el akartál kerülni.
Mit jelent ez neked?
Az OIDC-alapú deploy megszünteti a CI/CD legnagyobb, csendes kockázatát: a repóban heverő hosszú életű AWS-kulcsot. Cserébe rövid életű, szűk hatókörű, repóhoz és branchhez kötött tokent kapsz — nincs mit forgatni, nincs mit ellopni. A beállítás egyszeri munka Terraformban: OIDC provider, egy pontos bizalmi feltétel, és a valódi igényre szabott jogosultság. Ha ma egyetlen dolgot változtatsz a pipeline-odon, ez legyen az. A régi access key-eket pedig — miután az OIDC működik — töröld, ne csak hagyd ott „biztos, ami biztos” alapon.