Criteri di analisi tramite lint

Questo argomento descrive come eseguire il lint o la convalida dei criteri di autorizzazione di Identity and Access Management (IAM).

Prima di iniziare

Ruoli obbligatori

Per eseguire il lint del criterio di autorizzazione di una risorsa, devi avere le autorizzazioni necessarie per recuperarla e per ottenere e impostare il criterio di autorizzazione per la risorsa. Queste autorizzazioni hanno il formato seguente, dove SERVICE è il nome del servizio proprietario della risorsa e RESOURCE_TYPE è il nome del tipo di risorsa per cui vuoi gestire l'accesso:

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

Ad esempio, per eseguire il lint del criterio di autorizzazione di un progetto, devi disporre delle seguenti autorizzazioni:

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

Per ottenere le autorizzazioni richieste, chiedi all'amministratore di concederti un ruolo predefinito o personalizzato che includa le autorizzazioni. Ad esempio, l'amministratore potrebbe concederti il ruolo Amministratore sicurezza (roles/iam.securityAdmin), che include le autorizzazioni per ottenere quasi tutte le risorse Google Cloud e gestire i relativi criteri di autorizzazione.

Informazioni sull'analisi tramite lint per i criteri di autorizzazione

Nel contesto dei criteri di autorizzazione, l'analisi tramite lint è un metodo per esaminare un criterio di autorizzazione nuovo o esistente e per verificare la presenza di problemi specifici. Questi problemi includono le seguenti possibilità:

  • Suggerimenti
  • Avvisi
  • Informazioni che possono contribuire a migliorare l'intento del criterio di autorizzazione, ad esempio una migliore sintassi e una semantica
  • Errori di sintassi o semantici che causano la mancata riuscita delle operazioni setIamPolicy

Se provi ad aggiornare un criterio di autorizzazione e ricevi un errore, l'analisi del criterio di autorizzazione tramite lint può aiutarti a trovare la causa dell'errore. Puoi anche usare il linter per assicurarti che l'associazione di ruoli condizionale abbia l'effetto previsto.

Linting di una condizione

Le espressioni di condizione possono essere complesse, soprattutto in scenari che richiedono più clausole e operatori logici per gestire in modo appropriato l'accesso. Se un'espressione di condizione contiene una logica non valida o se la sintassi viola le restrizioni di un'espressione di condizione, non puoi aggiungere la condizione a un criterio di autorizzazione.

Inoltre, anche se un'espressione di condizione utilizza la sintassi corretta, potrebbe contenere errori semantici, che possono impedire il corretto funzionamento dei criteri di autorizzazione e delle associazioni di ruoli. Gli errori semantici più comuni sono:

  • Utilizzo di funzioni non consigliate
  • Utilizzo di tipi di risorse o nomi di servizi legacy
  • Condizioni inefficaci, ad esempio una data o un intervallo di tempo non applicabili

Quando esegui il lint di una condizione, il linter controlla l'espressione della condizione e segnala eventuali errori di sintassi. Segnala anche possibili errori semantici che potrebbero causare risultati imprevisti.

Prima di tentare di impostare una nuova associazione di ruolo condizionale, ti consigliamo di eseguire il lint dell'espressione. Questa sezione mostra come eseguire il lint di un'espressione della condizione utilizzando la console Google Cloud, Google Cloud CLI o l'API REST.

Per eseguire il lint di un'espressione della condizione:

Console

  1. Nella console Google Cloud, vai alla pagina IAM.

    Vai a IAM

  2. Fai clic su Seleziona un progetto, scegli un progetto e fai clic su Apri.

  3. Nell'elenco delle entità, individua quella che ti interessa e fai clic sul pulsante Modifica.

  4. Nel riquadro Modifica autorizzazioni, individua il ruolo che vuoi collegare. In Condizione IAM (facoltativa), fai clic sul nome della condizione.

  5. Nell'Editor condizioni, aggiungi o modifica manualmente un'espressione della condizione.

  6. Per convalidare la sintassi CEL, fai clic su Esegui Linter.

    Se la sintassi contiene errori, accanto alla riga errata viene visualizzata l'icona Errore. Per visualizzare i dettagli di ogni errore, tieni premuto il puntatore sull'icona.

    Se la condizione utilizza la sintassi corretta, ma il linter rileva un possibile problema, accanto alla riga che indica il problema viene visualizzata un'icona di avviso . Per visualizzare i dettagli di ciascun avviso, tieni premuto il puntatore sull'icona.

  7. Apporta le modifiche necessarie all'espressione della condizione. Dopo aver fatto clic su Esegui Linter, il linter viene eseguito automaticamente in background mentre modifichi l'espressione.

    Devi correggere tutti gli errori prima di salvare l'espressione della condizione. Ti consigliamo vivamente di correggere anche tutti gli avvisi.

  8. Se non sono presenti errori o avvisi, fai clic su Salva per applicare la condizione.

  9. Dopo aver chiuso il riquadro Modifica condizione, fai di nuovo clic su Salva nel riquadro Modifica autorizzazioni per aggiornare il criterio di autorizzazione.

gcloud

