서비스 계정에 대한 컨텍스트 인식 액세스 구성

이 가이드에서는 정의한 액세스 수준을 기반으로 서비스 계정의 Google Cloud API 액세스를 보호하기 위해 컨텍스트 인식 액세스를 설정하는 방법을 설명합니다.

제한사항

서비스 계정의 컨텍스트 인식 액세스 정책에는 다음 제한사항이 적용됩니다.

  • 서비스 계정이 워크플로 실행 및 Cloud Scheduler에 사용되는 경우 네트워크 기반 또는 IP 주소 기반 속성을 서비스 계정 바인딩에 사용할 수 없습니다.

  • kubectl를 사용하는 비공개 GKE 클러스터와 인증 프록시를 사용하는 Cloud SQL에 대한 연결은 컨텍스트 인식 액세스 정책으로 차단할 수 없습니다.

  • 서비스 계정에 바인드된 액세스 수준에 Device 속성과 같이 지원되지 않는 속성이 포함된 경우 API 액세스가 거부됩니다.

  • 서비스 계정에는 범위가 지정된 액세스 수준이 지원되지 않습니다.

Cloud Build 및 Cloud Run을 사용하는 경우 다음 내장 VPC 기능을 사용하는 것이 좋습니다.

시작하기 전에

  1. Google Cloud 조직과 하나 이상의 Google Cloud 프로젝트가 있어야 합니다.
  2. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  3. Google Cloud CLI를 설치합니다.

  4. 외부 ID 공급업체(IdP)를 사용하는 경우 먼저 제휴 ID로 gcloud CLI에 로그인해야 합니다.

  5. gcloud CLI를 초기화하려면, 다음 명령어를 실행합니다.

    gcloud init
  6. Google Cloud 프로젝트를 만들거나 선택합니다.

    프로젝트를 선택하거나 만드는 데 필요한 역할

    • 프로젝트 선택: 프로젝트를 선택하는 데는 특정 IAM 역할이 필요하지 않습니다. 역할이 부여된 프로젝트를 선택하면 됩니다.
    • 프로젝트 만들기: 프로젝트를 만들려면 resourcemanager.projects.create 권한이 포함된 프로젝트 생성자 역할(roles/resourcemanager.projectCreator)이 필요합니다. 역할 부여 방법 알아보기
    • Google Cloud 프로젝트를 만듭니다.

      gcloud projects create PROJECT_ID

      PROJECT_ID를 만들려는 Google Cloud 프로젝트의 이름으로 바꿉니다.

    • 만든 Google Cloud 프로젝트를 선택합니다.

      gcloud config set project PROJECT_ID

      PROJECT_ID을 Google Cloud 프로젝트 이름으로 바꿉니다.

  7. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  8. Google Cloud CLI를 설치합니다.

  9. 외부 ID 공급업체(IdP)를 사용하는 경우 먼저 제휴 ID로 gcloud CLI에 로그인해야 합니다.

  10. gcloud CLI를 초기화하려면, 다음 명령어를 실행합니다.

    gcloud init
  11. Google Cloud 프로젝트를 만들거나 선택합니다.

    프로젝트를 선택하거나 만드는 데 필요한 역할

    • 프로젝트 선택: 프로젝트를 선택하는 데는 특정 IAM 역할이 필요하지 않습니다. 역할이 부여된 프로젝트를 선택하면 됩니다.
    • 프로젝트 만들기: 프로젝트를 만들려면 resourcemanager.projects.create 권한이 포함된 프로젝트 생성자 역할(roles/resourcemanager.projectCreator)이 필요합니다. 역할 부여 방법 알아보기
    • Google Cloud 프로젝트를 만듭니다.

      gcloud projects create PROJECT_ID

      PROJECT_ID를 만들려는 Google Cloud 프로젝트의 이름으로 바꿉니다.

    • 만든 Google Cloud 프로젝트를 선택합니다.

      gcloud config set project PROJECT_ID

      PROJECT_ID을 Google Cloud 프로젝트 이름으로 바꿉니다.

  12. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  13. Google Cloud CLI 구성요소를 업데이트합니다.
    gcloud components update --quiet
  14. 아직 없는 경우 프로젝트에 서비스 계정을 만듭니다. 이 서비스 계정은 액세스 정책의 타겟입니다.

