정책 린트

이 주제에서는 Identity and Access Management(IAM) 정책을 린트 또는 검증하는 방법을 설명합니다.

시작하기 전에

IAM 조건 개요를 읽고 IAM 조건의 기본 사항을 이해합니다.

IAM 정책의 린트 이해

IAM 정책의 맥락에서 린트는 새 정책이나 기존 정책을 검사하여 특정 문제를 확인하는 방법입니다. 이러한 문제에는 다음이 포함될 수 있습니다.

  • 제안
  • 경고
  • 정책의 의도를 개선할 수 있는 더 나은 구문 및 시맨틱스와 같은 정보
  • setIamPolicy 작업이 실패할 수 있는 구문 또는 시맨틱 오류

IAM 정책을 업데이트하려고 할 때 오류가 발생하면 정책 린트 작업으로 오류의 원인을 찾을 수 있습니다. 또한 린터를 사용하여 조건부 역할 결합에 의도한 효과가 있는지 확인할 수도 있습니다.

조건 린트

조건 표현식은 특히 여러 절과 논리 연산자를 사용하여 액세스를 적절하게 관리해야 하는 상황에서 복잡해질 수 있습니다. 조건 표현식에 잘못된 논리가 포함되거나 구문이 조건 표현식의 제한을 위반하면 IAM 정책에 조건을 추가할 수 없습니다.

또한 조건 표현식에서 올바른 구문을 사용하더라도 IAM 정책 및 역할 결합이 예상대로 작동하지 않을 수 있는 시맨틱 오류가 포함되어 있을 수 있습니다. 일반적인 시맨틱 오류는 다음과 같습니다.

  • 권장되지 않는 함수 사용
  • 기존 리소스 유형 또는 기존 서비스 이름 사용
  • 적용할 수 없는 날짜 또는 시간 범위와 같은 무효 조건

조건을 린트하면 린터가 조건 표현식을 검사하고 구문 오류를 보고합니다. 또한 예기치 않은 결과가 발생할 수 있는 시맨틱 오류도 보고합니다.

새 조건부 역할 binding을 설정하기 전에 먼저 표현식을 린트하는 것이 좋습니다. 이 섹션에서는 Cloud Console, gcloud 명령줄 도구 또는 REST API를 사용하여 조건 표현식을 린트하는 방법을 보여줍니다.

조건 표현식을 린트하려면 다음을 수행합니다.

Console

  1. Cloud Console에서 IAM 페이지로 이동합니다.

    IAM으로 이동

  2. 프로젝트 선택을 클릭하고 프로젝트를 선택한 다음 열기를 클릭합니다.

  3. 구성원 목록에서 원하는 구성원을 찾고 수정 버튼을 클릭합니다.

  4. 권한 수정 패널에서 원하는 역할을 찾습니다. 그런 다음 조건에서 조건의 이름을 클릭합니다.

  5. 조건 편집기에서 조건 표현식을 직접 추가하거나 수정합니다.

  6. CEL 구문을 검증하려면 린터 실행을 클릭합니다.

    구문에 오류가 있으면 잘못된 줄 옆에 오류 아이콘이 표시됩니다. 각 오류에 대한 세부정보를 확인하려면 아이콘 위에 마우스 포인터를 올려 놓습니다.

    조건에서 올바른 구문을 사용하지만 린터가 발생 가능한 문제를 발견하면 문제가 있는 줄 옆에 경고 아이콘이 표시됩니다. 각 경고에 대한 세부정보를 확인하려면 아이콘 위에 마우스 포인터를 올려 놓습니다.

  7. 조건 표현식을 필요한 대로 변경합니다. 린터 실행을 클릭하면 표현식을 수정하는 동안 린터가 백그라운드에서 자동으로 실행됩니다.

    조건 표현식을 저장하기 전에 모든 오류를 수정해야 합니다. 또한 모든 경고도 수정하는 것이 좋습니다.

  8. 오류나 경고가 없으면 저장을 클릭하여 조건을 적용합니다.

  9. 조건 수정 패널이 닫히면 권한 수정 패널에서 저장을 다시 클릭하여 IAM 정책을 업데이트합니다.

