Políticas de análise estática

Este tópico descreve como analisar ou validar as políticas de autorização da gestão de identidade e de acesso (IAM).

Antes de começar

Funções necessárias

Para analisar a política de autorização de um recurso, precisa de autorizações para obter o recurso e para obter e definir a política de autorização do recurso. Estas autorizações têm o seguinte formato, em que SERVICE é o nome do serviço que detém o recurso e RESOURCE_TYPE é o nome do tipo de recurso ao qual quer gerir o acesso:

  • SERVICE.RESOURCE_TYPE.get
  • SERVICE.RESOURCE_TYPE.getIamPolicy
  • SERVICE.RESOURCE_TYPE.setIamPolicy

Por exemplo, para aplicar o linting a uma política de permissões de um projeto, precisa das seguintes autorizações:

  • resourcemanager.projects.get
  • resourcemanager.projects.getIamPolicy
  • resourcemanager.projects.setIamPolicy

Para obter as autorizações necessárias, peça ao seu administrador para lhe conceder uma função predefinida ou personalizada que inclua as autorizações. Por exemplo, o seu administrador pode conceder-lhe a função de administrador de segurança (roles/iam.securityAdmin), que inclui autorizações para obter quase todos osTrusted Cloud recursos e gerir as respetivas políticas de autorização.

Compreender a análise estática para políticas de permissão

No contexto das políticas de permissão, a análise estática é um método de examinar uma política de permissão nova ou existente e verificar se existem problemas específicos. Estes problemas incluem o seguinte conjunto de possibilidades:

  • Sugestões
  • Avisos
  • Informações que podem ajudar a melhorar a intenção da política de permissão, como uma sintaxe e uma semântica melhores
  • Erros de sintaxe ou semânticos que fazem com que as operações setIamPolicy falhem

Se tentar atualizar uma política de autorização e receber um erro, a análise da política de autorização pode ajudar a encontrar a causa do erro. Também pode usar o linter para ajudar a garantir que uma associação de funções condicional tem o efeito pretendido.

Validar uma condição

As expressões de condições podem ser complexas, especialmente em cenários que requerem várias cláusulas e operadores lógicos para gerir adequadamente o acesso. Se uma expressão de condição contiver lógica inválida ou se a sintaxe violar as restrições de uma expressão de condição, não pode adicionar a condição a uma política de autorização.

Além disso, mesmo que uma expressão de condição use a sintaxe correta, pode conter erros semânticos, o que pode impedir que as suas políticas de autorização e associações de funções funcionem conforme esperado. Os erros semânticos comuns incluem o seguinte:

  • Utilização de funções não recomendadas
  • Utilização de tipos de recursos antigos ou nomes de serviços antigos
  • Condições ineficazes, como um intervalo de datas ou horas não aplicável

Quando aplica o lint a uma condição, o linter inspeciona a expressão da condição e comunica quaisquer erros de sintaxe. Também comunica possíveis erros semânticos que podem causar resultados inesperados.

Antes de tentar definir uma nova associação de função condicional, recomendamos que valide primeiro a expressão. Esta secção mostra como validar uma expressão de condição através da consola Trusted Cloud , da Google Cloud CLI ou da API REST.

Para verificar uma expressão condicional:

Consola

  1. Na Trusted Cloud consola, aceda à página IAM.

    Aceda ao IAM

  2. Clique em Selecionar um projeto, escolha um projeto e clique em Abrir.

  3. Na lista de responsáveis, localize o responsável pretendido e clique no botão Editar.

  4. No painel Editar autorizações, localize a função pretendida que quer analisar. Em seguida, em Condição do IAM (opcional), clique no nome da condição.

  5. No editor de condições, adicione ou edite manualmente uma expressão de condição.

  6. Para validar a sintaxe CEL, clique em Executar Linter.

    Se a sintaxe contiver erros, é apresentado um ícone de Erro junto à linha incorreta. Para ver detalhes sobre cada erro, mantenha o ponteiro sobre o ícone.

    Se a condição usar a sintaxe correta, mas o linter encontrar um possível problema, é apresentado um ícone de aviso junto à linha com o problema. Para ver detalhes sobre cada aviso, mantenha o ponteiro sobre o ícone.

  7. Faça as alterações necessárias à expressão de condição. Depois de clicar em Executar Linter, o linter é executado automaticamente em segundo plano enquanto edita a expressão.

    Tem de corrigir todos os erros antes de guardar a expressão de condição. Recomendamos vivamente que corrija também todos os avisos.

  8. Quando não existirem erros nem avisos, clique em Guardar para aplicar a condição.

  9. Quando o painel Editar condição estiver fechado, clique novamente em Guardar no painel Editar autorizações para atualizar a política de permissão.

