서비스 계정 보안 권장사항

서비스 계정은 리소스이자 주 구성원이라는 점에서 사용자 계정과 다릅니다.

  • 주 구성원으로서 Cloud Storage 버킷과 같은 리소스에 대한 액세스 권한을 서비스 계정에 부여할 수 있습니다.
  • 리소스로서 서비스 계정에 액세스할 수 있으며 사용자 또는 그룹과 같은 다른 주 구성원에 의해 가장될 수 있습니다.

서비스 계정을 보호하려면 이중적인 특성을 고려하세요.

  • 서비스 계정은 주 구성원이므로, 침해된 서비스 계정으로 인해 발생할 수 있는 잠재적 위험을 줄이기 위해 권한을 제한해야 합니다.
  • 서비스 계정은 리소스이므로 침해되지 않도록 보호해야 합니다.

서비스 계정은 여러 가지 방법으로 악용될 수 있습니다.

  • 권한 에스컬레이션: 악의적인 행위자가 서비스 계정을 가장하여 정상적으로는 액세스할 수 없는 리소스에 액세스할 수 있습니다.
  • 스푸핑: 악의적인 행위자가 서비스 계정 가장을 사용하여 신원을 은폐할 수 있습니다.
  • 부인 방지: 악의적인 행위자는 서비스 계정을 사용하여 자신을 대신하여 작업을 수행함으로써 자신의 ID 및 작업을 숨길 수 있습니다. 경우에 따라 이러한 행동을 악의적인 행위자로 추적하지 못할 수 있습니다.
  • 정보 공개: 악의적인 행위자가 특정 서비스 계정의 존재로부터 인프라, 애플리케이션 또는 프로세스에 대한 정보를 추출할 수 있습니다.

이 가이드에서는 서비스 계정의 권한을 제한하고 이러한 위험 요소를 줄이기 위한 권장사항을 제공합니다.

서비스 계정 권한 제한

서비스 계정은 주 구성원이며 일반 사용자 계정과 마찬가지로 리소스에 대한 액세스 권한을 부여받을 수 있습니다.

기본 서비스 계정에 자동 역할 부여를 사용하지 않음

일부 Google Cloud 서비스는 Google Cloud 프로젝트에서 API를 처음으로 사용 설정할 때 기본 서비스 계정을 만듭니다. 기본적으로 이러한 서비스 계정에는 Cloud 프로젝트의 편집자 역할(roles/editor)이 부여되어 Cloud 프로젝트의 모든 리소스를 읽고 수정할 수 있습니다. 이 역할은 편의를 위해 부여되지만 서비스의 작동을 위해 꼭 필요하지 않습니다. Cloud 프로젝트의 리소스에 액세스하기 위해 Google Cloud 서비스는 기본 서비스 계정이 아니라 서비스 에이전트를 사용합니다.

기본 서비스 계정에 편집자 역할이 자동으로 부여되지 않도록 하려면 조직에 기본 서비스 계정에 대한 자동 IAM 부여 사용 중지(constraints/iam.automaticIamGrantsForDefaultServiceAccounts) 제약조건을 사용 설정합니다. 여러 Cloud 프로젝트에 제약조건을 적용하려면 폴더 또는 조직 노드에서 제약조건을 구성합니다. 제약조건을 적용하더라도 기존 기본 서비스 계정에서 편집자 역할이 삭제되지는 않습니다.

VM 인스턴스에 서비스 계정을 연결할 때는 액세스 범위를 사용하지 않음

VM 인스턴스에 서비스 계정을 연결할 때 하나 이상의 액세스 범위를 지정할 수 있습니다. 액세스 범위를 사용하면 VM에서 액세스할 수 있는 서비스를 제한할 수 있습니다. 이러한 제한은 Identity and Access Management(IAM) 정책에 추가로 적용됩니다.

액세스 범위는 대략적입니다. 예를 들어 https://www.googleapis.com/auth/devstorage.read_only 범위를 사용하면 Cloud Storage 읽기 전용 작업에 대한 액세스를 제한할 수 있지만 특정 버킷에 대한 액세스를 제한할 수는 없습니다. 따라서 액세스 범위는 세분화된 IAM 정책에 적합한 대안이 아닙니다.

액세스 범위를 사용하는 대신 전용 서비스 계정을 만들고 세분화된 IAM 정책을 사용하여 서비스 계정에서 액세스할 수 있는 리소스를 제한합니다.

서비스 계정에 리소스에 대한 액세스 권한을 부여하기 위해 그룹을 사용하지 않음

조직에서는 여러 직원이 유사하거나 중복된 직무를 수행하는 경우가 많기 때문에 리소스에 대한 비슷한 액세스가 요구됩니다. 그룹을 사용하면 이러한 유사성을 활용하여 관리 오버헤드를 줄일 수 있습니다.

