Stratégies concernant les fonctions d'analyse lint

Cet article explique comment exécuter les fonctions d'analyse lint sur vos stratégies d'autorisation Cloud IAM (Cloud Identity and Access Management) ou les valider.

Avant de commencer

Rôles requis

Pour exécuter les fonctions d'analyse lint sur la stratégie d'autorisation d'une ressource, vous devez disposer d'autorisations permettant d'obtenir et de définir la stratégie d'autorisation de la ressource. Ces autorisations présentent le format suivant, où SERVICE est le nom du service propriétaire de la ressource et RESOURCE_TYPE est le nom du type de ressource dont vous souhaitez gérer l'accès :

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

Par exemple, pour exécuter les fonctions d'analyse lint sur la stratégie d'autorisation d'un projet, vous devez disposer des autorisations suivantes :

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

Pour obtenir les autorisations requises, demandez à votre administrateur de vous attribuer un rôle prédéfini ou personnalisé qui inclut ces autorisations. Par exemple, votre administrateur peut vous accorder le rôle "Administrateur de sécurité" (roles/iam.securityAdmin), qui inclut des autorisations permettant d'obtenir presque toutes les ressources Google Cloud et de gérer leurs stratégies d'autorisation.

Comprendre les fonctions d'analyse lint pour les stratégies d'autorisation

Dans le contexte des stratégies d'autorisation, l'analyse lint est une méthode qui consiste à examiner une stratégie d'autorisation existante ou nouvelle et à la vérifier pour détecter des problèmes spécifiques. Ces problèmes incluent les possibilités suivantes :

  • Suggestions
  • Avertissements
  • Informations susceptibles d'améliorer l'objectif de la stratégie d'autorisation, telles qu'une syntaxe et une sémantique améliorées
  • Erreurs de syntaxe ou de sémantique qui entraîneront l'échec des opérations setIamPolicy

Si vous essayez de mettre à jour une stratégie d'autorisation et que vous obtenez une erreur, l'analyse lint peut vous aider à trouver la cause de l'erreur. Vous pouvez également utiliser l'outil lint pour vous assurer qu'une liaison de rôle conditionnelle a l'effet escompté.

Exécuter les fonctions d'analyse lint sur une condition

Les expressions de condition peuvent être complexes, en particulier dans les cas où plusieurs clauses et opérateurs logiques gèrent l'accès de manière appropriée. Si une expression de condition contient une logique non valide ou si la syntaxe ne respecte pas les restrictions d'une expression de condition, vous ne pouvez pas ajouter la condition à une stratégie d'autorisation.

De plus, même si une expression de condition utilise la syntaxe correcte, elle peut contenir des erreurs sémantiques, ce qui peut empêcher vos stratégies d'autorisation et vos liaisons de rôle de fonctionner comme prévu. Les erreurs sémantiques courantes sont les suivantes :

  • Utilisation de fonctions non recommandées
  • Utilisation d'anciens types de ressources ou d'anciens noms de service
  • Conditions inefficaces, telles qu'une date ou une période non applicable

Lorsque vous utilisez les fonctions d'analyse lint pour une condition, l'outil lint inspecte l'expression de condition et signale les erreurs de syntaxe. Il signale également les erreurs sémantiques possibles susceptibles de provoquer des résultats inattendus.

Avant d'essayer de définir une nouvelle liaison de rôle conditionnelle, il est recommandé d'exécuter d'abord les fonctions d'analyse lint sur l'expression. Cette section vous explique comment exécuter les fonctions d'analyse lint sur une expression de condition à l'aide de la console, de Google Cloud CLI ou de l'API REST.

Pour exécuter les fonctions d'analyse lint sur une expression de condition, procédez comme suit :

Console

  1. Dans la console, accédez à la page IAM.

    Accéder à IAM

  2. Cliquez sur Sélectionner un projet, choisissez un projet et cliquez sur Ouvrir.

  3. Dans la liste des comptes principaux, localisez le compte principal souhaité, puis cliquez sur le bouton Modifier.

  4. Dans le panneau Modifier les autorisations, localisez le rôle sur lequel vous souhaitez exécuter les fonctions d'analyse lint. Sous Condition, cliquez sur le nom de la condition.

  5. Dans l'Éditeur de conditions, ajoutez ou modifiez manuellement une expression de condition.

  6. Pour valider la syntaxe CEL, cliquez sur Exécuter l'outil lint.

    Si la syntaxe contient des erreurs, une icône d'erreur  s'affiche à côté de la ligne incorrecte. Pour afficher les détails de chaque erreur, maintenez le pointeur de la souris sur l'icône.

    Si la condition utilise la syntaxe correcte, mais que l'outil lint détecte un problème possible, une icône d'avertissement apparaît à côté de la ligne en cause. Pour afficher les détails de chaque avertissement, maintenez le pointeur de la souris sur l'icône.

  7. Apportez les modifications nécessaires à l'expression de condition. Une fois que vous avez cliqué sur Exécuter l'outil lint, l'outil lint s'exécute automatiquement en arrière-plan pendant que vous modifiez l'expression.

    Vous devez corriger toutes les erreurs avant d'enregistrer l'expression de condition. Nous vous encourageons vivement à corriger aussi tous les avertissements.

  8. En l'absence d'erreurs ou d'avertissements, cliquez sur Enregistrer pour appliquer la condition.

  9. Une fois le panneau Modifier la condition fermé, cliquez à nouveau sur Enregistrer dans le panneau Modifier les autorisations pour mettre à jour votre stratégie d'autorisation.