필요한 역할

이 섹션에서는 컨텍스트 인식 액세스를 사용하는 데 필요한 Identity and Access Management (IAM) 역할을 설명합니다.

프로젝트 수준 역할

프로젝트 수준에서 필요한 권한을 얻으려면 관리자에게 사용자 계정 또는 서비스 계정에 대한 서비스 계정 관리자 (roles/iam.serviceAccountAdmin) IAM 역할을 부여해 달라고 요청하세요. 역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

이 사전 정의된 역할에는 프로젝트 수준에서 필요한 the required permissions 권한이 포함되어 있습니다.

커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 가져올 수도 있습니다.

조직 수준 역할

조직 수준에서 필요한 권한을 얻으려면 관리자에게 사용자 계정 또는 서비스 계정에 다음 IAM 역할을 부여해 달라고 요청하세요.

역할 부여에 대한 자세한 내용은 프로젝트, 폴더, 조직에 대한 액세스 관리를 참조하세요.

이 사전 정의된 역할에는 조직 수준에서 필요한 the required permissions 권한이 포함되어 있습니다.

커스텀 역할이나 다른 사전 정의된 역할을 사용하여 이 권한을 가져올 수도 있습니다.

액세스 정책을 다양한 리소스 수준에 바인딩

리소스 계층 구조의 여러 수준에 있는 리소스에 동일한 시행 모드의 액세스 정책을 바인딩할 수 있습니다. 리소스가 액세스를 시도하면 컨텍스트 인식 액세스는 상위 수준 리소스에 바인딩된 정책을 사용하기 전에 해당 리소스에 바인딩된 정책을 사용합니다.

예를 들어 시행 모드 액세스 정책을 서비스 계정에 직접 바인딩하고 다른 시행 모드 정책을 서비스 계정이 포함된 프로젝트에 바인딩할 수 있습니다. 서비스 계정이 리소스에 액세스하려고 하면 컨텍스트 인식 액세스에서 서비스 계정에 바인딩된 정책을 평가합니다. 액세스 정책이 바인딩되지 않은 프로젝트의 다른 서비스 계정의 경우 컨텍스트 인식 액세스에서 프로젝트에 바인딩된 시행 모드 정책을 평가합니다. 프로젝트 수준 정책과 서비스 계정 수준 정책 모두에 시행 모드가 드라이 런으로 설정된 경우에도 마찬가지입니다.

여러 액세스 정책을 사용하여 액세스 정책을 점진적으로 선택적으로 배포할 수 있습니다. 예를 들어 다음 작업을 할 수 있습니다.

  1. 프로젝트 수준에서 테스트 실행 모드로 액세스 정책을 바인딩하고 Cloud 감사 로그에서 액세스 거부 이벤트를 확인하여 예상대로 작동하는지 확인합니다.
  2. 시행 모드의 액세스 정책을 특정 서비스 계정에만 바인딩합니다.
  3. 프로젝트 수준에서 시행 모드로 액세스 정책을 바인딩하고, 필요에 따라 제한이 적은 시행 모드 액세스 정책을 특정 서비스 계정에 바인딩합니다.

서비스 계정의 액세스 수준 속성

이 섹션에는 서비스 계정에 지원되는 액세스 수준이 나열되어 있습니다.