서비스 계정은 애플리케이션에 의해 사용됩니다. 여러 애플리케이션이 동일한 기능을 수행하기 때문에 액세스 요구사항이 비슷하거나 동일한 경우는 거의 없습니다. 애플리케이션은 고유한 경우가 많으며 액세스가 필요한 리소스는 일반적으로 애플리케이션마다 다릅니다.

그룹을 사용하여 서비스 계정에 리소스에 대한 액세스 권한을 부여하면 몇 가지 잘못된 결과가 발생할 수 있습니다.

  • 각 그룹에 서비스 계정이 하나 또는 일부만 포함된 그룹 급증
  • 권한 추가: 그룹의 각 구성원은 리소스의 하위 집합에 대한 액세스만 필요로 하지만 시간이 지남에 따라 점점 더 많은 리소스에 대한 액세스 권한이 그룹에 부여됩니다.

그룹의 목적이 좁게 정의되지 않는 한 그룹을 사용하지 않는 것이 좋습니다. 대신 서비스 계정에 필요한 리소스에 대한 액세스 권한을 직접 부여합니다.

도메인 전체 위임 사용하지 않음

도메인 전체 위임은 서비스 계정이 Cloud ID 또는 Google Workspace 계정의 모든 사용자를 가장할 수 있도록 합니다. 도메인 전체 위임을 사용하면 서비스 계정이 Google Workspace 및 Cloud ID에서 특정 관리 작업을 수행하거나 Google Cloud 외부에서 서비스 계정을 지원하지 않는 Google API에 액세스할 수 있습니다.

도메인 전체 위임은 특정 사용자를 가장하기 위해 서비스 계정을 제한하지 않지만 최고 관리자를 포함한 Cloud ID 또는 Google Workspace 계정의 모든 사용자를 가장할 수 있도록 허용합니다. 따라서 서비스 계정이 도메인 전체 위임을 사용하도록 허용하면 서비스 계정이 권한 에스컬레이션 공격의 목표가 되기 쉽습니다.

서비스 계정으로 직접 또는 OAuth 동의 흐름을 통해 작업을 처리할 수 있는 경우 도메인 전체 위임을 사용하지 마세요.

도메인 전체 위임을 사용할 수밖에 없는 경우 서비스 계정이 사용할 수 있는 OAuth 범위 집합을 제한하세요. OAuth 범위는 서비스 계정이 가장할 수 있는 사용자를 제한하지 않지만 서비스 계정에서 액세스할 수 있는 사용자 데이터 유형을 제한합니다.

사용자 인증 정보 액세스 경계를 사용하여 액세스 토큰 권한 축소

Google 액세스 토큰은 Bearer 토큰이며 특정 애플리케이션에 한정되지 않고 사용할 수 있습니다. 내 애플리케이션이 액세스 토큰을 다른 애플리케이션에 전달하면 다른 애플리케이션 또한 내 애플리케이션과 같은 방식으로 토큰을 사용할 수 있습니다. 마찬가지로, 액세스 토큰이 악의적인 사용자에게 유출되는 경우 이러한 사용자 역시 토큰을 사용하여 액세스 권한을 얻을 수 있습니다.

액세스 토큰은 Bearer 토큰이므로 승인되지 않은 당사자에게 유출되거나 표시되지 않도록 보호해야 합니다. 액세스 권한이 부여되는 리소스를 제한하여 유출된 액세스 토큰에 의해 발생할 수 있는 잠재적인 피해를 제한할 수 있습니다. 이 과정을 줄이기(downscoping)라고 합니다.

사용자 인증 정보 경계를 사용하여 다른 애플리케이션이나 애플리케이션의 다른 구성요소로 액세스 토큰을 전달할 때마다 액세스 토큰을 축소할 수 있습니다. 토큰이 필요한 리소스에 대해 적당한 범위를 벗어나지 않는 액세스 권한을 부여하도록 필요한 액세스 경계를 설정합니다.

역할 권장사항을 사용하여 사용하지 않는 권한 식별

애플리케이션을 처음 배포할 때 애플리케이션에 실제로 어떤 역할과 권한이 필요한지 확실하지 않을 수 있습니다. 따라서 애플리케이션 서비스 계정에 필요한 추가 권한을 부여할 수 있습니다.

마찬가지로 애플리케이션의 액세스 요구사항이 시간이 지남에 따라 증가할 수 있으며, 처음에 부여한 역할과 권한의 일부는 필요 없어질 수 있습니다.

역할 권장사항을 사용하여 애플리케이션에서 실제로 사용 중인 권한과 사용하지 않을 수 있는 권한을 식별합니다. 애플리케이션이 실제로 필요한 것보다 많은 액세스 권한을 부여받지 않도록 영향을 받는 리소스의 IAM 정책을 조정합니다.

측면 이동 통계를 사용하여 측면 이동 제한

