다음을 통해 공유


Azure Pipelines을 안전하게 보호하십시오

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

파이프라인은 스크립트를 실행하고 프로덕션 환경에 코드를 배포하기 위한 강력한 기능을 제공하지만 보안과 이 기능의 균형을 맞추는 것이 중요합니다. 파이프라인이 악성 코드의 통로가 되는 것을 원하지 않습니다. 개발 팀이 필요로 하는 유연성과 성능과 보안의 균형을 맞추는 것이 필수적입니다.

이 문서에서는 위협 및 취약성으로부터 파이프라인을 보호하는 데 필요한 보안 관련 구성에 대한 개요를 제공합니다.

필수 조건

범주 요구 사항
Azure DevOps - Azure DevOps 보안을 위해 권장 사항을 구현합니다.
- YAML 및 Azure Pipelines에 대한 기본 지식 자세한 내용은 첫 번째 파이프라인 만들기를 참조하세요.
권한 - 파이프라인 사용 권한을 수정하려면: 프로젝트 관리자 그룹의 구성원입니다.
- 조직 권한을 수정하려면 : 프로젝트 컬렉션 관리자 그룹의 구성원입니다.

프로젝트, 리포지토리 및 서비스 연결 액세스 제한

보안을 강화하려면 프로젝트를 분리하고 분기 정책을 사용하며 포크에 대한 보안 조치를 추가하는 것이 좋습니다. 서비스 연결 범위를 최소화하고 가장 안전한 인증 방법을 사용합니다.

  • 개별 프로젝트: 개별 프로젝트에서 각 제품 및 팀을 관리합니다. 이를 통해 한 제품의 파이프라인이 우연히 다른 제품의 열린 리소스에 접근하는 것을 방지하여 횡적 노출을 최소화할 수 있습니다.
  • 프로젝트 수준 ID 사용: 컬렉션 수준 ID 대신 파이프라인에 프로젝트 기반 빌드 ID를 사용합니다. 프로젝트 수준 ID는 연결된 프로젝트 내의 리소스에만 액세스할 수 있으므로 악의적인 행위자의 무단 액세스 위험을 최소화할 수 있습니다. 자세한 내용은 범위가 지정된 빌드 ID작업 권한 부여 범위를 참조하세요.
  • 분기 정책 사용: 코드 및 파이프라인을 안전하게 변경하려면 사용 권한 및 분기 정책을 적용합니다. 또한 리포지토리에 파이프라인 권한 및 검사를 추가하는 것이 좋습니다.
  • 포크에 대한 추가 보안 추가: GitHub의 공용 리포지토리를 사용하는 경우 포크 빌드에 대한 접근 방식을 신중하게 고려합니다. 조직 외부에서 발생하는 포크는 특정 위험을 초래합니다.
    • 포크 빌드에 대한 비밀을 제공하지 마세요. 기본적으로 파이프라인은 포크를 빌드하도록 구성되지만 비밀 및 보호된 리소스는 해당 파이프라인의 작업에 자동으로 노출되지 않습니다. 보안을 유지하기 위해 이 보호를 사용하지 않도록 설정하지 않는 것이 중요합니다.
    • 포크 빌드를 수동으로 트리거하는 것이 좋습니다. 자동 포크 빌드를 해제하고 끌어오기 요청 주석을 사용하여 이러한 기여를 수동으로 빌드합니다. 이 설정을 사용하면 빌드를 트리거하기 전에 코드를 검토할 수 있습니다. 자세한 내용은 자동 포크 빌드 해제를 참조하세요.
    • 포크 빌드에 대한 비밀을 제공하지 마세요. 기본적으로 파이프라인과 연결된 비밀은 포크의 끌어오기 요청 유효성 검사에 사용할 수 없습니다. 포크 빌드에 비밀을 사용할 수 있도록 하는 옵션을 사용하도록 설정하지 마세요. 이 설정을 찾고 확인하는 방법에 대한 지침은 포크의 기여를 참조하세요.
    • 포크 빌드를 수동으로 트리거하는 것이 좋습니다. 자동 포크 빌드를 해제하고 끌어오기 요청 주석을 사용하여 이러한 기여를 수동으로 빌드합니다. 이 설정을 사용하면 빌드를 트리거하기 전에 코드를 검토할 수 있습니다. 이 작업을 수행하는 방법에 대한 지침은 자동 포크 빌드 해제를 참조하세요.
    • 포크 빌드에 Microsoft 호스팅 에이전트 사용: 자체 호스팅 에이전트의 포크에서 빌드를 실행하지 않습니다. 이렇게 하면 외부 조직이 회사 네트워크 내의 컴퓨터에서 외부 코드를 실행할 수 있습니다. 가능하면 Microsoft 호스팅 에이전트를 사용합니다.
    • 토큰 범위 제한에 Azure Pipelines GitHub 앱을 사용합니다. GitHub 포크된 끌어오기 요청을 빌드할 때 Azure Pipelines는 파이프라인이 GitHub 리포지토리 콘텐츠를 변경할 수 없도록 합니다. 이 제한은 Azure Pipelines GitHub 앱을 사용하여 GitHub와 통합하는 경우에만 적용됩니다.