gcloud

gcloud alpha iam policies lint-condition 명령어를 실행하여 지정된 조건 표현식을 린트합니다. 이 명령어를 실행하려면 조건이 포함된 텍스트 파일을 만들거나 조건의 제목, 설명, 표현식에 플래그를 지정합니다.

다음 예시에서는 다음 조건을 포함하는 텍스트 파일을 사용합니다.

condition.json

{
  "condition": {
    "title": "1_less_than_2",
    "description": "",
    "expression": "1 <"
  }
}

명령어:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

명령어의 출력에는 다음이 포함됩니다.

lintResults:
- debugMessage: |-
    ERROR: Parse expression:1:3: mismatched input '<EOF>' expecting {'[', '{', '(', '.', '-', '!', 'true', 'false', 'null', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}
      | 1 >
      | ...^
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 3
  severity: ERROR
  validationUnitName: LintValidationUnits/ConditionCompileCheck
...

각 린트 결과에는 debugMessage가 포함되어 조건 표현식의 문제점을 찾는 데 도움이 됩니다. 조건에서 컴파일할 수 없을 때 다음 debugMessage 텍스트가 포함된 여러 validationUnitName 유형을 볼 수 있습니다.

The validation unit is skipped due to absence of a required object: CheckedExpr

조건 표현식이 컴파일되도록 변경한 다음 조건을 다시 린트합니다.

REST

iamPolicies.lintPolicy 메서드는 IAM 정책의 조건 표현식을 린트하거나 확인합니다.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • condition: 린트 조건을 나타내는 Expr 객체입니다. 예를 들면 다음과 같습니다.

    "title": "1_less_than_2",
    "description": "",
    "expression": "1 <"
    

    Expr 객체의 형식에 관해 알아보려면 Expr 스키마 참조를 확인하세요.

HTTP 메서드 및 URL:

POST https://iam.googleapis.com/v1/iamPolicies:lintPolicy

JSON 요청 본문:

{
  "condition": {
    condition
  }
}

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

응답 본문에는 다음과 같은 하나 이상의 LintResult 객체가 포함됩니다.

{
  "lint_results": {
    "level": "CONDITION",
    "validation_unit_name": "LintValidationUnits/ConditionCompileCheck",
    "severity": "ERROR",
    "field_name": "condition.expression",
    "location_offset": "2",
    "debug_message": "ERROR: Parse expression:1:2: mismatched input \'<EOF>\' expecting {\'[\', \'{\', \'(\', \'.\', \'-\', \'!\', \'true\', \'false\', \'null\', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}\n  | 1<\n  | ..^"
  },
  "lint_results": {
    "level": "CONDITION",
    "validation_unit_name": "LintValidationUnits/ConditionComplexityCheck",
    "severity": "NOTICE",
    "field_name": "condition.expression",
    "debug_message": "The validation unit is skipped due to absence of a required object: CheckedExpr"
  }
}

각 린트 결과에는 debug_message가 포함되어 조건 표현식의 문제점을 찾는 데 도움이 됩니다. 조건에서 컴파일할 수 없을 때 다음 debugMessage 텍스트가 포함된 여러 validation_unit_name 유형을 볼 수 있습니다.

The validation unit is skipped due to absence of a required object: CheckedExpr

조건 표현식이 컴파일되도록 변경한 다음 조건을 다시 린트합니다.

지원되는 검증 단위

이전에 설명한 것처럼 검증 단위는 구문 문제에 대한 표현식을 평가하는 개별 린트 유형입니다. 아래의 표는 각각의 린트 수준, 린트 결과 심각도, 간단한 설명이 포함된 지원 검증 단위를 요약한 것입니다.

