Ejecutar lint en políticas

En este tema se describe cómo lint o validar tus políticas de permisos de gestión de identidades y accesos (IAM).

Antes de empezar

Roles obligatorios

Para analizar la política de permisos de un recurso, necesitas permisos para obtener el recurso y para obtener y definir la política de permisos del recurso. Estos permisos tienen el siguiente formato, donde SERVICE es el nombre del servicio propietario del recurso y RESOURCE_TYPE es el nombre del tipo de recurso al que quieres gestionar el acceso:

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

Por ejemplo, para analizar la política de permisos de un proyecto, necesitas los siguientes permisos:

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

Para obtener los permisos necesarios, pide a tu administrador que te asigne un rol predefinido o personalizado que incluya los permisos. Por ejemplo, tu administrador podría asignarte el rol Administrador de seguridad (roles/iam.securityAdmin), que incluye permisos para obtener casi todos losGoogle Cloud recursos y gestionar sus políticas de permisos.

Información sobre el análisis de código de las políticas de permisos

En el contexto de las políticas de permiso, el análisis de lint es un método para examinar una política de permiso nueva o ya creada y comprobar si tiene problemas específicos. Estos problemas incluyen las siguientes posibilidades:

  • Sugerencias
  • Advertencias
  • Información que puede ayudar a mejorar la intención de la política de permitir, como una sintaxis y una semántica mejores
  • Errores de sintaxis o semánticos que provocan que las operaciones de setIamPolicy fallen

Si intentas actualizar una política de permiso y se produce un error, puedes usar el análisis de lint para encontrar la causa del error. También puedes usar el linter para asegurarte de que un enlace de rol condicional tenga el efecto deseado.

Ejecutar lint en una condición

Las expresiones de condición pueden ser complejas, sobre todo en situaciones que requieren varias cláusulas y operadores lógicos para gestionar el acceso de forma adecuada. Si una expresión de condición contiene una lógica no válida o si la sintaxis infringe las restricciones de una expresión de condición, no podrá añadir la condición a una política de permiso.

Además, aunque una expresión de condición use la sintaxis correcta, puede contener errores semánticos, lo que puede impedir que tus políticas de permiso y vinculaciones de roles funcionen como esperas. Entre los errores semánticos habituales se incluyen los siguientes:

  • Uso de funciones no recomendadas
  • Uso de tipos de recursos o nombres de servicios antiguos
  • Condiciones ineficaces, como un intervalo de fechas u horas no aplicable

Cuando analizas una condición, el linter inspecciona la expresión de la condición e informa de cualquier error de sintaxis. También informa de posibles errores semánticos que podrían provocar resultados inesperados.

Antes de intentar definir un nuevo enlace de rol condicional, te recomendamos que valides la expresión. En esta sección se muestra cómo analizar una expresión de condición mediante la Google Cloud consola, la CLI de Google Cloud o la API REST.

Para analizar una expresión condicional, sigue estos pasos:

Consola

  1. En la consola, ve a la página Gestión de identidades y accesos. Google Cloud

    Ir a IAM

  2. Haz clic en Seleccionar un proyecto, elige un proyecto y haz clic en Abrir.

  3. En la lista de principales, busca el principal que quieras y haz clic en el botón Editar.

  4. En el panel Editar permisos, busca el rol que quieras analizar. A continuación, en Condición de IAM (opcional), haz clic en el nombre de la condición.

  5. En el editor de condiciones, añade o edita manualmente una expresión de condición.

  6. Para validar la sintaxis de CEL, haz clic en Ejecutar Linter.

    Si la sintaxis contiene errores, aparecerá un icono de Error junto a la línea incorrecta. Para ver los detalles de cada error, coloca el puntero sobre el icono.

    Si la condición usa la sintaxis correcta, pero el linter encuentra un posible problema, aparecerá un icono de Advertencia junto a la línea con el problema. Para ver los detalles de cada advertencia, mantén el puntero sobre el icono.

  7. Haz los cambios necesarios en la expresión de la condición. Después de hacer clic en Ejecutar linter, el linter se ejecuta automáticamente en segundo plano mientras editas la expresión.

    Debe corregir todos los errores antes de guardar la expresión de condición. Te recomendamos encarecidamente que corrijas todas las advertencias.

  8. Si no hay errores ni advertencias, haz clic en Guardar para aplicar la condición.

  9. Cuando se cierre el panel Editar condición, vuelve a hacer clic en Guardar en el panel Editar permisos para actualizar tu política de permitir.

gcloud

Ejecuta el comando gcloud alpha iam policies lint-condition para analizar una expresión de condición determinada. Para ejecutar este comando, puedes crear un archivo de texto que contenga la condición o especificar marcas para el título, la descripción y la expresión de la condición.