측면 이동은 한 프로젝트의 서비스 계정에 다른 프로젝트의 서비스 계정을 가장할 수 있는 권한이 있는 경우입니다. 예를 들어 프로젝트 A에서 만든 서비스 계정이 프로젝트 B의 서비스 계정을 가장할 수 있는 권한을 보유할 수 있습니다.

이러한 권한은 주 구성원에 의도하지 않은 리소스 액세스 권한을 부여하는 프로젝트 간의 일련의 가장을 일으킬 수 있습니다. 예를 들어 주 구성원은 프로젝트 A에서 서비스 계정을 가장한 후 이 서비스 계정을 사용해서 프로젝트 B의 서비스 계정을 가장할 수 있습니다. 프로젝트 B의 서비스 계정에 조직 내 다른 프로젝트의 다른 서비스 계정을 가장할 수 있는 권한이 있으면 주 구성원이 계속해서 서비스 계정 가장을 사용하여 프로젝트 간에 이동하며 권한을 계속 얻을 수 있습니다.

추천자는 이 문제의 해결을 돕기 위해 측면 이동 통계를 제공합니다. 측면 이동 통계는 한 프로젝트의 서비스 계정이 다른 프로젝트의 서비스 계정을 가장하도록 허용하는 역할을 식별합니다. 측면 이동 통계를 직접 보고 관리하는 방법을 알아보려면 측면 이동 통계 관리를 참조하세요.

일부 측면 이동 통계는 역할 권장사항과 관련됩니다. 이러한 권장사항을 적용하여 프로젝트 간 측면 이동을 줄일 수 있습니다. 자세한 내용은 권장사항 검토 및 적용을 참조하세요.

권한 에스컬레이션 위협으로부터 보호

아무런 역할도 부여되지 않았고 어떤 리소스에도 액세스할 수 없으며 방화벽 규칙과 연결되지 않은 서비스 계정은 일반적으로 값이 제한되어 있습니다. 서비스 계정에 리소스에 대한 액세스 권한을 부여하면 서비스 계정의 값이 증가합니다. 서비스 계정은 사용자에게 더 유용한 역할을 하지만 쉽게 권한 에스컬레이션 공격의 대상이 되기도 합니다.

예를 들어 민감한 정보가 포함된 Cloud Storage 버킷에 대한 전체 액세스 권한이 있는 서비스 계정을 가정해 보겠습니다. 이 경우 서비스 계정은 Cloud Storage 버킷 자체만큼 유용합니다. 악의적인 사용자는 버킷에 직접 액세스하는 대신 서비스 계정을 제어하려고 시도할 수 있습니다. 이러한 시도가 성공하면 악의적인 사용자가 서비스 계정을 가장하여 해당 권한을 에스컬레이션할 수 있으며, 이를 통해 버킷의 민감한 정보에 액세스할 수 있습니다.

서비스 계정과 관련된 권한 에스컬레이션 기술은 일반적으로 다음과 같은 카테고리로 분류됩니다.

  • 직접 가장: 실수로 서비스 계정을 가장하거나 서비스 계정 키를 만들 수 있는 권한을 부여할 수 있습니다. 서비스 계정이 사용자 계정보다 더 많은 권한을 부여받은 경우 이 기능을 사용하여 권한을 에스컬레이션하고 원래 액세스할 수 없었던 리소스에 액세스할 수 있습니다.
  • 간접 가장: 사용자가 서비스 계정을 직접 가장할 수 없을 때, 서비스 계정이 CI/CD 파이프라인, VM 인스턴스 또는 다른 자동화 시스템에서 사용되는 경우에는 간접적으로 가장할 수 있습니다. 시스템이 적절한 액세스 제한을 구현하지 않으면 사용자는 시스템에서 처리할 수 없었던 작업을 처리하도록 허용하여 권한을 에스컬레이션할 수 있습니다.
  • IAM 정책, 그룹 또는 커스텀 역할 수정: 권한이 있는 서비스 계정에 대한 액세스 권한이 없는 사용자도 서비스 계정, 바깥쪽 Cloud 프로젝트 또는 폴더의 IAM 정책을 수정할 권한이 있을 수 있습니다. 그러면 사용자는 이러한 IAM 정책 중 하나를 확장하여 서비스 계정에 대해 직접 또는 간접적으로 가장할 수 있는 권한을 부여할 수 있습니다.

다음 섹션에서는 권한 에스컬레이션 위협으로부터 서비스 계정을 보호하기 위한 권장사항을 제공합니다.

사용자가 사용자 자신보다 권한이 더 높은 서비스 계정을 가장하는 것을 허용하지 않음

서비스 계정을 가장하면 사용자는 서비스 계정에서 액세스할 수 있는 일부 또는 모든 리소스에 액세스할 수 있습니다. 서비스 계정이 사용자보다 더 광범위한 액세스를 가진 경우 사실상 사용자보다 더 많은 권한을 갖게 됩니다.

