Erstellen verschlüsselter Geheimnisse
GitHub-Aktionen-Workflows benötigen häufig Zugriff auf vertrauliche Informationen wie API-Schlüssel, Kennwörter, Zertifikate und Token. GitHub bietet verschlüsselte Geheimschlüssel zum sicheren Speichern und Zugreifen auf diese vertraulichen Daten, ohne sie in Code- oder Workflowdateien verfügbar zu machen.
Grundlegendes zu GitHub-Geheimschlüsseln
GitHub-Schlüssel sind verschlüsselte Umgebungsvariablen, die Sie auf verschiedenen Ebenen innerhalb Ihrer GitHub-Organisation erstellen können. Nach der Erstellung werden geheime Schlüssel verschlüsselt und können nur während der Workflowausführung in autorisierten Kontexten entschlüsselt werden.
Wichtige Merkmale von GitHub-Geheimschlüsseln:
- Verschlüsselter Speicher: Alle geheimen Schlüssel werden mithilfe der Branchenstandardverschlüsselung verschlüsselt.
- Kontrollierter Zugriff: Nur autorisierte Workflows können auf geheime Schlüssel zugreifen
- In Protokollen maskiert: Geheime Werte werden automatisch in Workflowprotokollen maskiert
- Unveränderlich: Nach der Erstellung können geheime Werte nicht angezeigt werden, nur ersetzt
Geheime Bereiche und Hierarchien
Geheime Schlüssel auf Repositoryebene
Geheime Repositoryschlüssel sind nur für Workflows in diesem bestimmten Repository verfügbar:
# Using repository secret in workflow
name: Deploy Application
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to production
env:
API_KEY: ${{ secrets.PRODUCTION_API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_CONNECTION_STRING }}
run: |
echo "Deploying with API key starting with: ${API_KEY:0:8}..."
./deploy.sh
Geheimnisse auf Organisationsebene
Geheime Organisationsgeheimnisse können für mehrere Repositorys mit kontrolliertem Zugriff freigegeben werden:
# Organization secret with repository access control
name: Shared CI Pipeline
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run integration tests
env:
# This secret is available to authorized repositories
SHARED_TEST_API_KEY: ${{ secrets.INTEGRATION_TEST_API_KEY }}
run: |
npm test -- --api-key="$SHARED_TEST_API_KEY"
Geheimnisse auf Umgebungsebene
Geheime Umgebungsgeheimnisse bieten eine differenzierte Steuerung für Bereitstellungsumgebungen:
name: Multi-Environment Deploy
on:
push:
branches: [main, develop]
jobs:
deploy-staging:
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
environment: staging
steps:
- name: Deploy to staging
env:
# Environment-specific secrets
DEPLOYMENT_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
API_ENDPOINT: ${{ secrets.STAGING_API_URL }}
run: ./deploy.sh staging
deploy-production:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production
steps:
- name: Deploy to production
env:
DEPLOYMENT_KEY: ${{ secrets.PRODUCTION_DEPLOY_KEY }}
API_ENDPOINT: ${{ secrets.PRODUCTION_API_URL }}
run: ./deploy.sh production
Erstellen und Verwalten von Geheimnissen
Einrichtung von Repository-Geheimnissen
Navigieren Sie zu Repositoryeinstellungen:
- Wechseln Sie zu Ihrem Repository auf GitHub
- Klicken Sie auf die Registerkarte "Einstellungen".
- Auswählen Geheimnisse und Variablen>Aktionen
Neuen Repositoryschlüssel erstellen:
Name: PRODUCTION_API_KEY Value: your-actual-api-key-valueVerwendung im Workflow:
env: API_KEY: ${{ secrets.PRODUCTION_API_KEY }}
Verwaltung geheimer Organisationsgeheimnisse
# Example of organization secret usage with access policies
name: Organization-wide CI
on: [push]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- name: Security vulnerability scan
env:
# Organization secret with controlled repository access
SECURITY_SCAN_TOKEN: ${{ secrets.ORG_SECURITY_SCAN_TOKEN }}
run: |
security-scanner --token="$SECURITY_SCAN_TOKEN" .
Richtlinien für den geheimen Zugriff der Organisation:
- Alle Repositorys: Für alle Repositorys in der Organisation verfügbar
- Private Repositorys: Nur für private Repositorys verfügbar
- Ausgewählte Repositorys: Nur für speziell ausgewählte Repositorys verfügbar
Umgebungsgeheimnisse mit Schutzvorschriften
name: Protected Production Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: https://myapp.production.com
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy with environment protection
env:
# Protected by environment rules (approvals, wait timers)
PROD_DEPLOY_TOKEN: ${{ secrets.PRODUCTION_DEPLOY_TOKEN }}
PROD_DB_PASSWORD: ${{ secrets.PRODUCTION_DATABASE_PASSWORD }}
run: |
echo "Deploying to production environment..."
./scripts/deploy-production.sh
Bewährte Methoden für die Sicherheit von Geheimnissen
Geheime Benennungskonventionen
# Good: Clear, descriptive names
secrets:
PRODUCTION_API_KEY
STAGING_DATABASE_URL
AWS_ACCESS_KEY_ID
AZURE_CLIENT_SECRET
DOCKER_REGISTRY_TOKEN
# Avoid: Vague or generic names
secrets:
KEY
PASSWORD
TOKEN
SECRET
Prinzip des geringsten Privilegs
# Good: Specific secrets for specific purposes
name: Database Migration
jobs:
migrate:
runs-on: ubuntu-latest
steps:
- name: Run database migration
env:
# Read-only database connection for migrations
DB_MIGRATION_URL: ${{ secrets.DB_MIGRATION_CONNECTION }}
run: |
migrate up --database-url="$DB_MIGRATION_URL"
backup:
runs-on: ubuntu-latest
steps:
- name: Create database backup
env:
# Backup-specific credentials with limited scope
BACKUP_ACCESS_KEY: ${{ secrets.DB_BACKUP_ACCESS_KEY }}
run: |
backup-db --credentials="$BACKUP_ACCESS_KEY"
Geheimnisrotation und Lebenszyklusverwaltung
name: Secret Health Check
on:
schedule:
- cron: "0 6 * * 1" # Weekly on Monday at 6 AM
jobs:
check-secret-health:
runs-on: ubuntu-latest
steps:
- name: Test API key validity
env:
API_KEY: ${{ secrets.PRODUCTION_API_KEY }}
run: |
# Test if API key is still valid
response=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $API_KEY" \
https://api.example.com/health)
if [ "$response" != "200" ]; then
echo "API key may be expired or invalid"
# Create issue or notify team
gh issue create --title "API Key Health Check Failed" \
--body "The production API key failed health check. Response code: $response"
else
echo "API key is healthy"
fi
Bedingte geheime Verwendung
name: Flexible Secret Usage
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Run tests
env:
# Use different secrets based on event type
API_KEY: ${{ github.event_name == 'push' && secrets.INTEGRATION_API_KEY || secrets.TESTING_API_KEY }}
DATABASE_URL: ${{ github.ref == 'refs/heads/main' && secrets.PROD_DB_URL || secrets.TEST_DB_URL }}
run: |
echo "Running tests with appropriate credentials..."
npm test
Erweiterte geheime Muster
Geheime Schlüssel mit mehreren Werten (JSON-Konfiguration)
name: Complex Configuration
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Parse complex secret
env:
# Store complex configuration as JSON in secret
AWS_CONFIG: ${{ secrets.AWS_DEPLOYMENT_CONFIG }}
run: |
# Parse JSON secret
echo "$AWS_CONFIG" | jq -r '.access_key_id' > /tmp/aws_key
echo "$AWS_CONFIG" | jq -r '.secret_access_key' > /tmp/aws_secret
echo "$AWS_CONFIG" | jq -r '.region' > /tmp/aws_region
# Configure AWS CLI
aws configure set aws_access_key_id "$(cat /tmp/aws_key)"
aws configure set aws_secret_access_key "$(cat /tmp/aws_secret)"
aws configure set default.region "$(cat /tmp/aws_region)"
# Clean up temporary files
rm -f /tmp/aws_*
Geheime Vererbung und Zusammensetzung
name: Composed Secrets
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Build connection string
env:
DB_HOST: ${{ secrets.DATABASE_HOST }}
DB_USER: ${{ secrets.DATABASE_USER }}
DB_PASS: ${{ secrets.DATABASE_PASSWORD }}
DB_NAME: ${{ secrets.DATABASE_NAME }}
run: |
# Compose connection string from individual secrets
CONNECTION_STRING="postgresql://$DB_USER:$DB_PASS@$DB_HOST:5432/$DB_NAME"
# Use composed string (never log it)
echo "Connecting to database..."
psql "$CONNECTION_STRING" -c "SELECT version();"
Geheime Überprüfung und Tests
name: Secret Validation
jobs:
validate-secrets:
runs-on: ubuntu-latest
steps:
- name: Validate API credentials
env:
API_KEY: ${{ secrets.API_KEY }}
API_SECRET: ${{ secrets.API_SECRET }}
run: |
# Test API credentials without exposing values
if [ -z "$API_KEY" ] || [ -z "$API_SECRET" ]; then
echo "Missing required API credentials"
exit 1
fi
# Test key format (without revealing the key)
if [[ ${#API_KEY} -lt 32 ]]; then
echo "API key appears to be invalid (too short)"
exit 1
fi
# Test authentication
response=$(curl -s -w "%{http_code}" -o /dev/null \
-H "Authorization: Bearer $API_KEY" \
https://api.example.com/auth/test)
if [ "$response" = "200" ]; then
echo "API credentials validated successfully"
else
echo "API credential validation failed (HTTP $response)"
exit 1
fi
Häufige Fallstricke und Sicherheitsaspekte
Vermeiden der geheimen Exposition
# DON'T: Never echo or log secrets directly
- name: Bad secret usage
env:
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "Using API key: $API_KEY" # This will expose the secret!
# DO: Use secrets safely without exposure
- name: Safe secret usage
env:
API_KEY: ${{ secrets.API_KEY }}
run: |
# Use the secret without logging it
curl -H "Authorization: Bearer $API_KEY" https://api.example.com/data
echo "API request completed successfully"
Ordnungsgemäße Fehlerbehandlung
- name: Secure error handling
env:
DATABASE_PASSWORD: ${{ secrets.DATABASE_PASSWORD }}
run: |
# Set error handling to avoid secret leaks
set +x # Disable command echoing
if ! psql "postgresql://user:$DATABASE_PASSWORD@host/db" -c "SELECT 1"; then
# Log error without exposing secret
echo "Database connection failed"
exit 1
fi
echo "Database connection successful"
Geheimnisbereichsverwaltung
# Good: Limit secret scope to specific steps
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
# No secrets available here
- name: Deploy application
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} # Secret only in this step
run: |
./deploy.sh
- name: Run post-deploy tests
# No secrets available here
run: |
./test.sh
Die ordnungsgemäße geheime Verwaltung ist entscheidend für die Aufrechterhaltung der Sicherheit Ihrer CI/CD-Pipelines. Befolgen Sie immer das Prinzip der geringsten Rechte, verwenden Sie eine beschreibende Benennung, und implementieren Sie eine ordnungsgemäße Überprüfung, um sicherzustellen, dass Ihre geheimen Schlüssel sicher bleiben und gleichzeitig leistungsstarke Automatisierungsfunktionen ermöglichen.