보안 서비스 연결

  • 서비스 연결 범위 최소화: 서비스 연결은 필요한 리소스에만 액세스할 수 있어야 합니다. 새 Azure Resource Manager 서비스 연결을 만들 때는 항상 특정 리소스 그룹을 선택합니다. 리소스 그룹에 빌드에 필요한 VM 또는 리소스만 포함되어 있는지 확인합니다. 서비스 연결을 설정하는 방법에 대한 지침은 Azure Resource Manager 서비스 연결 사용을 참조하세요.
  • 인증에 워크로드 ID 페더레이션 사용: 가능하면 Azure 서비스 연결에 대한 서비스 주체 대신 워크로드 ID 페더레이션을 사용합니다. 워크로드 ID 페더레이션은 업계 표준 기술인 OIDC(Open ID Connect)를 사용하여 비밀에 의존하지 않고 Azure와 Azure DevOps 간의 인증을 용이하게 합니다. 이 작업을 수행하는 방법에 대한 지침은 워크로드 ID 페더레이션(자동)을 사용하여 서비스 연결 만들기를 참조하세요.
  • GitHub 앱 액세스 최소화: Azure DevOps에 GitHub 앱을 구성할 때 파이프라인을 사용하여 빌드하려는 리포지토리에만 액세스 권한을 부여합니다.

클래식 파이프라인 대신 YAML 파이프라인 사용

보안을 추가하고 실수로 잘못된 구성의 위험을 줄이려면 클래식 파이프라인 대신 YAML 파이프라인을 사용합니다. 이 예방 조치는 서비스 연결과 같은 동일한 리소스를 공유하는 YAML 및 클래식 파이프라인에서 발생하는 보안 문제를 방지합니다. 조직에서 클래식 파이프라인을 사용하는 경우 파이프라인을 YAML로 마이그레이션합니다.

  • YAML은 코드로 인프라의 이점을 제공합니다. 단계 및 종속성이 코드에 정의되어 있기 때문에 YAML 파이프라인을 다른 코드와 같이 처리합니다. 파이프라인 구성에 대한 명확한 가시성과 우발적인 잘못된 구성의 위험이 줄어듭니다.
  • YAML 파이프라인을 향상된 보안 조치와 결합할 수 있습니다. 코드 검토 및 끌어오기 요청을 통해 분기 정책을 사용하여 잘못된 병합을 방지하기 위해 끌어오기 요청에 대한 검토 프로세스를 설정합니다.
  • 리소스 액세스 관리: 리소스 소유자는 YAML 파이프라인이 특정 리소스에 액세스할 수 있는지 여부를 제어합니다. 이 보안 기능은 다른 리포지토리 도용과 같은 공격을 방지합니다. 승인 및 검사를 사용하여 각 파이프라인 실행에 대한 액세스 제어를 제공합니다.
    • 보호된 분기 검사: 특정 분기에 대한 수동 코드 검토 프로세스가 있는 경우 이 보호를 파이프라인으로 확장할 수 있습니다. 리소스에 대한 보호된 분기 검사를 통해 파이프라인이 권한 없는 분기에서 자동으로 실행되지 않습니다.
    • 수동 승인 확인: 수동 승인 검사를 사용하여 파이프라인 요청이 지정된 사용자 또는 그룹에서 수동으로 승인될 때까지 보호된 리소스를 사용하지 못하도록 차단합니다.
    • 업무 시간 확인: 이 검사를 사용하여 파이프라인 배포가 지정된 날짜 및 기간 내에 시작되도록 합니다.
  • 클래식 파이프라인 만들기 사용 안 함: 클래식 빌드 파이프라인 및 클래식 릴리스 파이프라인 만들기를 독립적으로 사용하지 않도록 설정합니다. 둘 다 사용하지 않도록 설정하면 클래식 빌드 파이프라인, 클래식 릴리스 파이프라인, 작업 그룹 또는 배포 그룹을 사용자 인터페이스 또는 REST API를 통해 만들 수 없습니다. 자세한 내용은 클래식 파이프라인 생성 비활성화를 참조하세요.