En el siguiente ejemplo se usa un archivo de texto que contiene la siguiente condición:

condition.json

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

Ejecuta el comando:

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

La salida del comando contiene lo siguiente:

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 uno de los resultados de lint contiene un debugMessage que se puede usar para ayudar a localizar el problema con la expresión de la condición. Si no se ha podido compilar la condición, es posible que veas muchos tipos de validationUnitName con el siguiente texto debugMessage:

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

Haz los cambios necesarios para que la expresión se compile y, a continuación, vuelve a analizar la condición.

REST

El método iamPolicies.lintPolicy valida una expresión de condición en una política de permiso.

Antes de usar los datos de la solicitud, haz las siguientes sustituciones:

  • condition: un objeto Expr que representa la condición de lint. Por ejemplo:

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

    Para obtener información sobre el formato de un objeto Expr, consulta la referencia del esquema Expr.

Método HTTP y URL:

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

Cuerpo JSON de la solicitud:

{
  "condition": {
    condition
  }
}

Para enviar tu solicitud, despliega una de estas opciones:

El cuerpo de la respuesta contiene uno o varios objetos LintResult, como los siguientes:

{
  "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 uno de los resultados de lint contiene un debug_message que se puede usar para ayudar a localizar el problema con la expresión de la condición. Si no se ha podido compilar la condición, es posible que veas muchos tipos de validation_unit_name con el siguiente texto debugMessage:

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

Haz los cambios necesarios para que la expresión se compile y, a continuación, vuelve a analizar la condición.

Unidades de validación admitidas

Como se ha descrito anteriormente, una unidad de validación es un tipo de lint individual que evalúa la expresión para detectar problemas sintácticos. En la siguiente tabla se resumen las unidades de validación admitidas, cada una con el nivel de linting previsto, la gravedad del resultado del linting y una breve descripción.

Unidad de validación Nivel de pelusa Gravedad Descripción
ConditionCompileCheck CONDITION ERROR La expresión de condición contiene un error de compilación debido a una sintaxis de CEL no válida.
ConditionComplexityCheck CONDITION ERROR La expresión condicional contiene más de 12 operadores lógicos, que es el máximo permitido.
DateTimeCheck CONDITION WARNING

La expresión de condición especifica una comparación de marcas de tiempo que siempre se evalúa como verdadera o falsa debido a uno de estos problemas:

DateTimeRangeCheck CONDITION WARNING Valor fuera del intervalo de la función de marca de tiempo avanzada y de la expresión de comparación. Consulta los valores válidos de las funciones de marca de tiempo avanzadas.
DrgGetAttributeDefaultValueCheck CONDITION ERROR La expresión de condición llama a api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', V), donde V es cualquier valor que no sea una lista vacía, []. En el caso de este atributo de la API, V siempre debe ser una lista vacía.
EffectiveTimeRangeCheck CONDITION WARNING En un uso más complejo de las funciones de marca de tiempo y de comparación, la expresión da como resultado un intervalo de tiempo efectivo vacío y, por lo tanto, es efectivamente falsa. De lo contrario, el intervalo de tiempo abarca todo el intervalo, por lo que es efectivamente verdadero.
HasOnlyListConstCheck CONDITION ERROR La expresión de condición llama a hasOnly(List<T>), donde el tipo T no es un tipo constante, como una cadena o un número entero. La función hasOnly() solo acepta una lista de constantes.
HasOnlyListLengthCheck CONDITION ERROR La expresión de la condición llama a hasOnly(List<T>) y List<T> contiene más del máximo de 10 elementos.
ResourceServiceLiteralCheck CONDITION WARNING No se admite el valor resource.service especificado. La expresión que usa este literal de cadena para la comparación de igualdad es efectivamente falsa. Usa un valor admitido.
ResourceTypeLiteralCheck CONDITION WARNING No se admite el valor resource.type especificado. La expresión que usa este literal de cadena para la comparación de igualdad es efectivamente falsa. Usa un valor admitido.
RestrictedAttributesCheck CONDITION WARNING La expresión usa un atributo restringido o no admitido. Es posible que no se pueda definir la expresión de la condición. Consulta la lista de atributos.

Ejemplos de linting

En esta sección se muestran ejemplos de condiciones que provocan que cada unidad de validación informe de problemas. En cada ejemplo se muestra cómo se realiza el análisis de lint usando la CLI de Google Cloud.

No hay problemas de validación

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de Lint:

{}

ConditionCompileCheck

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de Lint:

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

DateTimeCheck

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de Lint:

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

HasOnlyListConstCheck

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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

Condición de ejemplo:

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

Ejecuta el comando:

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

Resultado de 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