사용자에게 권한이 더 많은 서비스 계정으로 가장할 수 있는 권한이 부여되면 Linux에서 sudo 도구를 사용하거나 Windows에서 프로세스 승격을 사용하는 것과 같이 사용자가 일시적으로 권한을 승격할 수 있습니다. 이러한 일시적인 권한 승격이 필요한 상황이 아니라면 사용자가 권한이 더 많은 서비스 계정을 가장하지 않도록 하는 것이 가장 좋습니다.

사용자가 서비스 계정을 가장할 수 있는 권한은 다음과 같습니다.

  • iam.serviceAccounts.getAccessToken
  • iam.serviceAccounts.getOpenIdToken
  • iam.serviceAccounts.actAs
  • iam.serviceAccounts.implicitDelegation
  • iam.serviceAccountKeys.create
  • iam.serviceAccountKeys.get
  • deploymentmanager.deployments.create
  • cloudbuild.builds.create

이러한 권한 중 일부를 포함하는 역할은 다음과 같습니다(이에 국한되지 않음).

  • 소유자(roles/owner)
  • 편집자(roles/editor)
  • 서비스 계정 사용자(roles/iam.serviceAccountUser)
  • 서비스 계정 토큰 생성자(roles/iam.serviceAccountTokenCreator)
  • 서비스 계정 키 관리자(roles/iam.serviceAccountKeyAdmin)
  • 서비스 계정 관리자(roles/iam.serviceAccountAdmin)
  • 워크로드 아이덴티티 사용자(roles/iam.workloadIdentityUser)
  • Deployment Manager 편집자(roles/deploymentmanager.editor)
  • Cloud Build 편집자(roles/cloudbuild.builds.editor)

사용자에게 역할을 할당하기 전에 먼저 다음과 같이 자문해 보세요.

  • 현재 Cloud 프로젝트 내부 및 외부 리소스 중 사용자가 서비스 계정을 가장하여 액세스할 수 있는 리소스는 무엇인가요?
  • 이러한 액세스 수준은 정당한가요?
  • 사용자가 서비스 계정을 가장할 수 있는 상황을 관리할 충분한 보호 조치가 있나요?

모든 질문에 확실히 답할 수 없는 경우 역할을 할당하지 마세요. 대신 사용자에게 권한이 낮은 다른 서비스 계정을 부여하는 것이 좋습니다.

사용자가 권한이 더 높은 서비스 계정의 IAM 정책을 변경하는 것을 허용하지 않음

서비스 계정을 사용하거나 가장할 수 있는 사용자는 서비스 계정의 IAM 정책에 의해 캡처됩니다. IAM 정책은 특정 서비스 계정에서 iam.serviceAccounts.setIamPolicy 권한을 가진 사용자가 수정하거나 확장할 수 있습니다. 이러한 권한을 포함하는 역할은 다음과 같습니다.

  • 소유자(roles/owner)
  • 보안 관리자(roles/iam.securityAdmin)
  • 서비스 계정 관리자(roles/iam.serviceAccountAdmin)

iam.serviceAccounts.setIamPolicy 권한이 포함된 역할은 사용자에게 서비스 계정에 대한 완전한 제어 권한을 부여합니다.

  • 사용자는 서비스 계정을 가장할 수 있는 권한을 자신에게 부여할 수 있으며, 이를 통해 사용자는 서비스 계정과 동일한 리소스에 액세스할 수 있습니다.
  • 사용자는 다른 사용자에게 서비스 계정에 대해 동일하거나 유사한 수준의 액세스 권한을 부여할 수 있습니다.

이러한 역할을 사용자에게 할당하려면 먼저 사용자가 서비스 계정을 가장하여 현재 Cloud 프로젝트 내부 및 외부에서 어떤 리소스에 액세스할 수 있는지 확인하세요. 서비스 계정이 사용자보다 더 많은 권한을 가진 경우 사용자가 서비스 계정의 IAM 정책을 변경하도록 허용하지 마세요.

사용자가 서비스 계정 키를 만들거나 업로드하도록 허용하지 않음

애플리케이션 또는 사용자가 서비스 계정 키를 사용하여 서비스 계정으로 인증할 수 있습니다. 다른 형태의 서비스 계정 가장과는 달리 서비스 계정 키를 사용할 때는 이전과 같은 인증이 필요하지 않습니다. 즉, 서비스 계정 키를 소유한 사람이 이를 사용할 수 있습니다.

따라서 서비스 계정 키를 사용하여 인증하는 것은 다른 형태의 가장과 유사합니다. 사용자에게 서비스 계정 키에 대한 액세스 권한을 부여하거나 새 서비스 계정 키를 만들 수 있는 권한을 부여하면 사용자는 서비스 계정을 가장하고 서비스 계정에서 액세스할 수 있는 모든 리소스에 액세스할 수 있습니다.

서비스 계정 키를 생성 또는 업로드하기 위해서는 iam.serviceAccountKeys.create 권한이 필요하며 이 권한은 서비스 계정 키 관리자(roles/iam.serviceAccountKeyAdmin) 및 편집자(roles/editor) 역할을 포함합니다.

