Einführung
Beim Deployen auf AWS-Ressourcen von GitHub Actions war der traditionelle Ansatz das Speichern von IAM-Benutzer-Zugriffsschlüsseln in GitHub Secrets. Diese Methode hat jedoch mehrere Herausforderungen:
- Risiko des Zugriffsschlüssel-Lecks
- Regelmäßige Rotationsarbeiten erforderlich
- Zunahme zu verwaltender Secrets
OIDC (OpenID Connect)-Authentifizierung löst diese Herausforderungen. Dieser Artikel erklärt detailliert, wie die OIDC-Integration zwischen GitHub Actions und AWS eingerichtet wird.
Was ist OIDC?
OIDC ist ein Authentifizierungsprotokoll basierend auf OAuth 2.0. GitHub Actions gibt ein Token aus, das „Ich bin ein Workflow aus diesem Repository" gegenüber AWS beweisen kann, und AWS verifiziert es und stellt temporäre Credentials bereit.
Vorteile von OIDC
- Keine Secrets erforderlich: Keine Notwendigkeit, Zugriffsschlüssel in GitHub zu speichern
- Verbesserte Sicherheit: Verwendet nur temporäre Credentials
- Feinkörnige Berechtigungskontrolle: Berechtigungen können nach Repository oder Branch eingeschränkt werden
- Reduzierte Verwaltungskosten: Keine Schlüsselrotation erforderlich
AWS-Konfiguration
1. IAM Identity Provider erstellen
Erstellen Sie zunächst einen IAM Identity Provider in der AWS Management Console.
- IAM-Konsole öffnen
- „Identity providers" → „Add provider" klicken
- Folgende Informationen eingeben:
Provider type: OpenID Connect
Provider URL: https://token.actions.githubusercontent.com
Audience: sts.amazonaws.com
Beispiel mit Terraform
resource "aws_iam_openid_connect_provider" "github_actions" {
url = "https://token.actions.githubusercontent.com"
client_id_list = [
"sts.amazonaws.com",
]
thumbprint_list = [
"6938fd4d98bab03faadb97b34396831e3780aea1"
]
}
Beispiel mit AWS SAM
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: GitHub Actions OIDC Provider
Resources:
GitHubOIDCProvider:
Type: AWS::IAM::OIDCProvider
Properties:
Url: https://token.actions.githubusercontent.com
ClientIdList:
- sts.amazonaws.com
ThumbprintList:
- 6938fd4d98bab03faadb97b34396831e3780aea1
2. IAM-Rolle erstellen
Erstellen Sie als nächstes eine IAM-Rolle, die GitHub Actions übernehmen wird.
Trust Policy konfigurieren
{
"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"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:*"
}
}
}
]
}
Bedingungsdetails
Der Zugriff kann mit dem Wert token.actions.githubusercontent.com:sub eingeschränkt werden.
# Gesamtes spezifisches Repository
repo:your-org/your-repo:*
# Nur spezifischer Branch
repo:your-org/your-repo:ref:refs/heads/main
# Nur spezifische Umgebung
repo:your-org/your-repo:environment:production
# Nur Pull Requests
repo:your-org/your-repo:pull_request
Beispiel mit Terraform
data "aws_iam_policy_document" "github_actions_assume_role" {
statement {
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.github_actions.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:your-org/your-repo:*"]
}
}
}
resource "aws_iam_role" "github_actions" {
name = "github-actions-deploy-role"
assume_role_policy = data.aws_iam_policy_document.github_actions_assume_role.json
}
# Erforderliche Berechtigungsrichtlinien anhängen
resource "aws_iam_role_policy_attachment" "deploy_policy" {
role = aws_iam_role.github_actions.name
policy_arn = "arn:aws:iam::aws:policy/AmazonECS_FullAccess"
}
Beispiel mit AWS SAM
Resources:
GitHubActionsRole:
Type: AWS::IAM::Role
Properties:
RoleName: github-actions-deploy-role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Federated: !GetAtt GitHubOIDCProvider.Arn
Action: sts:AssumeRoleWithWebIdentity
Condition:
StringEquals:
token.actions.githubusercontent.com:aud: sts.amazonaws.com
StringLike:
token.actions.githubusercontent.com:sub: repo:your-org/your-repo:*
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonECS_FullAccess
Outputs:
GitHubActionsRoleArn:
Description: ARN der GitHub Actions IAM-Rolle
Value: !GetAtt GitHubActionsRole.Arn
Export:
Name: GitHubActionsRoleArn
Mit SAM deployen:
sam build
sam deploy --guided
Nach dem ersten Deployment die ausgegebene Rollen-ARN in GitHub Secrets als AWS_ROLE_ARN registrieren.
3. Berechtigungsrichtlinien anhängen
Hängen Sie die für das Deployment notwendigen Berechtigungen an die Rolle an. Zum Beispiel:
- Für S3-Deployment:
AmazonS3FullAccess - Für ECS-Deployment:
AmazonECS_FullAccess - Für Lambda:
AWSLambda_FullAccess
Für Produktionsumgebungen empfehlen wir die Erstellung benutzerdefinierter Richtlinien nach dem Prinzip der geringsten Berechtigung.
GitHub Actions-Konfiguration
Workflow-Datei erstellen
.github/workflows/deploy.yml erstellen.
name: Deploy to AWS
on:
push:
branches:
- main
# Berechtigungseinstellungen zum Abrufen des OIDC-Tokens (Wichtig!)
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy-role
aws-region: ap-northeast-1
- name: Deploy to S3
run: |
aws s3 sync ./dist s3://your-bucket-name --delete
- name: Verify deployment
run: |
aws s3 ls s3://your-bucket-name
Wichtige Punkte
1. permissions-Konfiguration
permissions:
id-token: write # Zum Abrufen des OIDC-Tokens erforderlich
contents: read # Zum Auschecken des Repositorys erforderlich
Ohne diese Einstellung kann das OIDC-Token nicht abgerufen werden und es tritt ein Fehler auf.
2. configure-aws-credentials-Aktionsversion
Verwenden Sie v4 oder später. Ältere Versionen unterstützen möglicherweise kein OIDC.
uses: aws-actions/configure-aws-credentials@v4
Praktisches Beispiel: SAM-Anwendung deployen
Hier ist ein Beispiel für das Deployen einer serverlosen Anwendung mit AWS SAM.
name: Deploy SAM Application
on:
push:
branches:
- main
permissions:
id-token: write
contents: read
env:
AWS_REGION: ap-northeast-1
SAM_STACK_NAME: my-sam-app
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Setup SAM CLI
uses: aws-actions/setup-sam@v2
with:
use-installer: true
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
- name: SAM Build
run: sam build --use-container
- name: SAM Deploy
run: |
sam deploy \
--stack-name ${{ env.SAM_STACK_NAME }} \
--capabilities CAPABILITY_IAM \
--resolve-s3 \
--no-fail-on-empty-changeset \
--no-confirm-changeset
- name: Get Stack Outputs
run: |
aws cloudformation describe-stacks \
--stack-name ${{ env.SAM_STACK_NAME }} \
--query 'Stacks[0].Outputs' \
--output table
Fehlerbehebung
Fehler: „Not authorized to perform sts:AssumeRoleWithWebIdentity"
Ursache: Trust-Policy-Bedingungen stimmen nicht überein
Lösung:
- Den
token.actions.githubusercontent.com:sub-Wert in der Trust Policy der IAM-Rolle überprüfen - Repository-Namen und Branch-Namen prüfen
- Den tatsächlichen
sub-Claim-Wert in den GitHub Actions-Logs prüfen
- name: Debug OIDC token
run: |
curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com" | \
jq -R 'split(".") | .[1] | @base64d | fromjson'
Fehler: „Error: Credentials could not be loaded"
Ursache: Fehlende permissions-Konfiguration
Lösung: Folgendes zur Workflow-Datei hinzufügen
permissions:
id-token: write
contents: read
Authentifizierung erfolgreich, aber Berechtigungsfehler
Ursache: Erforderliche Berechtigungsrichtlinien sind nicht an die IAM-Rolle angehängt
Lösung: Geeignete Richtlinien an die IAM-Rolle anhängen
aws iam attach-role-policy \
--role-name github-actions-deploy-role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
Sicherheits-Best-Practices
1. Prinzip der geringsten Berechtigung
Nur die minimal notwendigen Berechtigungen gewähren.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::your-specific-bucket",
"arn:aws:s3:::your-specific-bucket/*"
]
}
]
}
2. Nach Branch oder Tag einschränken
Produktions-Deployments auf spezifische Branches beschränken.
{
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
}
}
}
3. Rollen nach Umgebung trennen
Unterschiedliche Rollen für Entwicklung, Staging und Produktion verwenden.
- name: Configure AWS credentials (Production)
if: github.ref == 'refs/heads/main'
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN_PROD }}
aws-region: ap-northeast-1
- name: Configure AWS credentials (Development)
if: github.ref == 'refs/heads/develop'
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN_DEV }}
aws-region: ap-northeast-1
4. Mit CloudTrail auditieren
Alle API-Aufrufe aufzeichnen und regelmäßig überprüfen.
Fazit
Die OIDC-Integration zwischen GitHub Actions und AWS bietet folgende Vorteile:
- Sicheres Deployment ohne Zugriffsschlüssel
- Verwendet nur temporäre Credentials
- Feinkörnige Berechtigungskontrolle nach Repository oder Branch
- Reduzierte Verwaltungskosten
Obwohl die anfängliche Einrichtung etwas komplex ist, führt sie nach der Konfiguration zu langfristigen Verbesserungen in Sicherheit und Betriebsfähigkeit. Ich empfehle dringend, ihre Einführung zu erwägen.
