Políticas de análise de lint

Este tópico descreve como validar (lint) suas políticas de gerenciamento de identidade e acesso (IAM, na sigla em inglês).

Antes de começar

Noções básicas de análise de lint para políticas do IAM

No contexto das políticas do IAM, lint é um método de examinar uma política nova ou atual e de verificar problemas específicos. Esses problemas incluem as seguintes possibilidades:

  • Sugestões
  • Alertas
  • Informações que podem ajudar a melhorar a intenção da política, como melhor sintaxe e semântica
  • Erros de sintaxe ou de semântica que causarão falha nas operações de setIamPolicy

É possível usar a análise de lint de uma política como uma ferramenta de depuração para fornecer uma explicação detalhada para qualquer operação setIamPolicy() com falha. Ela também pode ser usada como ferramenta auxiliar para facilitar a criação de uma política do IAM e alcançar o resultado pretendido.

Como fazer análise de lint em uma condição

As expressões de condição costumam ficar complexas, especialmente em cenários que exigem várias cláusulas e operadores lógicos para restringir o acesso adequadamente. Se uma expressão de condição contiver uma lógica inválida ou se a sintaxe violar as restrições de uma expressão de condição, a operação setIamPolicy() falhará. Além disso, mesmo que uma condição atenda a todos os requisitos rígidos de sintaxe e semântica para atualização da política, é possível que ela contenha criações que levem a resultados de acesso inesperados durante a aplicação da política. Veja alguns exemplos desses casos:

  • Uso de funções não recomendadas
  • Uso de tipos de recursos legados ou nomes de serviços legados
  • Condições ineficazes, como um intervalo de data ou hora não aplicável

A análise de lint de uma condição realizará uma inspeção completa e informará as falhas que podem ocorrer na atualização da política, bem como outras criações questionáveis.

Antes de tentar configurar uma nova vinculação condicional de papel, é recomendável inspecionar a expressão primeiro. Esta seção mostra como inspecionar uma expressão de condição usando o Console do Cloud, a ferramenta de linha de comando gcloud ou a API REST.

Para inspecionar uma expressão de condição:

Console

  1. No Console do Cloud, acesse a página IAM.

    Acessar a página do IAM

  2. Clique em Selecionar um projeto e em Abrir.

  3. Na lista de membros, localize o membro desejado e clique no botão .

  4. No painel Editar permissões, localize o papel desejado que você quer inspecionar. Em seguida, em Condição, clique no nome da condição.

  5. No painel Editar condição, o Editor de condições permite inspecionar a expressão. No momento, o Criador de condições tem funcionalidade de inspeção limitada.

  6. Em Editor de condições, adicione ou edite manualmente uma expressão de condição.

  7. Valide a sintaxe da CEL clicando em Executar o linter acima da caixa de texto na parte superior direita. Se a sintaxe contiver erros, um ícone de aparecerá ao lado de cada linha da expressão. Se você passar o cursor do mouse sobre o ícone, a mensagem de erro referente a essa parte da expressão aparecerá e mostrará feedback útil para a depuração.

    É recomendável corrigir os erros antes de salvar a condição. Se as condições estiverem sintaticamente corretas, mas a operação de inspeção encontrar construtos questionáveis, um ícone de alerta () será exibido. Se você passar o cursor do mouse sobre o ícone, a mensagem de alerta referente a essa parte da expressão aparecerá e mostrará feedback útil para a depuração. Embora seja altamente recomendável, não é obrigatório corrigir os alertas antes de salvar a condição.

  8. Faça as alterações necessárias na expressão de condição. Depois que Executar o linter for acionado, ele continuará com a inspeção em segundo plano para facilitar a edição da expressão.

  9. Depois que a expressão passar pela análise de lint, clique em Salvar para aplicar a condição.

  10. Quando o painel Editar condição for fechado, clique em Salvar novamente no painel Editar permissões para atualizar a política do IAM.

Comando gcloud

Execute o comando gcloud alpha iam policies lint-condition para inspecionar uma determinada expressão de condição. Para executá-lo, crie um arquivo de texto que contenha a condição ou especifique as sinalizações para o título, a descrição e a expressão da condição.

No exemplo abaixo, será usado um arquivo de texto que contém a condição:

