Learn (Almost) Anything
КаталогСкачать курс

Автоматизация в GitHub

Как заменить long-lived cloud secrets на OIDC federation: trust relationship, claims, audience, short-lived tokens, AWS/Azure/GCP/Vault patterns и ограничения.

ruЭнциклопедия33 урока6 модулей9
GitHub actionsАвтоматизация в GitHubМодель workflowсостояние и артефактыматрицы и runtimeрелизы и environmentsПереиспользование и собственные actionsgovernance и эксплуатацияgithubactions

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
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 убирает long-lived cloud secret из GitHub: job получает временный token только после проверки trust policy у провайдера.

Как работает обмен

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 --delete

id-token: write здесь не даёт job права писать в репозиторий или cloud. Оно разрешает запросить OIDC token у GitHub. Реальные cloud-права задаются IAM policy у role. Это важное разделение с Permissions и GITHUB_TOKEN: GITHUB_TOKEN управляет доступом к GitHub API, а OIDC federation — доступом к внешней системе.

ИнтерактивРазбор OIDC-deploy по шагам#int-1
Шаг 1 из 51. Cloud trust сначала
В AWS/Azure/GCP/Vault сначала настраивается trust relationship: issuer GitHub, audience провайдера и условия на subject/claims. Без этого workflow не сможет обменять JWT на cloud token.
Короткий walkthrough того, где именно появляется доверие и где чаще всего ошибаются.

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-west1

Vault немного отличается: он часто не деплоит сам, а выдаёт секреты на короткий 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

Внешние справки: GitHub Docs по OpenID Connect, OIDC reference, AWS OIDC, Azure OIDC, Google Cloud OIDC и HashiCorp Vault OIDC.

Быстрое повторение #rc-1

Почему OIDC federation в GitHub Actions безопаснее, чем хранить AWS_ACCESS_KEY_ID, JSON service account key или Azure client secret в GitHub Secrets?

Показать ответ

Workflow не хранит long-lived cloud key. Job получает GitHub OIDC JWT и обменивает его у cloud provider на short-lived access token только если claims проходят trust policy.

Источники

  1. GitHub Docs: OpenID Connect
  2. GitHub Docs: OpenID Connect reference
  3. GitHub Docs: Configuring OpenID Connect in Amazon Web Services
  4. GitHub Docs: Configuring OpenID Connect in Azure
  5. GitHub Docs: Configuring OpenID Connect in Google Cloud Platform
  6. GitHub Docs: Configuring OpenID Connect in HashiCorp Vault
  7. YouTube: Securely deploy to AWS with GitHub Actions and OIDC