Cloud deploy через OIDC
Как заменить long-lived cloud secrets на OIDC federation: trust relationship, claims, audience, short-lived tokens, AWS/Azure/GCP/Vault patterns и ограничения.
Cloud deploy через OIDC
Cloud deploy через OIDC — это способ дать workflow временный доступ к AWS, Azure, Google Cloud, Vault или другому провайдеру без хранения long-lived cloud keys в GitHub Secrets. Вместо AWS_ACCESS_KEY_ID, JSON service account key или Azure client secret job запрашивает у GitHub OIDC JWT, а cloud provider обменивает его на короткоживущий access token, если claims в JWT совпали с заранее настроенным trust relationship.
Это продолжает темы из Environments и protection rules, Deployment workflows и Packages и container images. Там job уже был опасной точкой: он публикует image, деплоит в production или читает секреты. OIDC меняет не сам deploy, а способ аутентификации: секрет не лежит в репозитории, а выдаётся «по факту» конкретному job.
sequenceDiagram
participant J as GitHub Actions job
participant G as GitHub OIDC provider
participant C as Cloud provider
participant R as Cloud role/resource
J->>G: Запрашивает OIDC JWT (id-token: write)
G-->>J: JWT с iss, aud, sub и claims
J->>C: Передает JWT в AWS/Azure/GCP/Vault
C->>C: Проверяет issuer, audience, subject, claims
C-->>J: Выдает короткоживущий access token
J->>R: Выполняет deploy с правами cloud roleКак работает обмен
OIDC в GitHub Actions держится на четырёх деталях: issuer, audience, subject и claims. Issuer у GitHub — https://token.actions.githubusercontent.com. Audience (aud) показывает, для кого предназначен token: например, для AWS с официальным action обычно используют sts.amazonaws.com, для Azure часто api://AzureADTokenExchange. Subject (sub) описывает, какой repo, branch, tag или environment пытается получить доступ. Дополнительные claims вроде repository, repository_id, workflow_ref, environment, runner_environment и job_workflow_ref дают больше материала для policy.
Минимальная мысль такая: cloud role не должен доверять «GitHub Actions вообще». Он должен доверять, например, только acme/api при job с environment: production, после approval, с branch/tag restrictions из Environments и protection rules. Поэтому OIDC почти всегда ставят вместе с environment gates, permissions, pinning сторонних actions и аккуратным Runner governance.
AWS: IAM role и sub
В AWS схема обычно такая: создать IAM OIDC identity provider для https://token.actions.githubusercontent.com, затем IAM role с trust policy, где проверяются aud и sub. GitHub Docs отдельно подчёркивают: в trust policy нужно задавать хотя бы одно условие, иначе чужой или неожиданный workflow может попытаться получить token для вашей role.
Пример trust policy для deploy из environment prod:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:acme/api:environment:prod"
}
}
}
]
}А workflow выглядит почти как обычный deploy, только без AWS access key:
name: deploy-aws
on:
release:
types: [published]
permissions:
contents: read
id-token: write
jobs:
deploy:
runs-on: ubuntu-24.04
environment: prod
steps:
- uses: actions/checkout@v6
- uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-prod-deploy
aws-region: eu-central-1
- run: aws s3 sync ./dist s3://acme-prod-site --deleteid-token: write здесь не даёт job права писать в репозиторий или cloud. Оно разрешает запросить OIDC token у GitHub. Реальные cloud-права задаются IAM policy у role. Это важное разделение с Permissions и GITHUB_TOKEN: GITHUB_TOKEN управляет доступом к GitHub API, а OIDC federation — доступом к внешней системе.
Azure, Google Cloud и Vault
В Azure trust задаётся через federated credential у Entra ID application/service principal или managed identity. В workflow обычно используются azure/login и три идентификатора: client ID, tenant ID, subscription ID. Это не пароль, но всё равно чувствительная конфигурация; часто её кладут в vars или secrets по внутренней политике.
permissions:
contents: read
id-token: write
jobs:
deploy:
runs-on: ubuntu-24.04
environment: production
steps:
- uses: azure/login@8c334a195cbb38e46038007b304988d888bf676a
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- run: az webapp deploy --resource-group rg-prod --name api-prod --src-path app.zipВ Google Cloud это называется Workload Identity Federation. Обычно создают workload identity pool/provider, настраивают attribute mapping и condition, затем дают service account право roles/iam.workloadIdentityUser. В workflow google-github-actions/auth обменивает GitHub OIDC token на Google Cloud credentials.
permissions:
contents: read
id-token: write
jobs:
deploy:
runs-on: ubuntu-24.04
environment: production
steps:
- uses: google-github-actions/auth@v2
with:
workload_identity_provider: projects/123/locations/global/workloadIdentityPools/github/providers/actions
service_account: deployer@acme-prod.iam.gserviceaccount.com
- run: gcloud run deploy api --image europe-docker.pkg.dev/acme-prod/api/api:${{ github.sha }} --region europe-west1Vault немного отличается: он часто не деплоит сам, а выдаёт секреты на короткий TTL. Vault JWT auth method доверяет GitHub issuer, проверяет bound_claims вроде repository или environment, затем выдаёт Vault token с policy на конкретные paths. Это полезно, когда legacy-интеграция ещё требует пароль, но пароль не должен жить в GitHub Secrets. Связь с Variables, env и secrets здесь прямая: OIDC не отменяет секреты вообще, он переносит их хранение в систему, где есть TTL, audit log и policy.
Где OIDC ломают
Первая ошибка — слишком широкий sub: repo:acme/api:* удобен, но он может разрешить не только production deploy, а ещё pull request branch, test workflow или ручной run. Для production лучше привязываться к environment, а сам environment защищать required reviewers, wait timer и branch/tag restrictions.
{
"bad": "repo:acme/api:*",
"better": "repo:acme/api:environment:prod"
}Вторая ошибка — считать, что OIDC защищает от вредного кода внутри доверенного job. Если workflow сначала делает checkout untrusted PR-кода, а потом получает cloud credentials, проблема не в OIDC, а в модели выполнения. Для pull request сценариев держите deploy credentials подальше от pull_request, особенно от pull_request_target; это уже территория pull_request_target и untrusted PR и Secure use и threat model.
Третья ошибка — доверять action по mutable tag. Если azure/login, aws-actions/configure-aws-credentials или другой deploy action получит опасное обновление, он стоит ровно перед выдачей cloud token. В production pinning к SHA из Marketplace actions и pinning не бюрократия, а часть цепочки доверия.
Практическое правило
Хорошая OIDC-конфигурация читается как предложение: «только этот repo, только этот workflow или environment, только после environment protection, только на этот cloud role, только с минимальными правами». Если в policy нельзя быстро ответить, какой именно job получит доступ, она слишком широкая.
Для больших организаций часто выносят cloud auth в Reusable workflows: продуктовые репозитории вызывают стандартизованный deploy workflow, а platform team держит trust policy, pinning и аудит в одном месте. Это не заменяет review конкретных cloud permissions, но снижает хаос: меньше copy-paste YAML, меньше случайных secrets, понятнее Monitoring и troubleshooting, когда deploy не получил token.
See also
- OIDC и секреты облаков — security-модель OIDC claims, secret rotation и cloud federation.
- Environments и protection rules — approval, wait timers и branch/tag restrictions перед выдачей deploy-доступа.
- Deployment workflows — как встроить OIDC в deploy after CI, promotion и rollback jobs.
- Permissions и GITHUB_TOKEN — почему
id-token: writeнужно выдавать точечно. - Marketplace actions и pinning — как закреплять cloud login actions к SHA.
- Runner governance — почему self-hosted runners меняют threat model для cloud deploy.
- Monitoring и troubleshooting — диагностика denied claims, неправильного audience и неработающих trust policies.
Внешние справки: GitHub Docs по OpenID Connect, OIDC reference, AWS OIDC, Azure OIDC, Google Cloud OIDC и HashiCorp Vault OIDC.
Источники
- GitHub Docs: OpenID Connect
- GitHub Docs: OpenID Connect reference
- GitHub Docs: Configuring OpenID Connect in Amazon Web Services
- GitHub Docs: Configuring OpenID Connect in Azure
- GitHub Docs: Configuring OpenID Connect in Google Cloud Platform
- GitHub Docs: Configuring OpenID Connect in HashiCorp Vault
- YouTube: Securely deploy to AWS with GitHub Actions and OIDC