iam.serviceAccountKeys.create 권한이 포함된 역할을 사용자에게 할당하려면 먼저 사용자가 서비스 계정을 가장하여 현재 Cloud 프로젝트 내부 및 외부에서 어떤 리소스에 액세스할 수 있는지 확인하세요. 사용자가 권한이 더 많은 서비스 계정에 대한 서비스 계정 키를 만들도록 허용하지 마세요.

Cloud 프로젝트에 서비스 계정 키가 전혀 필요하지 않은 경우 Cloud 프로젝트 또는 바깥쪽 폴더에 서비스 계정 키 생성 사용 중지서비스 계정 키 업로드 사용 중지 조직 정책 제약조건을 적용합니다. 이러한 제약조건을 통해 모든 사용자가 서비스 계정에 대한 iam.serviceAccountKeys.create 권한이 포함된 서비스 계정 키를 만들고 업로드할 수 없습니다.

Cloud 프로젝트 또는 폴더 수준에서 서비스 계정에 액세스 권한을 부여하지 않음

서비스 계정은 리소스이자 리소스 계층 구조의 일부입니다. 따라서 다음 수준으로 서비스 계정에 대한 액세스 권한을 관리할 수 있습니다.

  • 개별 서비스 계정
  • 바깥쪽 Cloud 프로젝트
  • Cloud 프로젝트의 상위 항목 폴더
  • 조직 노드

Cloud 프로젝트 수준 또는 리소스 계층 구조의 더 높은 수준에서 액세스 권한을 관리하면 관리 오버헤드를 줄이는 데 도움이 될 수 있지만, 권한이 과도하게 부여될 수 있습니다. 예를 들어 사용자에게 Cloud 프로젝트의 서비스 계정 토큰 생성자 역할을 부여하면 사용자는 Cloud 프로젝트의 모든 서비스 계정을 가장할 수 있습니다. 서비스 계정을 가장할 수 있는 경우 사용자가 Cloud 프로젝트 외부의 리소스를 포함해 해당 서비스 계정으로 액세스할 수 있는 모든 리소스에 액세스할 수 있습니다.

이러한 과도한 권한 부여를 방지하려면 Cloud 프로젝트 또는 폴더 수준에서 서비스 계정에 대한 액세스를 관리하지 마세요. 대신 각 서비스 계정의 액세스 권한을 개별적으로 관리하세요.

권한이 있는 서비스 계정이 연결된 컴퓨팅 리소스에서 보안 수준이 낮은 소스의 코드를 실행하지 않음

VM 인스턴스나 Cloud Run 애플리케이션과 같은 컴퓨팅 리소스에 서비스 계정을 연결하면 해당 리소스에서 실행 중인 프로세스가 메타데이터 서버를 사용하여 액세스 토큰 및 ID 토큰을 요청할 수 있습니다. 이러한 토큰을 사용하면 프로세스가 서비스 계정을 가장하고 서비스 계정을 대신하여 리소스에 액세스할 수 있습니다.

기본적으로 메타데이터 서버에 대한 액세스는 특정 프로세스 또는 사용자로 제한되지 않습니다. 대신 컴퓨팅 리소스에서 실행되는 모든 코드는 메타데이터 서버에 액세스하여 액세스 토큰을 얻을 수 있습니다. 이러한 코드에는 다음이 포함될 수 있습니다.

  • 애플리케이션의 코드.
  • 애플리케이션이 서버 측 스크립트 평가를 허용하는 경우 최종 사용자가 제출한 코드.
  • 컴퓨팅 리소스가 CI/CD 시스템의 일부인 경우 원격 소스 저장소에서 읽히는 코드.
  • Cloud Storage 버킷에서 제공하는 시작 및 종료 스크립트.
  • VM Manager가 배포한 게스트 정책.

사용자가 코드를 제출하거나 원격 스토리지 위치에서 코드를 읽는 경우, 코드가 신뢰할 수 있고 원격 스토리지 위치의 보안이 연결된 서비스 계정만큼 철저한지 확인해야 합니다. 원격 스토리지 위치가 서비스 계정보다 덜 안전한 경우 악의적인 사용자가 자신의 권한을 에스컬레이션할 수 있습니다. 서비스 계정의 권한을 사용하는 악성 코드를 해당 위치에 삽입하여 이를 수행합니다.

권한이 있는 서비스 계정이 연결된 VM에 대한 셸 액세스 제한

일부 컴퓨팅 리소스는 대화형 액세스를 지원하며 사용자가 시스템에 대한 셸 액세스 권한을 얻을 수 있도록 합니다. 예를 들면 다음과 같습니다.

  • Compute Engine을 통해 SSH 또는 RDP를 사용하여 VM 인스턴스에 로그인할 수 있습니다.
  • Google Kubernetes Engine을 통해 kubectl exec를 사용하여 명령어를 실행하거나 Kubernetes 컨테이너에서 셸을 시작할 수 있습니다.