condition.json

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

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 inspeção contém um debugMessage que pode ser usado para ajudar a localizar o problema com a expressão de condição. Se a compilação da condição falhar, você verá vários tipos diferentes de validationUnitName com o seguinte texto de debugMessage:

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

Faça as alterações necessárias para que a expressão seja compilada com sucesso e, em seguida, tente inspecionar a condição novamente.

API REST

Chame lintPolicy() para inspecionar uma expressão condicional:

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

O corpo da solicitação contém a expressão de condição:

{
    "condition": {
      "title": "1_less_than_2",
      "description": "",
      "expression": "1 &lt;"
    }
}

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

{
  "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 \'&lt;EOF&gt;\' expecting {\'[\', \'{\', \'(\', \'.\', \'-\', \'!\', \'true\', \'false\', \'null\', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}\n  | 1&lt;\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 inspeção contém um debug_message que pode ser usado para ajudar a localizar o problema com a expressão de condição. Se a compilação da condição falhar, você verá vários tipos diferentes de validation_unit_name com o seguinte texto de debugMessage:

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

Faça as alterações necessárias para que a expressão seja compilada com sucesso e, em seguida, tente inspecionar a condição de expressão novamente.

Unidades de validação compatíveis

Conforme descrito na seção acima, uma unidade de validação é um tipo de inspeção individual que avalia se a expressão tem problemas sintáticos. A tabela abaixo resume as unidades de validação compatíveis, cada uma com o nível de inspeção desejado, a gravidade do resultado da inspeção e uma breve descrição.

Unidade de validação Nível de inspeção Gravidade Descrição
ConditionCompileCheck CONDITION ERROR A expressão da condição tem um erro de compilação como resultado de uma sintaxe CEL inválida.
ConditionComplexityCheck CONDITION ERROR A expressão da condição contém mais do que o máximo de 12 operadores lógicos.
DateTimeCheck CONDITION WARNING A expressão da condição especifica uma comparação de carimbo de data/hora como efetivamente verdadeiro ou falso, devido a um formato inválido do carimbo de data/hora (diferente da ISO 8601): ou o prazo final do carimbo ou início dele está no passado.
DateTimeRangeCheck CONDITION WARNING Valor fora do intervalo da função avançada do carimbo de data/hora pretendido e da expressão de comparação. Consulte aqui o intervalo de valores válidos para funções avançadas de carimbo de data/hora.
EffectiveTimeRangeCheck CONDITION WARNING Em um uso mais complexo de funções e comparação de carimbo de data/hora, a expressão resulta em um intervalo de tempo efetivo vazio e, portanto, é efetivamente falsa. Ou ainda, o intervalo de tempo abrange um intervalo completo e, portanto, é efetivamente verdadeiro.
ResourceServiceLiteralCheck CONDITION WARNING O valor resource.service especificado não é compatível. A expressão que usa esse literal de string para comparação de igualdade é efetivamente falsa. Consulte aqui os valores compatíveis.
ResourceTypeLiteralCheck CONDITION WARNING O valor resource.type especificado não é compatível. A expressão que usa esse literal de string para comparação de igualdade é efetivamente falsa. Consulte aqui os valores compatíveis.
RestrictedAttributesCheck CONDITION WARNING A expressão usa um atributo que está restrito no momento ou não é compatível. A definição da expressão condicional pode não ter êxito. Consulte aqui a lista de atributos e os estágios de versão.

Exemplos de inspeção

Esta seção traz exemplos de uso da política de inspeção para cada unidade de validação. Para cada unidade de validação, é fornecido o exemplo de entrada problemática. Cada exemplo demonstra a inspeção usando a ferramenta de linha de comando gcloud.

ConditionCompileCheck

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

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

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

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

DateTimeCheck

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

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

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

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

EffectiveTimeRangeCheck

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

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

ResourceServiceLiteralCheck

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

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

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

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

Exemplo de expressão de condição:

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

Comando de execução:

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

Resultado da inspeção:

lintResults:
- debugMessage: Condition attribute `request.auth.access_levels` is in private beta
    release and may be subject to whitelist control. Please check https://cloud.google.com/iam/docs/conditions-overview
    for the full list of restricted attributes
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 57
  severity: WARNING
  validationUnitName: LintValidationUnits/RestrictedAttributesCheck