서비스 계정에는 다음 속성이 지원됩니다.

  • 공개 IP 주소를 기반으로 하는 IP 서브네트워크
  • 비공개 IP 주소를 기반으로 하는 VPC 네트워크
  • 공개 IP 주소를 기반으로 하는 지리적 위치

    서비스 계정이 Google CloudAPI에 요청을 하면 컨텍스트 인식 액세스에서 요청을 평가하고 요청의 IP 주소를 컨텍스트 인식 액세스 정책에 지정된 IP 주소와 비교합니다. IP 주소가 일치하면 API 호출이 허용됩니다. IP 주소가 일치하지 않으면 API 호출이 거부됩니다.

  • Common Expression Language (CEL) 표현식이 있는 맞춤 액세스 수준입니다. 액세스를 허용하려면 표현식이 true로 평가되어야 하고 액세스를 거부하려면 false로 평가되어야 합니다.

    다음 CEL 표현식은 서비스 계정의 액세스를 제한하는 데 유용합니다.

    요청이 하나 이상의 지정된 프로젝트 번호에서 시작된 경우 표현식은 true로 평가됩니다.

        expression: "originatesFromProjects(origin, [PROJECT_NUMBER, ...])"
        

    originatesFromProjects는 요청이 지정된 프로젝트와 연결된 네트워크에서 오는지, 요청이 비공개 IP 주소에서 오는지 확인합니다.

  • 지정된 시간대의 요청 시간과 날짜를 기반으로 하는 시간입니다.

    자세한 내용은 시간 및 요일 액세스 조건 구성을 참고하세요.

액세스 수준 만들기

이 섹션에서는 조직 내에서 액세스 수준을 만드는 방법을 설명합니다. 액세스 수준은 액세스가 허용되는 조건을 정의합니다.

  1. 안내에 따라 기본 액세스 수준을 만들거나 맞춤 액세스 수준을 만듭니다.

  2. 액세스 정책의 전체 이름을 기록합니다. 전체 이름은 accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME 형식입니다.

액세스 바인딩 만들기

액세스 수준을 선택한 서비스 계정에 바인딩합니다. 이렇게 하면 액세스 수준에 정의된 조건이 적용됩니다. 액세스 수준을 단일 서비스 계정 또는 프로젝트 내의 모든 서비스 계정에 바인딩할 수 있습니다.

액세스 수준을 특정 서비스 계정에 바인딩

이 섹션에서는 액세스 수준을 특정 서비스 계정에 바인딩하는 방법을 설명합니다.

gcloud

gcloud CLI를 사용하여 액세스 수준을 서비스 계정에 바인딩합니다.

gcloud access-context-manager cloud-bindings create \
    --organization=ORGANIZATION_ID \
    --service-account=SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com \
    --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

다음을 바꿉니다.

  • ORGANIZATION_ID: Google Cloud조직 ID
  • SERVICE_ACCOUNT_NAME: 타겟 서비스 계정의 이메일이 아닌 이름
  • SERVICE_ACCOUNT_PROJECT_ID: 대상 서비스 계정이 포함된 프로젝트의 ID
  • POLICY_ID: 액세스 정책 ID
  • ACCESS_LEVEL_NAME: 사용자가 만든 액세스 수준의 이름

    액세스 수준을 적용하고 액세스를 허용하지 않고 컨텍스트 인식 액세스를 사용하려면 드라이런 모드에서 액세스 수준을 바인딩하면 됩니다.

REST API