VM 인스턴스에 권한이 있는 서비스 계정이 연결된 경우 시스템에 대한 셸 액세스 권한이 있는 모든 사용자가 서비스 계정을 가장하고 서비스 계정을 대신해 리소스에 액세스할 수 있습니다. 사용자가 이러한 기능을 남용해 권한을 에스컬레이션하지 못하게 하려면 셸 액세스 권한의 보안이 연결된 서비스 계정만큼 철저한지 확인해야 합니다.

Linux 인스턴스의 경우 OS 로그인을 사용하여 연결된 서비스 계정에 대한 액세스보다 SSH 액세스를 더 제한적으로 적용할 수 있습니다. OS 로그인이 사용 설정된 VM 인스턴스에 연결하려면 사용자는 OS 로그인을 사용하도록 허용되어야 할 뿐만 아니라 연결된 서비스 계정에 대한 iam.serviceAccounts.actAs 권한도 있어야 합니다.

메타데이터 기반 키를 사용하는 VM 인스턴스나 Windows 인스턴스에는 동일한 수준의 액세스 제어가 적용되지 않습니다. 메타데이터에 SSH 키를 게시하거나 Windows 사용자 인증 정보를 요청하려면 VM 인스턴스의 메타데이터에 대한 액세스 권한과 연결된 서비스 계정에 대한 iam.serviceAccounts.actAs 권한이 필요합니다. 하지만 SSH 키가 게시되거나 Windows 사용자 인증 정보를 획득한 후에는 로그인 시 추가 IAM 권한 확인이 적용되지 않습니다.

마찬가지로 VM 인스턴스가 인증을 위해 커스텀 Linux 플러그인 가능한 인증 모듈을 사용하거나 Active Directory 도메인의 구성원인 경우 서비스 계정을 가장할 권한이 없는 사용자가 로그인할 수 있습니다.

특히 OS 로그인을 사용하지 않는 VM 인스턴스의 경우 IAP(Identity-Aware Proxy)를 통해 셸 액세스를 제한하는 것이 좋습니다. VM 인스턴스에 연결된 서비스 계정을 가장하도록 허용되어야 하는 사용자에게 IAP 보안 터널 사용자 역할만 부여합니다.

선택된 사용자 및 프로세스에 대한 메타데이터 서버 액세스 제한

VM 인스턴스에 서비스 계정을 연결하면 VM에 배포된 워크로드가 메타데이터 서버에 액세스하여 서비스 계정의 토큰을 요청할 수 있습니다. 기본적으로 메타데이터 서버에 대한 액세스는 VM의 특정 프로세스 또는 사용자로 제한되지 않습니다. Linux의 nobody와 Windows의 LocalService 같이 권한이 낮은 사용자로 실행되는 프로세스도 메타데이터 서버에 대한 전체 액세스 권한을 가지며 서비스 계정의 토큰을 얻을 수 있습니다.

메타데이터 서버 액세스를 특정 사용자로 제한하려면 게스트 운영체제의 호스트 방화벽을 구성하여 이러한 사용자만 메타데이터 서버에 대한 아웃바운드 연결을 열 수 있도록 해야 합니다.

Linux에서는 --uid-owner--gid-owner 옵션을 사용하여 특정 사용자 또는 그룹에만 적용되는 iptables 규칙을 설정할 수 있습니다. Windows에서는 Set-NetFirewallSecurityFilter 명령어를 사용하면 선택한 사용자 또는 그룹에 적용되도록 방화벽 규칙을 맞춤설정할 수 있습니다.

스푸핑 위협으로부터 보호

워크로드 아이덴티티 제휴를 사용하면 Cloud 프로젝트와 외부 ID 공급업체 간에 단방향 트러스트 관계를 만들 수 있습니다. 이 트러스트 관계를 설정한 후 외부 ID 공급업체로부터 얻은 사용자 인증 정보를 보안 토큰 서비스(STS) 토큰과 교환할 수 있습니다. 그러면 해당 STS 토큰을 사용하여 서비스 계정에 액세스하거나 가장할 수 있습니다.

STS 토큰은 특정 Google ID와 대응하지 않는다는 점에서 액세스 토큰과 다릅니다. 또한 STS 토큰은 외부 ID 공급업체의 특정 ID와 대응하지 않을 수도 있습니다. 대신 STS 토큰은 속성 집합을 나타냅니다. 이러한 속성이 무엇인지에 따라 외부 ID 공급업체의 단일 또는 여러 ID에 대응할 수 있습니다.

STS 토큰으로 표현된 속성이 모호하거나 부적절하게 사용되는 경우 악의적인 사용자가 자신의 신원을 스푸핑할 수 있습니다. 다음 섹션에서는 이러한 위장 위협으로부터 보호하는 데 도움이 되는 권장사항을 설명합니다.