검증 단위 린트 수준 심각도 설명
ConditionCompileCheck CONDITION ERROR 조건 표현식에 잘못된 CEL 구문으로 인한 컴파일 오류가 있습니다.
ConditionComplexityCheck CONDITION ERROR 조건 표현식에 포함된 논리 연산자 수가 최댓값인 12개를 초과합니다.
DateTimeCheck CONDITION WARNING

조건 표현식은 다음 문제 중 하나로 인해 항상 참 또는 거짓으로 평가되는 타임스탬프 비교를 지정합니다.

DateTimeRangeCheck CONDITION WARNING 의도한 고급 타임스탬프 함수 및 비교 표현식에 대한 범위를 벗어난 값입니다. 고급 타임스탬프 함수는 유효한 값을 참조하세요.
DrgGetAttributeDefaultValueCheck CONDITION ERROR 조건 표현식은 api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', V)를 호출합니다. 여기서 V는 빈 목록 []가 아닌 다른 값입니다. 이 API 속성의 경우 V는 항상 빈 목록이어야 합니다.
EffectiveTimeRangeCheck CONDITION WARNING 타임스탬프 함수와 비교를 더 복잡하게 사용하면 표현식의 유효 시간 범위가 비어 사실상 거짓입니다. 또는 시간 범위가 전체 범위를 포함하므로 사실상 참입니다.
HasOnlyListConstCheck CONDITION ERROR 조건 표현식은 hasOnly(List<T>)를 호출합니다. 여기서 T 유형은 문자열 또는 정수와 같은 상수 유형이 아닙니다. hasOnly() 함수는 상수 목록만 허용합니다.
HasOnlyListLengthCheck CONDITION ERROR 조건 표현식은 hasOnly(List<T>)를 호출하고 List<T>에는 최대치인 10개를 초과하는 요소가 포함됩니다.
ResourceServiceLiteralCheck CONDITION WARNING 지정된 resource.service 값은 지원되지 않습니다. 균등 비교에 이러한 문자열 리터럴을 사용하는 표현식은 사실상 거짓입니다. 지원되는 값을 사용하세요.
ResourceTypeLiteralCheck CONDITION WARNING 지정된 resource.type 값은 지원되지 않습니다. 균등 비교에 이러한 문자열 리터럴을 사용하는 표현식은 사실상 거짓입니다. 지원되는 값을 사용하세요.
RestrictedAttributesCheck CONDITION WARNING 표현식에 제한되거나 지원되지 않는 속성이 사용됩니다. 조건 표현식 설정이 성공하지 못할 수 있습니다. 속성 목록을 참조하세요.

린트 예시

이 섹션에서는 각 검증 단위에 대한 린트 정책의 사용 예시를 제공합니다. 각 검증 단위에 대해 문제가 있는 입력 예시가 제공됩니다. 각 예시는 gcloud 명령줄 도구를 사용하여 린트를 보여줍니다.

ConditionCompileCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Condition not compiling",
    "description": "",
    "expression": "true=false"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: |-
    ERROR: Parse expression:1:4: token recognition error at: '=f'
      | true=false
      | ....^
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 4
  severity: ERROR
  validationUnitName: LintValidationUnits/ConditionCompileCheck

ConditionComplexityCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Condition not compiling",
    "description": "",
    "expression":
      "1<2 || 2<3 || 3<4 || 4<5 || 5<6 || 6<7 || 7<8 || 8<9 || 9<10 || 10<11 || 11<12 || 12<13 || 13<14 || 14<15"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: Logical operators count must not be more than 12
  fieldName: condition.expression
  level: CONDITION
  severity: ERROR
  validationUnitName: LintValidationUnits/ConditionComplexityCheck

DateTimeCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Condition not compiling",
    "description": "",
    "expression": "request.time < timestamp('2000-01-01T00:00:00Z')"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: Ineffective date time value 2000-01-01T00:00:00+00:00 parsed
    from "2000-01-01T00:00:00Z"; condition is effectively False. Time expired
    already.
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 25
  severity: WARNING
  validationUnitName: LintValidationUnits/DateTimeCheck

DateTimeRangeCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Time function out of range",
    "description": "",
    "expression": "request.time.getMonth() > 13"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: The value being compared to the specified timestamp function
    (getMonth) must be in range [0, 11].
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 26
  severity: WARNING
  validationUnitName: LintValidationUnits/DateTimeRangeCheck

DrgGetAttributeDefaultValueCheck

조건 표현식 예시:

{
  "condition": {
    "title": "DRG condition takes non empty list as default value",
    "description": "",
    "expression":
      "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', ['roles/viewer']).hasOnly(['roles/editor'])"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: api.getAttribute call on
    'iam.googleapis.com/modifiedGrantsByRole' can only
    accept empty list ('[]') as default value.
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 60
  severity: ERROR
  validationUnitName: LintValidationUnits/DrgGetAttributeDefaultValueCheck

EffectiveTimeRangeCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Empty time range",
    "description": "",
    "expression": "request.time.getMonth() > 5 && request.time.getMonth() < 4"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: The aggregate of time functions [getMonth] results in empty ranges.
  fieldName: condition.expression
  level: CONDITION
  severity: WARNING
  validationUnitName: LintValidationUnits/EffectiveTimeRangeCheck

HasOnlyListConstCheck

조건 표현식 예시:

{
  "condition": {
    "title": "hasOnly contains more than constant value",
    "description": "",
    "expression":
      "api.getAttribute('somekey', []).hasOnly(['somevalue', resource.name])"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: hasOnly() expects an argument of type list containing only const
      values, but a non-const expression was found in the list.
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 59
  severity: ERROR
  validationUnitName: LintValidationUnits/HasOnlyListConstCheck

HasOnlyListLengthCheck

조건 표현식 예시:

{
  "condition": {
    "title": "hasOnly contains more than 10 elements",
    "description": "",
    "expression":
      "api.getAttribute('somekey', []).hasOnly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: The list argument to hasOnly() cannot have more than 10 elements
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 39
  severity: ERROR
  validationUnitName: LintValidationUnits/HasOnlyListLengthCheck

ResourceServiceLiteralCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Condition with unsupported resource service string",
    "description": "",
    "expression": "resource.service == 'resourcemanager'"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: 'resource.service : resourcemanager is not supported. Using this
    value in condition may lead to unintended consequences. Check user guide at
    https://cloud.google.com/iam/docs/conditions-resource-attributes#resource_service_values
    for supported values for resource.service.'
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 20
  severity: WARNING
  validationUnitName: LintValidationUnits/ResourceServiceLiteralCheck

ResourceTypeLiteralCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Condition with legacy resource type",
    "description": "",
    "expression": "resource.type == 'resourcemanager.projects'"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: 'resource.type : resourcemanager.projects is not supported.
    Using this value in condition may lead to unintended consequences. Check
    user guide at https://cloud.google.com/iam/docs/conditions-resource-attributes#resource_type_values
    for supported values for resource.type.'
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 17
  severity: WARNING
  validationUnitName: LintValidationUnits/ResourceTypeLiteralCheck

RestrictedAttributesCheck

조건 표현식 예시:

{
  "condition": {
    "title": "Condition with restricted attribute",
    "description": "",
    "expression": "'accessPolicies/123/accesslevels/TRUSTED' in request.auth.access_levels"
  }
}

명령어 실행:

gcloud alpha iam policies lint-condition --condition-from-file="condition.json"

린트 결과:

lintResults:
- debugMessage: Condition attribute `request.auth.access_levels` is restricted
    or unsupported. Please check https://cloud.google.com/iam/docs/conditions-overview
    for the full list of supported attributes
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 57
  severity: WARNING
  validationUnitName: LintValidationUnits/RestrictedAttributesCheck