REST API를 사용하여 액세스 수준을 특정 서비스 계정에 바인딩하려면 다음 명령어를 실행합니다.

  1. 다음 콘텐츠로 request.json 파일을 만듭니다.

    {
      "principal": {
        "serviceAccount": "SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    다음을 바꿉니다.

    • SERVICE_ACCOUNT_NAME: 타겟 서비스 계정의 이메일이 아닌 이름

    • SERVICE_ACCOUNT_PROJECT_ID: 대상 서비스 계정이 포함된 프로젝트의 ID

    • POLICY_ID: 액세스 정책 ID

    • ACCESS_LEVEL_NAME: 생성한 액세스 수준의 이름

  2. 다음 명령어를 실행합니다.

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" \
      -d @request.json \
      "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    다음을 바꿉니다.

    • PROJECT_ID: API 호출에 사용하는 프로젝트의 ID

    • ORGANIZATION_ID: Google Cloud조직 ID입니다.

액세스 수준을 프로젝트의 모든 서비스 계정에 바인딩

이 섹션에서는 액세스 수준을 프로젝트의 모든 서비스 계정에 바인딩하는 방법을 설명합니다.

gcloud

gcloud CLI를 사용하여 액세스 수준을 프로젝트의 모든 서비스 계정에 바인딩하려면 다음 명령어를 실행합니다.

gcloud access-context-manager cloud-bindings create \
  --organization=ORGANIZATION_ID \
  --service-account-project-number=PROJECT_NUMBER \
  --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

다음을 바꿉니다.

  • ORGANIZATION_ID: Google Cloud조직 ID
  • PROJECT_NUMBER: 액세스 권한을 바인딩하려는 모든 서비스 계정이 포함된 프로젝트의 프로젝트 번호
  • POLICY_ID: 액세스 정책 ID
  • ACCESS_LEVEL_NAME: 생성한 액세스 수준의 이름입니다.

REST API

REST API를 사용하여 액세스 수준을 프로젝트의 모든 서비스 계정에 바인딩하려면 다음 단계를 따르세요.

  1. 다음 콘텐츠로 request.json 파일을 만듭니다.

    {
      "principal": {
        "serviceAccountProjectNumber": "PROJECT_NUMBER"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    다음을 바꿉니다.

    • PROJECT_NUMBER: 액세스 권한을 바인딩하려는 모든 서비스 계정이 포함된 프로젝트의 프로젝트 번호
    • POLICY_ID: 액세스 정책 ID
    • ACCESS_LEVEL_NAME: 생성한 액세스 수준의 이름입니다.
  2. 다음 명령어를 실행합니다.

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    다음을 바꿉니다.

    • PROJECT_ID: API 호출에 사용하는 프로젝트의 ID
    • ORGANIZATION_ID: Google Cloud조직 ID

액세스 수준을 시행하고 액세스를 거부하지 않고 컨텍스트 인식 액세스를 사용하려면 드라이런 모드에서 액세스 정책을 바인딩하면 됩니다.

바인딩 생성 작업의 API 응답에는 고유 바인딩 ID가 포함된 바인딩 이름이 포함됩니다.

테스트 실행 모드 사용

테스트 실행 모드에서 액세스 정책을 바인딩할 수 있습니다. 테스트 실행 모드를 사용하면 서비스 계정에서 강제 적용 없이 리소스에 계속 액세스할 수 있습니다. 하지만 서비스 계정이 액세스 정책을 위반하는 액세스를 시도하면 위반사항이 Cloud 감사 로그에 로깅됩니다.

테스트 실행 모드에서 액세스 정책 바인딩

gcloud

테스트 실행 모드에서 액세스 정책을 바인딩하려면 --level 매개변수를 다음과 같이 형식이 지정된 --dry-run-level로 바꿉니다.

--dry-run-level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

REST API

테스트 실행 모드에서 액세스 정책을 바인딩하려면 다음 콘텐츠로 request.json 파일을 만듭니다.

{
"principal": {
  "serviceAccountProjectNumber": "TARGET_PROJECT_NUMBER"
},
"dryRunAccessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
}

다음을 바꿉니다.

  • TARGET_PROJECT_NUMBER: 대상 프로젝트의 프로젝트 번호
  • POLICY_ID: 액세스 정책 ID
  • ACCESS_LEVEL_NAME: 액세스 수준의 이름

Cloud 감사 로그 확인

이 섹션에서는 서비스 계정의 드라이런 모드 액세스 거부를 Cloud 감사 로그에서 확인하는 방법을 설명합니다. Cloud 감사 로그에서 테스트 실행 모드 항목을 검색하는 방법을 자세히 알아보려면 테스트 실행 모드 로그 보기를 참고하세요.

콘솔

Google Cloud 콘솔을 사용하여 Cloud 감사 로그 드라이런 모드 서비스 계정 액세스 거부를 보려면 다음을 수행하세요.

Google Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.

로그 탐색기로 이동

검색창을 사용하여 이 페이지를 찾은 경우 부제목이 Logging인 결과를 선택합니다.

  1. Google Cloud 콘솔에서 프로젝트 또는 조직을 선택합니다.

  2. 로그 쿼리 필드에 다음 쿼리를 입력합니다.

    protoPayload.serviceName="contextawareaccess.googleapis.com"
    protoPayload.metadata.dryRunEvaluationResult:DENIED
    SEARCH("`SERVICE_ACCOUNT_NAME`")
    
  3. 시간 범위 선택기에서 지난 30분, 지난 1시간, 지난 24시간과 같은 사전 정의된 상대 시간을 선택하거나 맞춤 범위를 지정합니다.

gcloud

gcloud CLI를 사용하여 Cloud 감사 로그 테스트 실행 모드 서비스 계정 액세스 거부를 보려면 다음을 실행하세요.

gcloud logging read \
'protoPayload.serviceName="contextawareaccess.googleapis.com" AND
 protoPayload.metadata.dryRunEvaluationResult:DENIED AND
 SEARCH("`SERVICE_ACCOUNT_NAME`")' \
  --organization=ORGANIZATION_ID

다음을 바꿉니다.

  • ORGANIZATION_ID: 조직의 ID
  • SERVICE_ACCOUNT_NAME: 서비스 계정의 이름입니다.

gcloud logging read 명령어는 상대 시간 프레임에 대한 로깅 정보를 보기 위해 --freshness 플래그를 지원합니다. 예를 들어 명령어에 --freshness=3h를 추가하면 지난 3시간 동안의 드라이런 모드 로그 항목을 볼 수 있습니다.

문제 해결

이 섹션에서는 서비스 계정의 컨텍스트 인식 액세스 문제를 해결하는 방법을 설명합니다.

일반적인 문제해결

  1. Cloud 감사 로그를 검토합니다.

    다음 로그 쿼리를 사용하고 로그 항목을 검토하여 자세한 내용을 확인하세요.

    protoPayload.serviceName="contextawareaccess.googleapis.com"
    
  2. 컨텍스트 인식 액세스에서 시행 이벤트를 로깅할 때 보고하는 액세스 수준 리소스 이름을 검토합니다.

  3. 액세스 수준이 조직 수준 리소스인지 확인합니다.

  4. 액세스 정책의 액세스 수준이 서비스 계정에서 지원되는 속성을 기반으로 하는지 확인합니다.

  5. 액세스 정책이 의도한 서비스 계정에 바인딩되어 있는지 확인합니다.

  6. 액세스 정책에 의해 사용자 ID의 액세스가 제한되지 않는지 확인합니다. 사용자 ID가 바인딩된 액세스 정책이 있는 Google 그룹의 구성원인 경우 발생할 수 있습니다. 이 정책은 사용자 액세스를 제한하여 서비스 계정으로의 호출 흐름을 방해할 수 있습니다.

  7. 보안 관리자에게 문의하세요.

액세스가 거부되었습니다.

다음과 같은 이유로 액세스가 거부되었습니다.

  • 테스트 실행 모드가 아닌 시행 모드에서 액세스 정책을 바인딩했습니다.

    시행 대신 테스트 실행 모드를 사용하여 서비스 계정이 리소스에 액세스하고 리소스에 대한 액세스를 실제로 거부하지 않고 시행 이벤트를 로깅하도록 할 수 있습니다. 또한 일반 문제 해결 안내를 따를 수도 있습니다.

  • 더 많은 소스를 포함하도록 액세스 수준을 업데이트해야 합니다. 예를 들어 액세스 수준이 생성될 때 포함되지 않은 IP 주소가 사용되고 있습니다.

다음 단계