속성 매핑 수정 허용하지 않음

워크로드 아이덴티티 제휴는 속성 매핑을 사용하여 외부 ID 공급업체에서 제공하는 속성 중 STS 토큰에 삽입할 속성 및 속성 이름을 변환하는 방법을 선택합니다. 속성 매핑 구성은 외부 ID 공급업체와 Google Cloud 간의 트러스트 관계를 설정하는 중요한 단계입니다.

속성 매핑은 워크로드 아이덴티티 제휴를 이용하는 보안에도 중요합니다. 서비스 계정을 가장하고 속성 매핑을 변경할 수 있는 제휴된 주 구성원 또는 주 구성원 집합 권한을 부여한 경우 서비스 계정에 액세스할 수 있는 사용자를 변경할 수 있습니다.

속성 매핑을 수정하려면 iam.googleapis.com/workloadIdentityPoolProviders.update 권한이 필요합니다. 이 권한이 포함된 역할은 다음과 같습니다.

  • 소유자(roles/owner)
  • IAM 워크로드 아이덴티티 풀 관리자(roles/iam.workloadIdentityPoolAdmin)

악의적인 행위자가 속성 매핑을 수정할 권한이 있으면 ID를 스푸핑하여 서비스 계정에 대한 액세스 권한을 갖도록 매핑 규칙을 변경할 수 있습니다. 이러한 악성 수정을 방지하려면 소수의 관리 사용자만 속성 매핑을 수정할 수 있는 권한을 갖고 있어야 합니다.

리소스 계층 구조의 상위 수준에서 사용자에게 실수로 이러한 역할 중 하나가 할당되는 위험을 제한하기 위해 워크로드 아이덴티티 풀을 관리하기 위한 전용 Cloud 프로젝트를 만드는 것이 좋습니다.

안정적이지 않거나 신뢰할 수 없는 속성에 의존하지 않음

워크로드 아이덴티티 제휴를 사용하면 외부 ID 공급업체 통해 사용자를 인증하고 인증된 사용자에 대한 정확한 정보를 Google Cloud에 보고합니다.

ID 공급업체는 속성을 사용하여 인증된 사용자에 대한 정보를 전달합니다. 이러한 속성 중 일부는 일반적으로 권한이 보장되지만 다른 속성은 그렇지 않을 수 있습니다. 예를 들어 외부 ID 공급업체가 OpenID Connect ID 토큰에 사용자 이름과 사용자 ID를 모두 삽입할 수 있습니다. 두 속성 모두 사용자를 고유하게 식별하며 서로 상호 호환될 수 있는 것처럼 보일 수 있습니다. 하지만 외부 ID 공급업체는 사용자 ID가 안정적이고 신뢰할 수 있도록 보장하면서 사용자 이름을 변경하도록 허용할 수 있습니다.

속성 매핑이 안정적이지 않거나 신뢰할 수 없는 속성에 의존하는 경우 악의적인 행위자가 외부 ID 공급업체의 사용자 프로필을 수정하여 ID를 스푸핑할 수 있습니다. 예를 들어 외부 ID 공급업체에서 사용자 이름을 최근에 삭제되었지만 Google Cloud에서 서비스 계정에 계속 액세스할 수 있는 사용자의 이름으로 변경할 수 있습니다.

이러한 스푸핑 공격을 방지하려면 속성 매핑에서 외부 ID 공급업체가 안정적이고 신뢰할 수 있는 것으로 확인된 속성만 사용하도록 합니다.

정보 공개 위협으로부터 보호

서비스 계정 이메일 주소에 기밀 정보를 공개하지 않음

서비스 계정에 다른 Cloud 프로젝트의 리소스에 대한 액세스 권한을 부여하려면 리소스의 IAM 정책에 역할 결합을 추가하면 됩니다. IAM 정책은 리소스 자체와 마찬가지로 다른 Cloud 프로젝트의 일부이며 다른 Cloud 프로젝트에서 공개 상태가 제어됩니다.

IAM 정책 보기는 일반적으로 권한 작업으로 간주되지 않습니다. 대부분의 역할에는 기본 뷰어 역할을 비롯해 필요한 *.getIamPolicy 권한이 포함됩니다.

IAM 정책을 볼 수 있는 사용자는 리소스에 대한 액세스 권한이 부여된 주 구성원의 이메일 주소를 볼 수도 있습니다. 서비스 계정의 경우 이메일 주소는 악의적인 사용자에게 힌트를 제공할 수 있습니다.

예를 들어 IAM 정책에는 이메일 주소 jenkins@deployment-project-123.gserviceaccount.com이 있는 서비스 계정의 binding이 포함될 수 있습니다. 악의적인 행위자에게 이 이메일 주소는 ID가 deployment-project-123인 Cloud 프로젝트가 있음을 알려줄 뿐만 아니라 Cloud 프로젝트에서 Jenkins 서버를 실행한다는 것을 나타냅니다. deployer@deployment-project-123.gserviceaccount.com과 같이 일반적인 이름을 선택하면 deployment-project-123에서 실행 중인 소프트웨어 유형에 대한 정보가 공개되지 않습니다.

