Rego 101: Introducción a Rego
2 de noviembre de 2023
0 minutos de lecturaEsta serie de publicaciones del blog ofrece una introducción sencilla a Rego, el lenguaje de políticas de los creadores del motor Open Policy Agent (OPA). Si estás empezando y quieres aprender a escribir políticas como código en Rego, estás en el lugar indicado.
En esta serie de tres partes, veremos lo siguiente:
Parte 1 (¡esta!): Conceptos básicos de Rego y cómo empezar a usar OPA
Parte 2: Sintaxis intermedia de Rego
Parte 3: Tipos de valores y reglas
¿Qué son Rego y OPA?
Rego es un lenguaje declarativo de consultas creado por los desarrolladores del framework Open Policy Agent (OPA). La Cloud Native Computing Foundation (CNCF) aceptó OPA como proyecto alojado en etapa de incubación en abril de 2019, y OPA se graduó del estado de incubación en 2021.
Rego se usa para escribir políticas como código, lo que aplica prácticas de programación, como el control de versiones y el diseño modular, a la evaluación de recursos de la nube y de infraestructura como código (IaC).
OPA es el motor que evalúa las políticas como código escritas en Rego. «Desacopla la toma de decisiones sobre políticas de su aplicación», lo que significa que determina si un recurso cumple con las políticas para que no tengas que codificar esas comprobaciones directamente en el código de tu aplicación.
Al separar las políticas de tu software y delegar las comprobaciones en OPA, agregas velocidad y flexibilidad al ciclo de desarrollo. Puedes actualizar las políticas en cualquier momento sin tener que volver a compilar tu aplicación ni volver a implementar tu servicio. Esto te permite crear a escala, tener más visibilidad de tu nivel de cumplimiento y aplicar políticas de forma programática. Introducir políticas como código también tiene la ventaja de trasladar el desarrollo de la nube y de IaC «a la izquierda», es decir, incorporarlas antes en el ciclo de vida.
En Snyk, las reglas integradas y personalizadas de Snyk IaC+ están escritas en Rego y, detrás de escena, Snyk usa el motor OPA para evaluar las políticas de Rego y tomar decisiones. De hecho, ¡Snyk ha realizado más de mil millones de evaluaciones de reglas de seguridad con OPA!
¿Cómo funciona Rego?
En un lenguaje declarativo de consultas como Rego, describes los datos que quieres obtener y el programa busca una coincidencia en una fuente de datos, conocida como la entrada. Esto es distinto de los lenguajes imperativos tradicionales, en los que describes los pasos que deben seguirse para obtener un resultado. Quizás ya conozcas algunos lenguajes declarativos de consultas: SQL es probablemente el más usado.
Con Rego, describes las condiciones para aprobar o rechazar una política, y OPA busca en un documento de entrada JSON (o YAML) datos que coincidan con esas condiciones.
La idea suena genial, pero ¿cómo es una regla? Supongamos que debemos aplicar una política corporativa según la cual solo Alice, una administradora de redes, debe tener permiso para crear y eliminar redes virtuales en el entorno de producción. Esta es una regla de ejemplo que podríamos escribir:
Volveremos a esta regla en un momento para explicar qué hace y cómo funciona. Por ahora, ¡admira su elegante sencillez!
Entrada
OPA puede procesar cualquier documento JSON o YAML como entrada. ¿Notaste que usamos input.user en la regla de ejemplo anterior? input se trata como un documento JSON especial al que se puede acceder globalmente, lo que significa que puedes hacer referencia a él desde cualquier parte del archivo de políticas de Rego.
Este es un documento de entrada de ejemplo para la regla de la sección anterior:
Supongamos que este documento representa al usuario que inició sesión. En el mundo real, este documento de entrada podría ser un manifiesto de Kubernetes o el resultado de un plan de Terraform. Te mostraremos un ejemplo en una próxima publicación del blog.
Reglas
Ahora que viste cómo es una entrada, profundicemos en el concepto de las reglas. En el lenguaje Rego, una regla es una asignación condicional. Cada regla tiene dos partes:
El encabezado consta de una variable y un valor que se le puede asignar.
El cuerpo consta de una o más consultas que le indican a OPA qué condición o condiciones deben cumplirse para asignar el valor a la variable.
Puedes leer una regla así:
En resumen, una regla consulta la entrada para encontrar una coincidencia con una condición y, si la encuentra, asigna un valor a una variable.
Esta es la regla de ejemplo que usamos antes:
En el ejemplo anterior, el encabezado (variable y valor) es allow := true y el cuerpo (consulta) es input.user == "alice". Al combinar el encabezado y el cuerpo, obtienes una regla completa, que se puede leer así:
La variable allow tiene el valor true SI user es igual a "alice".
Ten en cuenta que en Rego, := es el operador de asignación, a veces llamado operador morsa. Simplemente asigna un valor a una variable, de forma muy similar al signo igual en otros lenguajes.
Consultas
Profundicemos en el concepto de las consultas. Como dijimos antes, una consulta representa una condición que se debe comprobar: básicamente, es la primera parte de una instrucción SI.
Por ejemplo, esta es la consulta de la regla de ejemplo de la sección anterior:
Esta línea le indica a OPA que consulte el documento input para averiguar SI user es igual a "alice".
Hay un matiz: Rego es declarativo, así que técnicamente una consulta simplemente afirma «Esto es así», y OPA encuentra todos los valores de la entrada que hacen verdadera esa afirmación. En este ejemplo, la consulta dice: «La propiedad user tiene el valor alice». La tarea de OPA es examinar la propiedad user y encontrar todos los usuarios de la entrada que hacen verdadera esa afirmación, si los hay (en este caso, busca al usuario alice).
Cómo hacer referencia a la entrada en una consulta
Al crear una consulta de Rego, usas la notación de puntos para llegar a la propiedad que buscas; es decir, cada nivel anidado del documento de entrada se separa con un punto. Primero, empiezas con input y luego agregas un punto y el nombre de la propiedad del nivel superior (en este caso, input.user).
Para hacer referencia a una propiedad anidada, debes especificar todos los niveles por los que pasas hasta llegar a ella. Empieza con input, un punto y la propiedad del nivel superior (input.your-property-here); luego sigue agregando puntos y nombres de propiedades hasta llegar a la propiedad anidada que quieres consultar. Si la propiedad que quieres consultar es una matriz, espera un momento: lo veremos enseguida.
Supongamos que el documento de entrada se ve así:
Como user está anidada dentro de admins, que a su vez está anidada dentro de input, harías referencia a ella así:
Por otro lado, si la propiedad de entrada a la que haces referencia es una matriz (lista), usarás el operador comodín, un guion bajo, para especificar la propiedad. Por ejemplo, supongamos que la entrada incluye una matriz de user:
En este caso, si quieres averiguar si alice está en la matriz users, usarías esta sintaxis:
Aquí, el operador comodín le indica a OPA que itere por la matriz y compruebe si alguno de sus elementos es igual a alice. En una próxima publicación del blog profundizaremos en la iteración.
Del mismo modo, supongamos que quieres comprobar si el valor de la propiedad admin es true en alguno de los elementos de la matriz users que aparece a continuación (aunque solo se muestre un elemento):
Usarías una sintaxis como esta:
Por supuesto, las condiciones SI no son muy útiles si no van acompañadas de una acción condicional. Aquí es donde resulta útil entender cómo funcionan las asignaciones en Rego: la segunda parte de la instrucción SI.
Evaluación de reglas
La acción condicional de una regla consiste en asignar una variable. En nuestro ejemplo, buscamos en la entrada para averiguar si se debe asignar el valor true a la variable allow. Puedes leerlo así:
¿Qué son las variables?
Una variable es una referencia a un valor específico. Aquí, se asigna el valor 1 a la variable x:
Después puedes usar la variable en lugar del valor, y para Rego es lo mismo:
Volviendo a nuestro ejemplo, la variable es allow y el valor que se le asignará es true:
Si lo combinas con la condición (consulta) que vimos antes, obtienes la regla completa:
En resumen, leerías esta regla así:
La regla allow tiene el valor true SI input.user es igual a "alice".
En la práctica, este tipo de regla es muy común, así que Rego permite abreviarla de la siguiente manera:
Evaluar la regla con OPA
Ya tenemos una regla y un documento de entrada. El siguiente paso es usar OPA para evaluar la entrada con respecto a la regla. Comprobemos si nuestra entrada cumple con la política y si el usuario que inició sesión tiene permiso para crear y eliminar redes virtuales en el entorno de producción.
Nos centraremos en dos formas de interactuar con OPA:
Usar Rego Playground
Usar la herramienta de línea de comandos de OPA
Usar Rego Playground
La forma más fácil de empezar a escribir reglas es usar Rego Playground de OPA. Es una herramienta interactiva que te permite escribir, probar y compartir reglas y entradas.
Estos son los conceptos básicos:
Para editar una regla, usa el campo de texto de reglas que está a la izquierda de la página.
Para editar la entrada, usa el campo Input, en la parte superior derecha de la página. (Ten en cuenta que debe ser JSON válido).
Para evaluar una regla, selecciona el botón Evaluate que está arriba de la entrada.
Para ver los resultados de la evaluación, revisa el campo Output, en la parte inferior derecha.
Para compartir una regla con otras personas, selecciona el botón Publish, en la parte superior derecha. OPA genera una URL que puedes compartir con cualquier persona para que pruebe o modifique tu regla y tu entrada.
¡Experimenta todo lo que quieras y no tengas miedo de ensuciarte las manos! No vas a romper nada: el compilador te avisará si el código de Rego no es válido. Vuelve a cargar la página si quieres restablecer el estado original de Playground (o su estado publicado si estás viendo una versión publicada de Playground).
Compartimos un Playground con la regla allow y el documento de entrada de ejemplo. Puedes acceder desde esta URL: https://play.openpolicyagent.org/p/SH5ApmfodX
También puedes abrir un Playground nuevo y pegar la regla en el cuadro de texto de la izquierda:
Y pegar la entrada en el cuadro de texto de la parte superior derecha:
Recuerda que nuestra política corporativa establece que solo Alice, una administradora de redes, debe tener permiso para crear y eliminar redes virtuales en el entorno de producción. El documento de entrada representa al usuario que inició sesión. Nuestra regla comprueba si el usuario del documento de entrada es alice y, de ser así, allow se evalúa como true.
Haz clic en el botón Evaluate. Verás este resultado:
Esto significa que allow efectivamente se evalúa como true. OPA determinó que el documento de entrada cumple con nuestra política corporativa. El usuario es Alice, lo que significa que tiene permiso para crear y eliminar redes virtuales en el entorno de producción.
Usar la herramienta de línea de comandos de OPA
Otra forma de evaluar reglas con OPA es usar la herramienta de línea de comandos opa. Encontrarás instrucciones para instalar opa en la documentación de OPA. Una vez instalada, necesitarás dos cosas:
Un archivo de políticas
.regoque contenga tu regla, junto con una declaración de paquete, comopackage rules.check_user, al principio del archivo. Llamamoscheck_user.regoa nuestro archivo de políticas.Un archivo
.jsonque contenga la entrada; llamamosinput.jsona nuestro archivo de entrada.
Una vez que tengas esas dos cosas, puedes usar el comando opa eval para evaluar tu política como código:
Por supuesto, puedes ponerles el nombre que quieras a tus archivos; solo asegúrate de que el comando siga esta estructura:
Si allow se evalúa como true, como sucede en nuestro ejemplo, verás el mismo resultado que viste en Rego Playground:
Una vez más, OPA indica que la entrada es coherente con —cumple con— la política de nuestra empresa. Esto significa que el usuario que inició sesión tiene permiso para crear y eliminar redes virtuales en la cuenta de producción.
Probar una entrada que no cumple con la política
¿Qué aspecto tiene un documento de entrada que no cumple con la política? En el playground o en tu archivo local .rego, cambia la entrada por lo siguiente:
Ahora, cuando evalúes la regla (al hacer clic en Evaluate en Rego Playground o al ejecutar el comando opa eval mencionado anteriormente), verás el siguiente resultado:
¿Qué significa? En este ejemplo, OPA devuelve un resultado "undefined" (es decir, un conjunto vacío) porque no encuentra en la entrada un valor que coincida con la condición input.user == "alice". El conjunto está vacío porque no hay resultados. Por lo tanto, allow no se evalúa como true y el documento de entrada no cumple con la política de la empresa. ¡Lo sentimos, Bob!
¿Qué sigue?
Vuelve a nuestro blog para leer el resto de la serie de contenido Rego para principiantes, donde exploraremos la sintaxis intermedia de las reglas de Rego, incluidas las estructuras AND y OR, los mensajes personalizados, las palabras clave especiales y más.
Mientras tanto, aquí tienes algunos recursos útiles:
Si te interesa usar Rego para escribir reglas personalizadas para Snyk IaC, consulta nuestra documentación. Además de los conjuntos de reglas de seguridad y cumplimiento integrados de Snyk, las reglas personalizadas de IaC+ te permiten establecer controles de seguridad personalizados en todo tu SDLC.
IaC+ te ofrece una vista única y controles para tus problemas de configuración, desde el código hasta la nube, con una interfaz de usuario para problemas, un conjunto de reglas y un motor de políticas que abarcan IDE, SCM, CLI, CI/CD, Terraform Cloud y entornos de nube implementados, como AWS, Azure y Google Cloud.
Seguridad de IaC diseñada para desarrolladores
Snyk protege tu infraestructura como código desde el ciclo de vida del desarrollo de software hasta el runtime en la nube con un motor unificado de políticas como código, para que todos los equipos puedan desarrollar, implementar y operar de forma segura.