gcloud

Exécutez la commande gcloud alpha iam policies lint-condition pour exécuter les fonctions d'analyse lint sur une expression de condition donnée. Pour exécuter cette commande, vous pouvez soit créer un fichier texte contenant la condition, soit spécifier des options pour le titre, la description et l'expression de la condition.

L'exemple suivant utilise un fichier texte contenant la condition suivante :

condition.json

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

Commande :

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

Le résultat de la commande contient les éléments suivants :

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

Chacun des résultats de l'analyse lint contient un message debugMessage qui peut être utilisé pour identifier le problème au niveau de l'expression de condition. Si la condition ne peut pas être compilée, vous pouvez voir de nombreux types d'éléments validationUnitNamedebugMessage avec le texte suivant :

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

Apportez les modifications nécessaires pour compiler l'expression, puis exécutez à nouveau l'analyse lint sur l'expression de condition.

REST

La méthode iamPolicies.lintPolicy permet d'exécuter des fonctions d'analyse lint sur une expression de condition dans une stratégie d'autorisation, ou de la valider.

Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

Méthode HTTP et URL :

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

Corps JSON de la requête :

{
  "condition": {
    condition
  }
}

Pour envoyer votre requête, développez l'une des options suivantes :

Le corps de la réponse contient un ou plusieurs objets LintResult, tels que :

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

Chacun des résultats de l'analyse lint contient un message debug_message qui peut être utilisé pour identifier le problème au niveau de l'expression de condition. Si la condition ne peut pas être compilée, vous pouvez voir de nombreux types d'éléments validation_unit_name avec le texte suivant debugMessage :

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

Apportez les modifications nécessaires pour compiler l'expression, puis exécutez à nouveau l'analyse lint sur l'expression de condition.

Unités de validation acceptées

Comme décrit précédemment, une unité de validation est un type d'analyse lint qui évalue l'expression pour rechercher des problèmes de syntaxe. Le tableau ci-dessous récapitule les unités de validation acceptées, chacune avec un niveau d'analyse lint approprié, une gravité des résultats d'analyse lint et une brève description.

Unité de validation Niveau d'analyse lint Gravité Description
ConditionCompileCheck CONDITION ERROR L'expression de condition contient une erreur de compilation due à une syntaxe CEL non valide.
ConditionComplexityCheck CONDITION ERROR L'expression de condition contient plus de 12 opérateurs logiques autorisés.
DateTimeCheck CONDITION WARNING

L'expression de condition spécifie une comparaison d'horodatage qui renvoie toujours la valeur "true" ou "false" en raison de l'un des problèmes suivants :

DateTimeRangeCheck CONDITION WARNING Valeur hors plage pour la fonction d'horodatage avancée prévue et l'expression de comparaison. Consultez les valeurs valides pour des fonctions d'horodatage avancées.
DrgGetAttributeDefaultValueCheck CONDITION ERROR L'expression de condition appelle api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', V), où V est une valeur autre qu'une liste vide, []. Pour cet attribut d'API, V doit toujours être une liste vide.
EffectiveTimeRangeCheck CONDITION WARNING Dans une utilisation plus complexe des fonctions d'horodatage et de comparaison, l'expression donne lieu à une période de validité effective vide et est donc effectivement fausse. Sinon, la plage de dates couvre une plage complète et est donc effectivement vraie.
HasOnlyListConstCheck CONDITION ERROR L'expression de condition appelle hasOnly(List<T>), où le type T n'est pas un type constant, tel qu'une chaîne ou un entier. La fonction hasOnly() n'accepte qu'une liste de constantes.
HasOnlyListLengthCheck CONDITION ERROR L'expression de condition appelle hasOnly(List<T>), et List<T> contient plus des 10 éléments autorisés.
ResourceServiceLiteralCheck CONDITION WARNING La valeur resource.service spécifiée n'est pas acceptée. L'expression utilisant une telle chaîne littérale pour la comparaison d'égalité est effectivement fausse. Utilisez une valeur compatible.
ResourceTypeLiteralCheck CONDITION WARNING La valeur resource.type spécifiée n'est pas acceptée. L'expression utilisant une telle chaîne littérale pour la comparaison d'égalité est effectivement fausse. Utilisez une valeur compatible.
RestrictedAttributesCheck CONDITION WARNING L'expression utilise un attribut limité ou non disponible. La définition de l'expression de condition peut échouer. Consultez la liste des attributs.

Exemples de fonctions d'analyse lint

Cette section fournit des exemples de linting de stratégies d'autorisation pour chaque unité de validation. Chaque exemple illustre l'utilisation de Google Cloud CLI pour exécuter le linting.

ConditionCompileCheck

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse lint :

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

DateTimeCheck

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse lint :

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

HasOnlyListConstCheck

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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

Exemple d'expression de condition :

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

Exécuter la commande :

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

Résultat de l'analyse 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