Esegui il comando gcloud alpha iam policies lint-condition per eseguire il lint di una determinata espressione della condizione. Per eseguire questo comando, puoi creare un file di testo contenente la condizione o specificare i flag per il titolo, la descrizione e l'espressione della condizione.

L'esempio seguente utilizza un file di testo contenente la seguente condizione:

condition.json

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

Esegui comando:

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

L'output del comando contiene quanto segue:

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

Ciascuno dei risultati lint contiene un elemento debugMessage che può essere utilizzato per individuare il problema con l'espressione della condizione. Se la compilazione della condizione non è riuscita, potresti vedere molti tipi diversi di validationUnitName con il seguente testo debugMessage:

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

Apporta modifiche in modo che l'espressione venga compilata, quindi esegui di nuovo lint della condizione.

REST

Il metodo iamPolicies.lintPolicy inserisce o convalida un'espressione di condizione in un criterio di autorizzazione.

Prima di utilizzare i dati della richiesta, effettua le seguenti sostituzioni:

  • condition: un oggetto Expr che rappresenta la condizione di lint. Ad esempio:

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

    Per scoprire di più sul formato di un oggetto Expr, consulta il riferimento sullo schema Expr.

Metodo HTTP e URL:

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

Corpo JSON della richiesta:

{
  "condition": {
    condition
  }
}

Per inviare la richiesta, espandi una di queste opzioni:

Il corpo della risposta contiene uno o più oggetti LintResult, come:

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

Ciascuno dei risultati lint contiene un elemento debug_message che può essere utilizzato per individuare il problema con l'espressione della condizione. Se la compilazione della condizione non è riuscita, potresti vedere molti tipi diversi di validation_unit_name con il seguente testo debugMessage:

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

Apporta modifiche in modo che l'espressione venga compilata, quindi esegui di nuovo lint della condizione.

Unità di convalida supportate

Come descritto in precedenza, un'unità di convalida è un singolo tipo di lint che valuta l'espressione per problemi sintattici. La tabella riportata di seguito riassume le unità di convalida supportate, ciascuna con il livello di analisi tramite lint previsto, la gravità dei risultati dell'analisi tramite lint e una breve descrizione.

Unità di convalida Livello di lanugine Gravità Descrizione
ConditionCompileCheck CONDITION ERROR L'espressione della condizione contiene un errore di compilazione a causa di una sintassi CEL non valida.
ConditionComplexityCheck CONDITION ERROR L'espressione della condizione contiene più del numero massimo di 12 operatori logici.
DateTimeCheck CONDITION WARNING

L'espressione della condizione specifica un confronto di timestamp che restituisce sempre il valore true o false, a causa di uno dei seguenti problemi:

DateTimeRangeCheck CONDITION WARNING Il valore non rientra nell'intervallo per la funzione timestamp avanzata desiderata e l'espressione di confronto. Consulta i valori validi per le funzioni di timestamp avanzate.
DrgGetAttributeDefaultValueCheck CONDITION ERROR L'espressione della condizione chiama api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', V), dove V è qualsiasi valore diverso da un elenco vuoto, []. Per questo attributo API, V deve essere sempre un elenco vuoto.
EffectiveTimeRangeCheck CONDITION WARNING In un uso più complesso delle funzioni di timestamp e del confronto, l'espressione genera un intervallo di tempo effettivo vuoto, pertanto è di fatto false. In alternativa, l'intervallo di tempo copre un intervallo intero e, di conseguenza, è vero.
HasOnlyListConstCheck CONDITION ERROR L'espressione della condizione chiama hasOnly(List<T>), dove il tipo T non è un tipo costante, ad esempio una stringa o un numero intero. La funzione hasOnly() accetta solo un elenco di costanti.
HasOnlyListLengthCheck CONDITION ERROR L'espressione della condizione chiama hasOnly(List<T>), mentre List<T> contiene più di 10 elementi consentiti.
ResourceServiceLiteralCheck CONDITION WARNING Il valore resource.service specificato non è supportato. L'espressione che utilizza questo valore letterale stringa per il confronto di uguaglianza è effettivamente falsa. Utilizza un valore supportato.
ResourceTypeLiteralCheck CONDITION WARNING Il valore resource.type specificato non è supportato. L'espressione che utilizza questo valore letterale stringa per il confronto di uguaglianza è effettivamente falsa. Utilizza un valore supportato.
RestrictedAttributesCheck CONDITION WARNING L'espressione utilizza un attributo limitato o non supportato. L'impostazione dell'espressione della condizione potrebbe non riuscire. Consulta l'elenco degli attributi.

Esempi di linting

Questa sezione mostra esempi di condizioni che causano la segnalazione di problemi da parte di ogni unità di convalida. Ogni esempio mostra l'analisi tramite lint utilizzando Google Cloud CLI.

Nessun problema di convalida

Esempio di condizione:

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

Esegui comando:

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

Risultato lint:

{}

ConditionCompileCheck

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato lint:

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

DateTimeCheck

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato lint:

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

HasOnlyListConstCheck

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato 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

Esempio di condizione:

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

Esegui comando:

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

Risultato 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