다음을 통해 공유


Azure Pipelines에서 비밀 보호

Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020

이 문서에서는 Azure Pipelines에서 비밀을 보호하는 모범 사례를 제공합니다. 비밀은 API 키, 암호, 인증서 또는 암호화 키 등에 대한 액세스를 엄격하게 제어하려는 항목입니다.

Azure Pipelines에서는 비밀 값을 생성하지 않습니다. 그러나 API 키와 같은 중요한 데이터를 저장하기 위해 파이프라인에 비밀을 추가해야 할 수 있습니다. 비밀 변수 설정에 대한 자세한 내용은 비밀 변수 설정을 참조하세요.

다른 방법을 사용할 수 있는 경우 비밀을 사용하지 마세요.

비밀을 보호하는 가장 좋은 방법은 처음에 비밀을 갖는 것이 아닙니다. 파이프라인이 비밀을 사용하여 작업을 수행하는 것과 다른 방법을 사용할 수 있는지 확인합니다.

  • 서비스 연결 사용:
    • Azure 또는 다른 서비스를 대상으로 하는 경우 변수에서 비밀을 관리하는 대신 서비스 연결을 사용합니다.
    • 서비스 연결을 사용하면 파이프라인 구성에서 중요한 정보를 직접 노출하지 않고도 외부 서비스에 안전하게 연결할 수 있습니다.
    • 자세한 내용은 서비스 연결 관리 및 Azure Resource Manager 서비스 연결을 사용하여 Microsoft Azure에 연결합니다.
  • 관리 ID 사용:

    • 비밀을 직접 처리하는 대신 관리 ID를 사용하는 것이 좋습니다.
    • 관리 ID를 사용하면 애플리케이션 및 서비스에서 명시적 자격 증명 없이 Azure 서비스를 사용하여 보안을 인증할 수 있습니다.
    • 관리 ID를 사용하여 다른 Azure 서비스에 액세스할 수 있습니다.
  • Azure CLI 작업:

    • Azure CLI 작업을 사용하는 경우 파이프라인에서 비밀을 명시적으로 전달하지 않고 스크립트의 서비스 주체 세부 정보에 액세스하는 설정을 사용하는 addSpnToEnvironment 것이 좋습니다.

자세한 내용은 서비스 주체 및 관리 ID 사용을 참조 하세요.

비밀 변수 사용

중요한 값을 Azure Pipelines .yml 파일에 일반 텍스트로 저장하지 마세요.

비밀 변수는 암호, ID 및 파이프라인에 노출하지 않으려는 기타 식별 데이터와 같은 개인 정보에 사용할 수 있습니다. Azure Key Vault를 사용하여 비밀 변수를 설정하는 것이 좋습니다. UI 또는 변수 그룹에서 비밀 변수를 설정할 수도 있습니다. 로깅 명령을 사용하여 비밀 변수를 설정하지 않는 것이 좋습니다. 로깅 명령을 사용하여 비밀을 설정하면 파이프라인에 액세스할 수 있는 모든 사용자가 비밀을 볼 수도 있습니다.

비밀 변수는 암호화되며 값을 노출하지 않고 파이프라인에서 사용할 수 있습니다. 해당 값은 노출되지 않지만 비밀을 출력으로 에코하지 않으며 명령줄에 비밀을 전달하지 않습니다. 대신 비밀을 환경 변수에 매핑하는 것이 좋습니다.

비밀을 만들 때 변수 명명 지침을 따르고 비밀 이름이 중요한 정보를 공개하지 않는지 확인합니다.

비밀 변수에 대한 액세스 제한

Azure DevOps에서 비밀에 대한 액세스를 제한하려면 다음 모범 사례를 따르세요.

  • Azure Key Vault비밀을 저장합니다. Azure Key Vault를 사용하면 Azure의 역할 기반 액세스 제어 모델을 사용하여 비밀 또는 비밀 그룹에 대한 액세스를 제한할 수 있습니다.
  • 파이프라인에 대한 UI에서 비밀 변수를 설정합니다. 파이프라인의 파이프라인 설정 UI에 설정된 비밀 변수는 설정된 파이프라인으로 범위가 지정됩니다. 따라서 해당 파이프라인에 대한 액세스 권한이 있는 사용자에게만 표시되는 비밀을 가질 수 있습니다.
  • 변수 그룹에서 비밀을 설정합니다. 변수 그룹은 라이브러리 보안 모델을 따릅니다. 라이브러리에서 새 항목을 정의할 수 있는 사용자와 기존 항목을 사용할 수 있는 사용자를 제어할 수 있습니다.

로그에 비밀 쓰기 안 함

Azure Pipelines는 가능한 한 로그에서 비밀을 스크러빙하려고 시도하지만 완벽하지는 않습니다. 콘솔에 비밀을 에코하거나, 명령줄 매개 변수에 사용하거나, 파일에 로깅하지 마세요. 중요한 정보를 출력하는 Azure CLI 명령을 사용하는 경우 주의해야 합니다. None output formatAzure CLI 호출Use none output format and retrieve security information to a secret variable에서 비밀을 검색해야 하는 경우 .