보안 에이전트

컨테이너를 보호하려면 볼륨을 읽기 전용으로 표시하고, 리소스 제한을 설정하고, 신뢰할 수 있는 이미지를 사용하고, 취약성을 검색하고, 보안 정책을 적용합니다.

  • 자체 호스팅 에이전트 대신 Microsoft 호스팅을 사용합니다. Microsoft 호스팅 에이전트는 파이프라인을 실행할 때마다 격리 및 클린 가상 머신을 제공합니다. 자체 호스팅 에이전트 대신 Microsoft 호스팅 에이전트를 사용합니다. 자세한 내용은 Microsoft 호스팅 에이전트를 참조하세요.
  • 각 프로젝트에 대한 별도의 에이전트: 횡적 이동을 완화하고 프로젝트 간의 교차 오염을 방지하려면 각각 특정 프로젝트에 전용으로 별도의 에이전트 풀을 유지 관리합니다.
  • 낮은 권한의 계정을 사용하여 에이전트 실행: 시스템 보안을 강화하려면 자체 호스팅 에이전트를 실행하기 위해 가장 낮은 권한 계정을 사용합니다. 예를 들어 컴퓨터 계정 또는 관리 서비스 ID를 사용하는 것이 좋습니다. Azure DevOps 리소스에 직접 액세스할 수 있는 ID로 에이전트를 실행하지 마세요.
  • 프로덕션 아티팩트 및 중요한 에이전트 풀 격리: 다른 에이전트 풀을 사용하여 보안 문제를 방지합니다.
    • 프로덕션 아티팩트용으로 별도의 에이전트 풀을 사용합니다. 고유 에이전트 풀을 사용하여 프로덕션 아티팩트를 격리하여 비프로덕션 분기에서 실수로 배포하는 것을 방지합니다.
    • 중요한 풀 세그먼트: 민감하고 민감하지 않은 워크로드에 대해 별도의 풀을 만듭니다. 적절한 풀과 연결된 빌드 정의에서만 자격 증명을 허용합니다.
  • 자체 호스팅 에이전트에 대해 제한적인 방화벽 구성: 에이전트가 작동하도록 허용하면서 보안 및 유용성의 균형을 유지하면서 방화벽을 최대한 제한적으로 설정합니다.
  • 정기적으로 자체 호스팅 에이전트 풀 업데이트: 취약한 코드가 실행되지 않도록 정기적인 업데이트를 통해 자체 호스팅 에이전트를 최신 상태로 유지하여 악용 위험을 줄입니다.

변수 및 매개 변수를 안전하게 사용

비밀을 설정하는 모범 사례를 따라 파이프라인에서 변수와 매개 변수를 안전하게 사용합니다. 모범 사례에는 비밀 사용 제한, 큐 시간 변수 사용, 셸 작업 인수 유효성 검사를 사용하여 위협 및 취약성으로부터 파이프라인을 보호하는 것이 포함됩니다.

  • 비밀에 대한 액세스 제한: 파이프라인에 나타나는 모든 비밀 또는 키를 제거합니다. 워크로드 ID 페더레이션과 같은 비밀 없는 인증 방법으로 이동하거나 UI, 변수 그룹 또는 Azure Key Vault에서 원본으로 사용하는 변수 그룹에서 비밀을 설정합니다.
  • 셸 매개 변수 유효성 검사 사용: 셸 작업 사용 인수 매개 변수 유효성 검사를 사용하도록 설정하면 세미콜론, 따옴표 및 괄호와 같은 문자에 대한 검사가 추가됩니다. 설정>>에서 조직 또는 프로젝트 수준에서 셸 작업 인수 매개 변수 유효성 검사를 사용하도록 설정합니다.
  • 큐 시간에 설정할 수 있는 변수 제한: 조직 설정 파이프라인>에서 큐 시간에 설정할 수 있는 제한 변수를 설정하여 사용자가 큐 시간에 새 변수> 정의하지 못하도록 합니다.
  • 변수 대신 매개 변수 사용: 변수와 달리 실행 중인 파이프라인은 파이프라인 매개 변수를 수정할 수 없습니다. 매개 변수에는 데이터 형식(예: numberstring)이 있으며 특정 값 하위 집합으로 제한될 수 있습니다. 이 제한은 파이프라인의 사용자 구성 가능한 측면이 미리 정의된 목록의 값만 허용하여 파이프라인이 임의 데이터를 허용하지 않도록 하는 경우에 유용합니다.
  • 템플릿에서 비밀 매개 변수 참조: 파이프라인 YAML에서 직접 인라인 스크립트를 사용하여 비밀 매개 변수를 포함하는 것 대신, 템플릿을 사용하여 주 파이프라인에서 중요한 정보를 보호합니다. 이 방법을 구현하려면 스크립트에 대한 별도의 YAML 파일을 만든 다음, 해당 스크립트를 별도의 보안 리포지토리에 저장합니다. 그런 다음 템플릿을 참조하고 YAML에서 비밀 변수를 매개 변수로 전달할 수 있습니다. 보안 변수는 Azure Key Vault, 변수 그룹 또는 파이프라인 UI에서 가져옵니다. 자세한 내용은 템플릿을 사용합니다.
  • 분기 정책 및 변수 그룹 사용 권한으로 비밀 제한: 변수 그룹 권한, 조건부 작업 삽입 및 분기 정책의 조합을 사용하여 비밀이 분기에 연결되어 main 있는지 확인할 수 있습니다. 자세한 내용은 비밀 보호를 참조하세요.
  • setvariable을 사용하여 변수 설정 제한: 특성을 사용하여 settableVariables 파이프라인 작성자가 파이프라인에서 설정할 수 있는 변수를 구성합니다. 이 설정이 없으면 파이프라인 작성자는 로깅 명령을 사용하여 무제한 새 변수를 선언할 setvariable 수 있습니다. 빈 목록을 with settableVariables지정하면 모든 변수 설정이 허용되지 않습니다. 자세한 내용은 YAML 스키마의 settableVariables 특성을 참조하세요.