샌드박스 또는 개발 Cloud 프로젝트 등 액세스 권한이 덜 엄격하게 제어되는 Cloud 프로젝트의 리소스에 대한 액세스 권한을 서비스 계정에 부여할 경우 서비스 계정의 이메일 주소가 모든 정보를 공개하지 않도록 해야 합니다. 특히 기밀이거나 공격자에게 힌트를 제공할 수 있는 정보를 공개하면 안 됩니다.

부인 방지 위협으로부터 보호

Google Cloud의 리소스 중 하나에 영향을 미치는 의심스러운 활동이 감지되었을 때, Cloud 감사 로그는 활동이 언제 발생했는지, 어떤 사용자가 관련되었는지를 확인하는 데 중요한 정보 소스입니다.

Cloud 감사 로그에서 서비스 계정에 의해 활동이 발생했음을 나타내는 경우 이 정보만으로는 이벤트의 전체 체인을 재구성하는 데 충분하지 않을 수 있습니다. 서비스 계정에서 활동을 수행하게 만든 사용자 또는 애플리케이션을 찾을 수 있어야합니다.

이 섹션에는 거부할 수 없는 감사 추적을 유지하는 데 도움이 되는 권장사항을 제공합니다.

IAM API의 데이터 액세스 로그 사용 설정

서비스 계정 가장 시나리오를 식별하고 이해할 수 있도록 Compute Engine과 같은 서비스에는 Cloud 감사 로그에 serviceAccountDelegationInfo 섹션이 포함되어 있습니다. 이 섹션에서는 서비스 계정이 가장되고 있는지 여부와 어떤 사용자에 의해 가장되는지를 나타냅니다.

일부 서비스는 Cloud 감사 로그에서 가장에 대한 세부정보를 포함하지 않습니다. 가장 이벤트를 기록하려면 다음 API에 대한 데이터 액세스 로그도 사용 설정해야 합니다.

  • 서비스 계정이 포함된 모든 Cloud 프로젝트의 Identity and Access Management(IAM) API
  • 워크로드 아이덴티티 풀이 포함된 모든 Cloud 프로젝트의 Security Token Service API

이러한 로그를 사용 설정하면 사용자가 액세스 토큰 또는 서비스 계정의 ID 토큰을 요청할 때마다 Cloud 감사 로그에 항목이 추가됩니다.

CI/CD 기록이 Cloud 감사 로그와 상호 연결될 수 있는지 확인

서비스 계정은 일반적으로 코드 변경이 성공적으로 확인되고 배포가 승인된 후 CI/CD 시스템에서 배포를 수행하는 데 사용됩니다. 일반적으로 CI/CD 시스템은 배포로 이어지는 이벤트 기록을 유지합니다. 이 기록에는 해당 코드 검토, 커밋, 파이프라인 실행 ID 및 배포를 승인한 사람에 대한 정보가 포함될 수 있습니다.

배포에 의해 Google Cloud의 리소스가 수정되면 이러한 변경사항은 각 리소스의 Cloud 감사 로그에서 추적됩니다. Cloud 감사 로그에는 변경을 시작한 사용자 또는 서비스 계정에 대한 정보가 포함됩니다. 하지만 CI/CD 시스템에 의해 트리거된 배포에서는 서비스 계정 자체만으로 변경에 기여한 전체 체인을 재구성할 수 없는 경우가 많습니다.

CI/CD 시스템과 Google Cloud 전체에 일관된 감사 추적을 설정하려면 Cloud 감사 로그 기록이 CI/CD 시스템 기록의 이벤트와 상호 연관될 수 있는지 확인해야 합니다. Cloud 감사 로그에서 예기치 않은 이벤트가 발생하면 이 상관관계를 사용하여 변경사항이 CI/CD 시스템에서 실제로 수행되었는지 여부, 수행된 이유 및 승인한 사람을 확인할 수 있습니다.

Cloud 감사 로그 레코드와 CI/CD 시스템 기록 간의 상관관계를 설정하는 방법은 다음과 같습니다.

  • 각 CI/CD 파이프라인에서 실행된 API를 로깅합니다.
  • API가 작업 ID를 반환할 때마다 CI/CD 시스템 로그에 ID를 기록합니다.
  • X-Goog-Request-Reason HTTP 헤더를 API 요청에 추가하고 CI/CD 파이프라인 실행 ID를 전달합니다. 또는 Cloud 감사 로그에 캡처되도록 User-Agent 헤더에 정보를 삽입합니다.

거부되지 않도록 하려면 로그 파일을 구성하고 기록을 커밋하여 악의적인 행위자가 추적을 소급하여 숨길 수 없도록 합니다.

다음 단계