비밀에 대한 정보
비밀은 조직, 리포지토리 또는 리포지토리 환경에서 만든 변수입니다. 만든 비밀은 GitHub Actions 워크플로에서 사용할 수 있습니다. GitHub Actions는 워크플로에 비밀을 명시적으로 포함하는 경우에만 비밀을 읽을 수 있습니다.
조직 수준에서 저장된 비밀의 경우 액세스 정책을 사용하여 조직 비밀을 사용할 수 있는 리포지토리를 제어할 수 있습니다. 조직 수준 비밀을 사용하면 여러 리포지토리 간에 비밀을 공유할 수 있으므로 중복 비밀을 만들 필요가 줄어듭니다. 또한 한 위치에서 조직 비밀을 업데이트하면 해당 비밀을 사용하는 모든 리포지토리 워크플로에서 변경 내용이 적용됩니다.
환경 수준에서 저장된 비밀의 경우 필요한 검토자가 비밀에 대한 액세스를 제어하도록 설정할 수 있습니다. 승인자가 승인할 때까지 워크플로 작업이 환경 비밀에 액세스할 수 없습니다.
Note
GitHub Actions 워크플로가 OIDC(OpenID Connect)를 지원하는 클라우드 공급자의 리소스에 액세스해야 하는 경우 클라우드 공급자에게 직접 인증하도록 워크플로를 구성할 수 있습니다. 이렇게 하면 이러한 자격 증명을 수명이 긴 비밀로 저장하지 않을 수 있고 다른 보안 이점을 제공할 수 있습니다. 자세한 내용은 "OpenID Connect를 사용한 보안 강화 정보"을 참조하세요.
비밀 이름 지정
비밀 이름에는 다음 규칙이 적용됩니다.
-
비밀 이름에는 영숫자 문자(
[a-z]
,[A-Z]
,[0-9]
) 또는 밑줄(_
)만 사용할 수 있습니다. 공백은 사용할 수 없습니다. -
비밀 이름은
GITHUB_
접두사로 시작할 수 없습니다. -
비밀 이름은 숫자로 시작할 수 없습니다.
-
이름은 대/소문자를 구분하지 않습니다.
-
비밀 이름은 해당 수준에서 고유해야 합니다.
예를 들어 환경 수준에서 만든 비밀에는 해당 환경에서 고유한 이름이 있어야 하고, 리포지토리 수준에서 만든 비밀에는 해당 리포지토리에 고유한 이름이 있어야 하며, 조직 수준에서 만든 비밀에는 해당 수준에서 고유한 이름이 있어야 합니다.
이름이 같은 비밀이 여러 수준에 있는 경우 가장 낮은 수준의 비밀이 우선적으로 적용됩니다. 예를 들어 조직 수준 비밀의 이름이 리포지토리 수준 비밀과 동일한 경우 리포지토리 수준 비밀이 우선 적용됩니다. 마찬가지로 조직, 리포지토리 및 환경 모두 이름이 같은 비밀이 있는 경우 환경 수준 암호가 우선적으로 적용됩니다.
GitHub가 로그에서 비밀을 수정하도록 하려면 정형 데이터를 비밀 값으로 사용하지 마세요. 예를 들어 JSON 또는 인코딩된 Git BLOB을 포함하는 비밀을 만들지 마세요.
비밀에 액세스
작업에 비밀을 사용할 수 있도록 하려면 워크플로 파일에서 비밀을 입력 또는 환경 변수로 설정해야 합니다. 작업의 추가 정보 파일을 검토하여 작업에 예상되는 입력 및 환경 변수에 대해 알아봅니다. 자세한 내용은 "GitHub Actions에 대한 워크플로 구문"을(를) 참조하세요.
파일을 편집할 수 있는 액세스 권한이 있는 경우 워크플로 파일에서 비밀을 사용하고 읽을 수 있습니다. 자세한 내용은 "GitHub의 액세스 권한"을(를) 참조하세요.
경고: 작업에서 비밀이 사용된 경우 GitHub는 로그에 출력된 비밀을 자동으로 수정합니다. 의도적으로 로그에 비밀을 출력하지 않아야 합니다.
워크플로 실행이 큐에 대기되면 조직 및 리포지토리 비밀을 읽고 환경을 참조하는 작업이 시작될 때 환경 비밀을 읽습니다.
REST API를 사용하여 비밀을 관리할 수도 있습니다. 자세한 내용은 "GitHub Actions 비밀에 대한 REST API 엔드포인트"을(를) 참조하세요.
자격 증명 권한 제한
자격 증명을 생성할 때 가능한 최소 권한을 부여하는 것이 좋습니다. 예를 들어 개인 자격 증명을 사용하는 대신 배포 키 또는 서비스 계정을 사용합니다. 필요한 모든 경우 읽기 전용 권한을 부여하고 가능한 한 액세스를 제한하는 것이 좋습니다.
personal access token (classic)을(를) 생성할 때 필요한 가장 적은 범위를 선택합니다. fine-grained personal access token을(를) 생성할 때 필요한 최소 권한 및 리포지토리 액세스를 선택합니다.
personal access token를 사용하는 대신 fine-grained personal access token와 유사하게 세분화된 권한과 짧은 수명의 토큰을 사용하는 GitHub App를 사용하는 것을 고려해 보세요. personal access token과 달리 GitHub App은 사용자와 연결되어 있지 않으므로 앱을 설치한 사용자가 조직을 떠나더라도 워크플로는 계속 작동합니다. 자세한 내용은 "GitHub Actions 워크플로에서 GitHub 앱을 사용하여 인증된 API 요청 만들기"을(를) 참조하세요.
Note
리포지토리에 대한 협력자 액세스 권한이 있는 사용자는 REST API를 사용하여 해당 리포지토리의 비밀을 관리할 수 있으며, 조직에 대한 관리자 액세스 권한이 있는 사용자는 REST API를 사용하여 해당 조직의 비밀을 관리할 수 있습니다. 자세한 내용은 "GitHub Actions 비밀에 대한 REST API 엔드포인트"을(를) 참조하세요.
리포지토리에 대한 비밀 만들기
리포지토리 소유자만 개인 계정 리포지토리의 GitHub에 비밀 또는 변수를 만들 수 있습니다. admin
액세스 권한이 있는 사용자만 조직 리포지토리에 대한 에 비밀 또는 변수를 만들 수 있습니다. 마지막으로, 협력자 액세스 권한이 있는 사용자만 REST API를 통해 개인 계정 리포지토리 또는 조직 리포지토리에 대한 비밀 또는 변수를 만들 수 있습니다.
-
GitHub에서 리포지토리의 기본 페이지로 이동합니다.
-
리포지토리 이름 아래에서 Settings(설정)를 클릭합니다. "설정" 탭이 표시되지 않으면 드롭다운 메뉴를 선택한 다음 설정을 클릭합니다.
-
사이드바의 "보안" 섹션에서 비밀 및 변수를 선택하고 작업을 클릭합니다.
-
비밀 탭을 클릭합니다.
-
새 리포지토리 비밀을 선택합니다.
-
이름 필드에 비밀의 이름을 입력합니다.
-
비밀 필드에 비밀 값을 입력합니다.
-
비밀 추가를 클릭합니다.
리포지토리에 환경 비밀이 있거나 부모 조직의 비밀에 액세스할 수 있는 경우 해당 비밀도 이 페이지에 나열됩니다.
Dependabot alerts의 자세한 내용은 “GitHub CLI 정보”를 참조하세요.
리포지토리 비밀을 추가하려면 gh secret set
하위 명령을 사용합니다. secret-name
을 비밀의 이름으로 바꿉니다.
gh secret set SECRET_NAME
CLI는 비밀 값을 입력하라는 메시지를 표시합니다. 또는 파일에서 비밀 값을 읽을 수 있습니다.
gh secret set SECRET_NAME < secret.txt
리포지토리에 대한 모든 비밀을 나열하려면 gh secret list
하위 명령을 사용합니다.
환경에 대한 비밀 만들기
개인 계정 리포지토리에서 환경에 대한 비밀 또는 변수를 만들려면 리포지토리 소유자여야 합니다. 조직 리포지토리에서 환경에 대한 비밀 또는 변수를 만들려면 admin
액세스 권한이 있어야 합니다. 환경에 대한 자세한 내용은 "배포 환경 관리"을 참조하세요.
-
GitHub에서 리포지토리의 기본 페이지로 이동합니다.
-
리포지토리 이름 아래에서 Settings(설정)를 클릭합니다. "설정" 탭이 표시되지 않으면 드롭다운 메뉴를 선택한 다음 설정을 클릭합니다.
-
왼쪽 사이드바에서 환경을 클릭합니다.
-
비밀을 추가할 환경을 클릭합니다.
-
환경 비밀에서 비밀 추가를 클릭합니다.
-
이름 입력 상자에 비밀의 이름을 입력합니다.
-
비밀 값을 입력합니다.
-
비밀 추가를 클릭합니다.
환경에 대한 비밀을 추가하려면 환경 이름 뒤에 --env
또는 -e
플래그가 있는 gh secret set
하위 명령을 사용합니다.
gh secret set --env ENV_NAME SECRET_NAME
환경에 대한 비밀을 나열하려면 환경 이름 뒤에 --env
또는 -e
플래그가 있는 gh secret list
하위 명령을 사용합니다.
gh secret list --env ENV_NAME
조직에 대한 비밀 만들기
조직에서 비밀 또는 변수를 만들 때, 정책을 사용하여 리포지토리별로 액세스를 제한할 수 있습니다. 예를 들어 모든 리포지토리에 대한 액세스 권한을 부여하거나 프라이빗 리포지토리 또는 지정된 리포지토리 목록에 대해서만 액세스를 제한할 수 있습니다.
조직 소유자 및 "조직 작업 변수 관리" 또는 "조직 작업 비밀 관리" 권한을 가진 사용자는 조직 수준에서 비밀 또는 변수를 만들 수 있습니다.
자세한 내용은 "사용자 지정 조직 역할 소개"을 참조하세요.
-
GitHub에서 조직의 기본 페이지로 이동합니다.
-
조직 이름에서 설정을 클릭합니다. "설정" 탭이 표시되지 않으면 드롭다운 메뉴를 선택한 다음 설정을 클릭합니다.
-
사이드바의 "보안" 섹션에서 비밀 및 변수를 선택하고 작업을 클릭합니다.
-
비밀 탭을 클릭합니다.
참고: "Actions 비밀 및 변수" 페이지에는 사용 권한에 따라 비밀 및 변수에 대한 고유한 탭이 표시되지 않을 수 있습니다. "조직 Actions 변수 관리" 및 "조직 Actions 비밀 관리" 권한이 있는 조직 소유자 및 사용자에게는 변수 및 비밀 탭이 표시됩니다. 자세한 내용은 "사용자 지정 조직 역할 소개"을(를) 참조하세요.
-
새 조직 비밀을 클릭합니다.
-
이름 입력 상자에 비밀의 이름을 입력합니다.
-
값 필드에 비밀 값을 입력합니다.
-
리포지토리 액세스 드롭다운 목록에서 액세스 정책을 선택합니다.
-
비밀 추가를 클릭합니다.
Note
기본적으로 GitHub CLI는 repo
및 read:org
범위를 인증합니다. 조직 비밀을 관리하려면 admin:org
범위에 추가로 권한을 부여해야 합니다.
gh auth login --scopes "admin:org"
조직에 대한 비밀을 추가하려면 조직 이름 뒤에 --org
또는 -o
플래그가 있는 gh secret set
하위 명령을 사용합니다.
gh secret set --org ORG_NAME SECRET_NAME
기본적으로 비밀은 프라이빗 리포지토리에서만 사용할 수 있습니다. 조직 내의 모든 리포지토리에서 비밀을 사용할 수 있도록 지정하려면 --visibility
또는 -v
플래그를 사용합니다.
gh secret set --org ORG_NAME SECRET_NAME --visibility all
조직 내의 선택된 리포지토리에서 비밀을 사용할 수 있도록 지정하려면 --repos
또는 -r
플래그를 사용합니다.
gh secret set --org ORG_NAME SECRET_NAME --repos REPO-NAME-1, REPO-NAME-2
조직에 대한 비밀을 나열하려면 조직 이름 뒤에 --org
또는 -o
플래그가 있는 gh secret list
하위 명령을 사용합니다.
gh secret list --org ORG_NAME
조직 수준 비밀에 대한 액세스 검토
조직의 비밀에 적용되는 액세스 정책을 확인할 수 있습니다.
-
GitHub에서 조직의 기본 페이지로 이동합니다.
-
조직 이름에서 설정을 클릭합니다. "설정" 탭이 표시되지 않으면 드롭다운 메뉴를 선택한 다음 설정을 클릭합니다.
-
사이드바의 "보안" 섹션에서 비밀 및 변수를 선택하고 작업을 클릭합니다.
-
비밀 목록에는 구성된 사용 권한 및 정책이 포함됩니다. 각 비밀에 대해 구성된 권한에 대한 자세한 내용을 보려면 업데이트를 클릭하세요.
워크플로에서 비밀 사용
Note
GITHUB_TOKEN
의 예외를 제외하고 포크된 리포지토리에서 워크플로가 트리거될 때 비밀이 실행기에게 전달되지 않습니다.- 비밀은 재사용 가능한 워크플로에 자동으로 전달되지 않습니다. 자세한 내용은 "워크플로 다시 사용"을(를) 참조하세요.
입력 또는 환경 변수로 비밀을 사용하여 작업을 제공하려면 secrets
컨텍스트를 사용하여 리포지토리에서 만든 비밀에 액세스할 수 있습니다. 자세한 내용은 "워크플로 실행에 대한 컨텍스트 정보에 액세스" 및 "GitHub Actions에 대한 워크플로 구문"을(를) 참조하세요.
steps:
- name: Hello world action
with: # Set the secret as an input
super_secret: ${{ secrets.SuperSecret }}
env: # Or as an environment variable
super_secret: ${{ secrets.SuperSecret }}
비밀은 if:
조건에서 직접 참조할 수 없습니다. 대신 비밀을 작업 수준 환경 변수로 설정한 다음 환경 변수를 참조하여 작업의 단계를 조건부로 실행하는 것이 좋습니다. 자세한 내용은 "워크플로 실행에 대한 컨텍스트 정보에 액세스" 및 jobs.<job_id>.steps[*].if
을(를) 참조하세요.
비밀이 설정되지 않은 경우 비밀을 참조하는 식의 반환 값(예: 예제의 ${{ secrets.SuperSecret }}
)은 빈 문자열이 됩니다.
가능하면 명령줄에서 프로세스 간에 비밀을 전달하지 마세요. 명령줄 프로세스는 다른 사용자에게 표시되거나(ps
명령을 사용) 보안 감사 이벤트에 의해 캡처될 수 있습니다. 비밀을 보호하려면 환경 변수, STDIN
또는 대상 프로세스에서 지원하는 기타 메커니즘을 사용하는 것이 좋습니다.
명령줄 내에서 비밀을 전달해야 하는 경우 적절한 따옴표로 묶습니다. 비밀에는 의도치 않게 셸에 영향을 줄 수 있는 특수 문자가 포함되어 있는 경우가 많습니다. 특수 문자를 이스케이프하려면 환경 변수와 함께 따옴표를 사용합니다. 예시:
npm을 사용한 예제
steps:
- shell: bash
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "$SUPER_SECRET"
PowerShell을 사용한 예제
steps:
- shell: pwsh
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "$env:SUPER_SECRET"
Cmd.exe를 사용한 예제
steps:
- shell: cmd
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "%SUPER_SECRET%"
비밀에 대한 제한
최대 1,000개의 조직 비밀, 100개의 리포지토리 비밀 및 100개의 환경 비밀을 저장할 수 있습니다.
리포지토리에서 만든 워크플로는 다음과 같은 수의 비밀에 액세스할 수 있습니다.
- 리포지토리 비밀 100개 전부.
- 리포지토리에 100개를 초과하는 조직 비밀에 대한 액세스 권한이 할당된 경우 워크플로는 처음 100개의 조직 비밀만 사용할 수 있습니다(비밀 이름을 기준으로 사전순으로 정렬됨).
- 환경 비밀 100개 전부.
비밀의 크기는 48KB로 제한됩니다. 더 큰 비밀을 저장하려면 아래의 “큰 비밀 저장” 해결 방법을 참조하세요.
큰 비밀 저장
48KB보다 큰 비밀을 사용하려면 비밀을 리포지토리에 저장하고 해독 암호를 GitHub에 비밀로 저장하는 방식으로 해결할 수 있습니다. 예를 들어 gpg
를 사용하여 GitHub의 리포지토리에 암호화된 파일을 체크 인하기 전에 로컬에서 비밀이 포함된 파일을 암호화할 수 있습니다. 자세한 내용은 gpg manpage를 참조하세요.
Warning
워크플로가 실행될 때 비밀이 인쇄되지 않도록 주의하세요. 이 해결 방법을 사용하는 경우 GitHub은 로그에 인쇄된 비밀을 수정하지 않습니다.
-
터미널에서 다음 명령을 실행하여
gpg
및 AES256 암호 알고리즘을 사용하여 암호가 포함된 파일을 암호화합니다. 이 예제에서my_secret.json
은 비밀을 포함하는 파일입니다.gpg --symmetric --cipher-algo AES256 my_secret.json
-
테이블 이름을 입력하라는 메시지가 표시됩니다. 암호를 값으로 사용하는 GitHub에 새 비밀을 만들어야 하므로 암호를 기억하세요.
-
암호를 포함하는 새 비밀을 만듭니다. 예를 들어
LARGE_SECRET_PASSPHRASE
라는 이름으로 새 비밀을 만들고 비밀 값을 위 단계에서 사용한 암호로 설정합니다. -
암호화된 파일을 리포지토리의 경로에 복사하고 커밋합니다. 이 예제에서 암호화된 파일은
my_secret.json.gpg
입니다.Warning
암호화되지 않은
my_secret.json
파일이 아니라.gpg
파일 확장자로 끝나는 암호화된my_secret.json.gpg
파일을 복사해야 합니다.git add my_secret.json.gpg git commit -m "Add new secret JSON file"
-
리포지토리에서 비밀 파일의 암호를 해독하는 셸 스크립트를 만듭니다. 이 예제에서 스크립트 이름은
decrypt_secret.sh
입니다.Shell #!/bin/sh # Decrypt the file mkdir $HOME/secrets # --batch to prevent interactive command # --yes to assume "yes" for questions gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" \ --output $HOME/secrets/my_secret.json my_secret.json.gpg
#!/bin/sh # Decrypt the file mkdir $HOME/secrets # --batch to prevent interactive command # --yes to assume "yes" for questions gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" \ --output $HOME/secrets/my_secret.json my_secret.json.gpg
-
리포지토리에 체크 인하기 전에 셸 스크립트가 실행 가능한지 확인합니다.
chmod +x decrypt_secret.sh git add decrypt_secret.sh git commit -m "Add new decryption script" git push
-
GitHub Actions 워크플로에서
step
을 사용하여 셸 스크립트를 호출하고 암호를 해독합니다. 워크플로가 실행되는 환경에서 리포지토리의 복사본을 만들려면actions/checkout
작업을 사용해야 합니다. 리포지토리의 루트에 상대적인run
명령을 사용하여 셸 스크립트를 참조합니다.name: Workflows with large secrets on: push jobs: my-job: name: My Job runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Decrypt large secret run: ./decrypt_secret.sh env: LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} # This command is just an example to show your secret being printed # Ensure you remove any print statements of your secrets. GitHub does # not hide secrets that use this workaround. - name: Test printing your secret (Remove this step in production) run: cat $HOME/secrets/my_secret.json
Base64 이진 BLOB을 비밀로 저장
Base64 인코딩을 사용하여 작은 이진 BLOB을 비밀로 저장할 수 있습니다. 그런 다음 워크플로에서 비밀을 참조하고 실행기에서 사용하기 위해 디코딩할 수 있습니다. 크기 제한에 대해서는 "GitHub Actions에서 비밀 사용"을(를) 참조하세요.
Note
Base64는 이진 파일만 텍스트로 변환하며 실제 암호화를 대체할 수 없습니다.
-
파일을 Base64 문자열로 인코딩하는 데
base64
를 사용합니다. 예시:macOS에서는 다음을 실행할 수 있습니다.
base64 -i cert.der -o cert.base64
Linux에서는 다음을 실행할 수 있습니다.
base64 -w 0 cert.der > cert.base64
-
Base64 문자열을 포함하는 비밀을 만듭니다. 예시:
$ gh secret set CERTIFICATE_BASE64 < cert.base64 ✓ Set secret CERTIFICATE_BASE64 for octocat/octorepo
-
실행기에서 Base64 문자열에 액세스하려면 비밀을
base64 --decode
으로 파이프합니다. 예시:name: Retrieve Base64 secret on: push: branches: [ octo-branch ] jobs: decode-secret: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Retrieve the secret and decode it to a file env: CERTIFICATE_BASE64: ${{ secrets.CERTIFICATE_BASE64 }} run: | echo $CERTIFICATE_BASE64 | base64 --decode > cert.der - name: Show certificate information run: | openssl x509 -in cert.der -inform DER -text -noout
Note
다른 셸을 사용하면 비밀을 파일로 디코딩하기 위해 다른 명령이 필요할 수 있습니다. Windows 실행기에서는 shell: bash
로 bash 셸을 사용하여 위 run
단계의 명령을 사용하는 것이 좋습니다.
워크플로 실행 로그에서 비밀 수정하기
GitHub Actions은(는) 워크플로 로그에 인쇄되는 모든 GitHub 비밀의 내용을 자동으로 수정합니다.
GitHub Actions은(는) 중요한 것으로 인식되지만 비밀로 저장되지 않은 정보를 수정합니다. 현재 GitHub은(는) 다음을 지원합니다.
- 32비트 및 64비트 Azure 키
- Azure AD 클라이언트 앱 암호
- Azure Cache 키
- Azure Container Registry 키
- Azure Function 호스트 키
- Azure Search 키
- 데이터베이스 연결 문자열
- HTTP 전달자 토큰 헤더
- JWT
- NPM 작성자 토큰
- NuGet API 키
- v1 GitHub 설치 토큰
- v2 GitHub 설치 토큰(
ghp
,gho
,ghu
,ghs
,ghr
) - v2 GitHub PAT
Note
다른 유형의 중요한 정보가 자동으로 수정되도록 하려면 커뮤니티 토론에서 Microsoft에 문의하세요.
모범 사례에서는 ::add-mask::VALUE
를 사용하여 GitHub 비밀이 아닌 모든 중요한 정보를 마스킹해야 합니다. 이렇게 하면 값이 비밀로 처리되고 로그에서 수정됩니다. 데이터 마스킹에 대한 자세한 내용은 "GitHub Actions에 대한 워크플로 명령" 항목을 참조하세요.
비밀 수정은 워크플로 실행기에서 수행됩니다. 즉, 비밀은 작업 내에서 사용되고 실행기에서 액세스할 수 있는 경우에만 수정됩니다. 수정되지 않은 비밀이 워크플로 실행 로그로 전송되는 경우 로그를 삭제하고 비밀을 회전해야 합니다. 사이트 삭제에 대한 자세한 내용은 "워크플로 실행 로그 사용" 항목을 참조하세요.