비밀을 보호하는 가장 좋은 방법은 처음에 비밀을 포함하지 않는 것입니다. 가능한 경우 비밀을 사용하지 말고, YAML 파일에 저장하지 말고, 보안을 유지하기 위해 기록되거나 인쇄되지 않도록 합니다.

  • 가능한 경우 비밀을 사용하지 마세요. 파이프라인이 비밀을 사용하는 것과 다른 방법을 사용하여 워크로드 ID 페더레이션 또는 관리 ID를 사용한 서비스 연결과 같은 작업을 수행할 수 있는지 확인합니다. 관리 ID를 사용하면 명시적 자격 증명 없이 애플리케이션과 서비스가 Azure로 인증할 수 있습니다. 자세한 내용은 서비스 주체 및 관리 ID 사용을 참조하세요. YAML에 비밀을 넣지 마세요. 중요한 값을 Azure Pipelines .yml 파일에 일반 텍스트로 저장하지 마세요.
  • 비밀을 기록하거나 인쇄하지 마세요. 비밀을 콘솔에 에코하거나, 명령줄 매개 변수에서 사용하거나, 파일에 로깅하지 마세요. Azure Pipelines는 가능한 한 로그에서 비밀을 제거하려고 시도하지만 비밀이 유출될 수 있는 모든 방법을 포착할 수는 없습니다.
  • JSON과 같은 구조적 데이터를 비밀로 사용하지 마세요. 각 중요한 값에 대한 개별 비밀을 만듭니다. 이 방법은 더 나은 편집 정확도를 보장하고 실수로 중요한 데이터를 노출할 위험을 최소화합니다.

보안 키 감사 및 회전

파이프라인을 보호하려면 정기적으로 작업 및 로그의 비밀 처리를 감사하고, 불필요한 비밀을 검토 및 제거하고, 비밀을 회전하여 보안 위험을 최소화합니다.

  • 작업 및 로그의 비밀 처리 감사: 태스크를 확인하여 비밀이 호스트로 전송되거나 로그에 인쇄되지 않는지 확인합니다. 오류 로그를 포함하여 로그 파일에 비밀이 없는지 확인합니다.
  • 등록된 비밀 검토: 파이프라인의 비밀이 여전히 필요한지 확인하고 더 이상 필요하지 않은 비밀을 제거하여 혼란과 잠재적인 보안 위험을 줄입니다.
  • 비밀 회전: 손상된 비밀을 악용할 수 있는 기간을 최소화하기 위해 정기적으로 비밀을 회전합니다.

악성 코드 실행 방지

