GitHub Actions Secrets 관리 방법
GitHub Actions에서 Secrets를 안전하게 관리하고 사용하는 방법을 알아봅니다.
GitHub Actions Secrets 관리 방법
GitHub Actions에서 Secrets는 민감한 정보(API 키, 비밀번호 등)를 안전하게 저장하고 워크플로우에서 사용할 수 있게 해줍니다.
Environment
$ gh --version
gh version 2.40.1 (2024-01-11)
$ gh auth status
github.com
✓ Logged in to github.com account joel-park (keyring)
- Active account: trueProblem: Secrets가 로그에 노출됨
# BAD PRACTICE - Never do this!
steps:
- name: Debug secrets
run: |
echo "API Key: $API_KEY" # Logged in plain text!
env:
API_KEY: ${{ secrets.API_KEY }}또는 Secrets를 제대로 사용하지 않아 빈 값이 전달됨:
# Common mistake
steps:
- name: Deploy
run: |
echo $API_KEY # Empty because env var name is wrong
env:
API_KEY: ${{ secrets.MISSING_SECRET }} # Returns emptyAnalysis: Secrets 동작 원리
# Secrets are encrypted at rest
# They are decrypted only during workflow run
# They are masked in logs (***)
# They cannot be downloaded from Actions UI
# Environment-level secrets
# Organization-level secrets
# Repository-level secrets# Check existing secrets
$ gh secret list
# List organization secrets
$ gh api orgs/{org}/actions/secrets
# List repository secrets
$ gh api repos/{owner}/{repo}/actions/secretsSolution: Secrets 안전한 관리 방법
방법 1: 기본 Secrets 사용
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to production
run: |
./deploy.sh
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
# This will be masked in logs
- name: Debug (safe)
run: |
echo "Deploying to $TARGET_ENV"
env:
TARGET_ENV: ${{ secrets.TARGET_ENV }}방법 2: 환경별 Secrets (Environments)
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- run: echo "Deploying to staging"
env:
API_URL: ${{ secrets.STAGING_API_URL }}
deploy-production:
runs-on: ubuntu-latest
environment: production
needs: deploy-staging
steps:
- run: echo "Deploying to production"
env:
API_URL: ${{ secrets.PRODUCTION_API_URL }}방법 3: Organization Secrets
# Shared across multiple repositories
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: |
curl -H "Authorization: Bearer ${{ secrets.SHARED_API_KEY }}" \
https://api.example.com/deploy# Set organization secret
$ gh secret set SHARED_API_KEY \
--org myorg \
--visibility selected \
--repos "repo1,repo2,repo3" \
--body "your-api-key"방법 4: Encrypted Secrets 사용
steps:
- name: Use encrypted secret
run: |
echo "Secret value is available but not logged"
echo $SECRET_VALUE | wc -c # Show length only
env:
SECRET_VALUE: ${{ secrets.MY_SECRET }}
# Never do this
# - run: echo $MY_SECRET # Security risk!방법 5: OIDC for Cloud Providers
# No long-lived secrets needed
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActions
aws-region: us-east-1
- run: aws s3 sync ./dist s3://my-bucketSecurity Best Practices
# 1. Limit permissions
permissions:
contents: read
actions: read
# 2. Use environment protection rules
environment:
name: production
protection-rules:
- type: required_reviewers
review_count: 2
# 3. Audit secret access
steps:
- name: Log secret usage (metadata only)
run: |
echo "Secret used at $(date)" >> $GITHUB_STEP_SUMMARYLessons Learned
로그 주의: Secrets가 로그에 노출되지 않도록 주의하세요. GitHub는 자동으로 마스킹하지만, 완전하지 않습니다.
Environment 활용: 환경별 Secrets을 사용하면 프로덕션 Secrets이 스테이징에서 사용되는 것을 방지할 수 있습니다.
OIDC 전환: AWS, GCP 등에서 장기 사용 자격증명 대신 OIDC를 사용하면 더 안전합니다.
최소 권한 원칙: Secrets에 접근할 수 있는 워크플로우의 권한을 최소화하세요.
정기 교체: Secrets는 정기적으로 교체하여 유출 시 피해를 최소화하세요.
This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.