gcloud

Execute o comando gcloud alpha iam policies lint-condition para analisar uma determinada expressão de condição. Para executar este comando, pode criar um ficheiro de texto que contenha a condição ou especificar flags para o título, a descrição e a expressão da condição.

O exemplo seguinte usa um ficheiro de texto que contém a seguinte condição:

condition.json

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

Executar comando:

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

A saída do comando contém o seguinte:

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
...

Cada um dos resultados da análise de código contém um debugMessage que pode ser usado para ajudar a localizar o problema com a expressão da condição. Se a condição não tiver sido compilada, pode ver muitos tipos de validationUnitName diferentes com o texto debugMessage seguinte:

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

Faça alterações para que a expressão seja compilada e, em seguida, aplique novamente o lint à condição.

REST

O método iamPolicies.lintPolicy valida uma expressão de condição numa política de autorização.

Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:

Método HTTP e URL:

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

Corpo JSON do pedido:

{
  "condition": {
    condition
  }
}

Para enviar o seu pedido, expanda uma destas opções:

O corpo da resposta contém um ou mais objetos LintResult, como os seguintes:

{
  "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"
  }
}

Cada um dos resultados da análise de código contém um debug_message que pode ser usado para ajudar a localizar o problema com a expressão da condição. Se a condição não tiver sido compilada, pode ver muitos tipos de validation_unit_name com o seguinte texto debugMessage:

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

Faça alterações para que a expressão seja compilada e, em seguida, aplique novamente o lint à condição.

Unidades de validação suportadas

Conforme descrito anteriormente, uma unidade de validação é um tipo de lint individual que avalia a expressão quanto a problemas sintáticos. A tabela abaixo resume as unidades de validação suportadas, cada uma com o nível de linting pretendido, a gravidade do resultado do linting e uma breve descrição.

Unidade de validação Nível de cotão Gravidade Descrição
ConditionCompileCheck CONDITION ERROR A expressão de condição contém um erro de compilação devido a uma sintaxe de IEC inválida.
ConditionComplexityCheck CONDITION ERROR A expressão de condição contém mais do que o máximo de 12 operadores lógicos.
DateTimeCheck CONDITION WARNING

A expressão de condição especifica uma comparação de data/hora que avalia sempre como verdadeira ou falsa devido a um destes problemas:

DateTimeRangeCheck CONDITION WARNING Valor fora do intervalo para a função de data/hora avançada pretendida e a expressão de comparação. Consulte os valores válidos para funções de data/hora avançadas.
DrgGetAttributeDefaultValueCheck CONDITION ERROR A expressão de condição chama api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', V), onde V é qualquer valor que não seja uma lista vazia, []. Para este atributo da API, V tem de ser sempre uma lista vazia.
EffectiveTimeRangeCheck CONDITION WARNING Numa utilização mais complexa das funções de data/hora e de comparação, a expressão resulta num intervalo de tempo efetivo vazio e, por isso, é efetivamente falsa. Em alternativa, o intervalo de tempo abrange um intervalo completo e, por isso, é efetivamente verdadeiro.
HasOnlyListConstCheck CONDITION ERROR A expressão de condição chama hasOnly(List<T>), onde o tipo T não é um tipo constante, como uma string ou um número inteiro. A função hasOnly() só aceita uma lista de constantes.
HasOnlyListLengthCheck CONDITION ERROR A expressão de condição chama hasOnly(List<T>) e List<T> contém mais do que o máximo de 10 elementos.
ResourceServiceLiteralCheck CONDITION WARNING O valor resource.service especificado não é suportado. A expressão que usa esse literal de string para comparação de igualdade é efetivamente falsa. Use um valor compatível.
ResourceTypeLiteralCheck CONDITION WARNING O valor resource.type especificado não é suportado. A expressão que usa esse literal de string para comparação de igualdade é, na prática, falsa. Use um valor compatível.
RestrictedAttributesCheck CONDITION WARNING A expressão usa um atributo restrito ou não suportado. A definição da expressão de condição pode não ter êxito. Consulte a lista de atributos.

Exemplos de linting

Esta secção mostra exemplos de condições que fazem com que cada unidade de validação comunique problemas. Cada exemplo demonstra a análise de código com a CLI do Google Cloud.

Sem problemas de validação

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

{}

ConditionCompileCheck

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

{
  "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"
}

Executar comando:

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

Resultado do lint:

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

DateTimeCheck

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

HasOnlyListConstCheck

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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

Condição de exemplo:

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

Executar comando:

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

Resultado do lint:

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