테스트된 코드와 삭제된 코드만 파이프라인을 통해 실행되도록 하려면 파이프라인에서 일반적인 문제를 정기적으로 검토합니다.

  • 코드 검색: 셸 명령 삽입을 방지하기 위해 인수의 특수 문자를 이스케이프합니다. Azure DevOps용 GitHub Advanced Security를 사용하여 코드 검사를 자동화할 수 있습니다.
  • 입력 유효성을 검사하고 매개 변수 사용: 입력 매개 변수 및 인수의 유효성을 검사하여 의도하지 않은 동작을 방지합니다. 스크립트에서 매개 변수가 있는 쿼리를 사용하여 SQL 삽입을 방지합니다. 런타임 매개 변수인수 삽입과 같은 변수와 관련된 보안 문제를 방지하는 데 도움이 됩니다.
  • 스크립트에서 PATH를 사용하지 마세요. 이전 스크립트 또는 도구에서 변경할 수 있으므로 에이전트의 PATH 설정을 사용하는 것은 위험합니다. 항상 정규화된 경로를 대신 사용합니다.
  • 사용 가능한 작업 제어: Marketplace에서 태스크를 설치하고 실행하는 기능을 사용하지 않도록 설정하면 파이프라인에서 실행되는 코드를 보다 자세히 제어할 수 있습니다.

컨테이너 보안

구성 변경, 검사 및 정책을 통해 컨테이너를 보호하는 방법을 알아봅니다.

  • 볼륨을 읽기 전용으로 표시: 컨테이너에는 호스트 에이전트를 사용하는 데 필요한 작업, 도구 및 외부 구성 요소에 대한 시스템 제공 볼륨 탑재가 포함됩니다. externals, tasks, 그리고 tools를 보안 강화를 위해 읽기 전용으로 설정합니다.
  • 컨테이너별 리소스 제한 설정: CPU 및 메모리에 대한 제한을 설정하여 컨테이너가 과도한 리소스를 사용하지 못하도록 하여 서비스 거부 또는 보안 취약성을 초래할 수 있습니다.
  • 신뢰할 수 있는 이미지 사용: Azure Container Registry 또는 Docker Hub와 같은 평판 좋은 원본에서 공식 및 확인된 이미지를 사용합니다. 항상 latest 태그에 의존하지 않고 일관성과 안정성을 유지하기 위해 특정 버전 또는 태그를 지정합니다. 최신 보안 패치 및 버그 수정을 포함하도록 기본 이미지를 정기적으로 업데이트합니다.
  • 컨테이너에서 취약성을 검사하고 런타임 위협 방지를 적용합니다. Microsoft Defender for Cloud 와 같은 도구를 사용하여 보안 위험을 모니터링하고 검색합니다. 또한 Azure Container Registry는 배포 전에 컨테이너 이미지를 안전하게 보호하는 데 도움이 되는 통합 취약성 검사를 제공합니다. 추가 보안 검사를 위해 Azure DevOps 확장을 통해 타사 검사 도구를 통합할 수도 있습니다.
  • 권한 에스컬레이션을 방지하고 필요한 최소 권한으로 컨테이너를 실행하도록 보안 정책을 구현합니다. 예를 들어 AKS(Azure Kubernetes Service), 역할 기반 액세스 제어Pod 보안 허용 을 사용하면 컨테이너 권한을 제한하고 루트가 아닌 실행을 보장하며 중요한 리소스에 대한 액세스를 제한하는 정책을 적용할 수 있습니다.
  • 네트워크 정책 활용: 네트워크 정책을 사용하여 컨테이너 간 통신을 제한할 수 있으므로 권한 있는 컨테이너만 네트워크 내의 중요한 리소스에 액세스할 수 있습니다. 또한 AKS용 Azure Policy를 적용하여 신뢰할 수 있는 컨테이너 이미지만 배포하는 것과 같은 컨테이너 보안 모범 사례를 적용할 수 있습니다.

템플릿을 사용하여 모범 사례 적용

최소 템플릿으로 시작하고 확장을 점진적으로 적용합니다. 이 방법을 사용하면 보안 사례를 구현할 때 모든 파이프라인을 포함하는 중앙 집중식 시작 지점이 보장됩니다.

  • 확장 템플릿 사용: 확장 템플릿은 외부 구조를 정의하고 대상 사용자 지정에 대한 특정 지점을 제공합니다. 확장 템플릿을 사용하면 악성 코드가 파이프라인에 침투하는 것을 방지할 수 있습니다.
  • 단계를 사용하여 액세스 제한: 패키지 다운로드와 같은 단계를 호스트가 아닌 컨테이너에서 실행하여 네트워크 액세스를 제한합니다. 컨테이너에서 단계가 실행되면 잘못된 행위자가 에이전트 구성을 수정하거나 나중에 실행하기 위해 악성 코드를 남기지 못하게 합니다.