구조적 데이터를 비밀로 사용하지 마세요.

JSON, XML 또는 YAML과 같은 구조화된 데이터 형식을 사용하여 캐리지 리턴 \r, 줄 바꿈\n 등의 제어 문자를 비롯한 비밀 값을 캡슐화하지 마세요. 대신 각 중요한 값에 대한 개별 비밀을 만듭니다. 이 방법은 더 나은 편집 정확도를 보장하고 실수로 중요한 데이터를 노출할 위험을 최소화합니다.

비밀 처리 방법 감사

Azure Pipelines에서 비밀이 사용되는 방법을 감사하려면 다음 모범 사례를 따르세요.

  • 소스 코드 검토: 파이프라인을 호스팅하는 리포지토리의 소스 코드를 검사합니다. 비밀이 올바르게 처리되는지 확인하려면 파이프라인에서 사용되는 작업을 확인합니다. 예를 들어 비밀이 의도하지 않은 호스트로 실수로 전송되거나 로그 출력에 명시적으로 인쇄되지 않았는지 확인합니다.
  • 실행 로그 검사: 유효하고 잘못된 입력을 테스트한 후 파이프라인에 대한 실행 로그를 확인합니다. 비밀이 제대로 수정되고 노출되지 않는지 확인합니다. 경우에 따라 명령 또는 도구의 오류가 실수로 비밀을 오류 로그로 누출할 수 있습니다. Azure Pipelines는 로그에서 비밀을 스크러빙하려고 시도하지만 수동 검토는 여전히 필수적입니다.

비밀 감사 및 회전

비밀을 감사하고 회전하려면 다음 모범 사례를 따릅니다.

  • 등록된 비밀 검토: 파이프라인에 등록된 비밀을 주기적으로 평가합니다. 여전히 필요한지 확인하고 더 이상 필요하지 않은 것을 제거하여 혼란과 잠재적인 보안 위험을 줄일 수 있습니다.
  • 비밀 회전: 손상된 비밀을 악용할 수 있는 기간을 최소화하기 위해 정기적으로 비밀을 회전합니다. 비밀을 주기적으로 변경하여 보안을 강화합니다.
  • 올바른 인증 방법 선택
    • 사용되는 비밀 유형:
      • 개인용 액세스 토큰(PAT): 이러한 토큰은 인증에 사용됩니다. 올바른 인증 방법을 선택할 때 보안 모범 사례를 따릅니다. REST API를 사용하여 PAT를 관리할 수 있습니다.
      • 비밀 변수: 비밀 변수를 사용하여 API 키, 암호 또는 파이프라인 내의 다른 자격 증명과 같은 중요한 정보를 안전하게 저장합니다.
      • Azure Key Vault 비밀: Azure Key Vault를 사용하여 비밀을 안전하게 저장하고 관리합니다.
      • 서비스 연결: 이러한 서비스 연결을 통해 파이프라인이 외부 서비스(예: Azure, GitHub, Docker Hub)에 연결할 수 있습니다. 서비스 연결 비밀의 적절한 구성 및 보안 처리를 보장합니다.

YAML 템플릿 사용

파이프라인 YAML에 비밀 매개 변수가 있는 인라인 스크립트를 직접 포함하는 대신 템플릿을 사용합니다. 이 방법은 주요 파이프라인에서 중요한 정보를 추상화하여 보안을 강화합니다.

이 방법을 구현하려면 스크립트에 대한 별도의 YAML 파일을 만든 다음, 해당 스크립트를 별도의 보안 리포지토리에 저장합니다. 그런 다음 템플릿을 참조하고 YAML에서 비밀 변수를 매개 변수로 전달할 수 있습니다. 보안 변수는 Azure Key Vault, 변수 그룹 또는 파이프라인 UI에서 가져옵니다. 템플릿 사용에 대한 자세한 내용은 템플릿 사용 참조를 참조하세요.

분기 정책 및 변수 그룹 권한으로 비밀 제한

비밀이 분기에 연결되어 main 있고 임의 분기에 액세스할 수 없도록 하려면 변수 그룹 권한, 조건부 작업 삽입 및 분기 정책의 조합을 사용할 수 있습니다.

분기 정책을 사용하면 주 분기의 빌드만 허용하는 빌드 유효성 검사 정책을 적용할 수 있습니다. 그런 다음 변수 그룹 권한을 사용하여 권한 있는 파이프라인만 변수 그룹에 저장된 비밀에 액세스할 수 있도록 할 수 있습니다. 마지막으로 파이프라인의 조건을 사용하여 분기로 푸시 main 를 통해서만 변수 그룹을 참조할 수 있는지 확인할 수 있습니다.

jobs:
- job: ExampleJob
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - script: echo "This runs only for the main branch"
    displayName: 'Conditional Step'
  variables:
  - group: your-variable-group-name

다음 단계