SPDL: Lenguaje de definición de políticas Speedle

Conceptos básicos de SPDL

SPDL es el lenguaje para escribir políticas y políticas de roles de Speedle. Esta página cubre la sintaxis, las reglas de nombres y los ejemplos.

Sintaxis

Sintaxis básica de definición de políticas

Palabras clave

grant, deny, user, group, entity, role, from, on, if e in tienen un significado especial en su posición sintáctica. Las palabras clave de las sentencias no distinguen mayúsculas. En las condiciones, use in o IN; los nombres de función distinguen mayúsculas. Los nombres de principal, acción y recurso también distinguen mayúsculas. El analizador actual acepta nombres parecidos a palabras clave en algunas posiciones de nombre, así que una prohibición general no es una regla de validación. Prefiera nombres inequívocos para la revisión y la interoperabilidad de los clientes.

Convención de nombres

Prefiera identificadores simples y estables. Escriba entre comillas los nombres con espacios en blanco o separadores, usando la forma de comillas simples o dobles del analizador, y pruebe la entrada real. Las clases de caracteres históricas de las expresiones regulares de Java no son un contrato de validación del analizador de Go. El prefijo de recurso expr: usa expresiones regulares de Go, no globs del shell. Los nombres de atributos y de funciones en las condiciones se describen más abajo.

Sintaxis

POLICY = EFFECT SUBJECT ACTION RESOURCE [if CONDITION]
EFFECT = grant | deny
SUBJECT = AND_PRINCIPALS (, AND_PRINCIPALS)*
AND_PRINCIPALS = PRINCIPAL | \( PRINCIPAL_LIST \)
PRINCIPAL_LIST = PRINCIPAL (, PRINCIPAL)*
PRINCIPAL = PRINCIPAL_TYPE PRINCIPAL_NAME [PRINCIPAL_IDD]
PRINCIPAL_TYPE = user|group|entity|role
PRINCIPAL_IDD = from IDD_IDENTIFIER
IDD_IDENTIFIER = NAME
ACTION = (ACTION_IDENTIFIER)(, ACTION_IDENTIFIER)*
RESOURCE = RESOURCE_IDENTIFIER
PRINCIPAL_NAME = NAME
ACTION_IDENTIFIER = NAME
RESOURCE_IDENTIFIER = NAME
ROLE_POLICY = EFFECT SUBJECT ROLE (on RESOURCE)? [if CONDITION]
EFFECT = grant | deny
SUBJECT = PRINCIPAL (, PRINCIPAL)*
PRINCIPAL = PRINCIPAL_TYPE PRINCIPAL_NAME [PRINCIPAL_IDD]
PRINCIPAL_TYPE = user|group|entity|role
PRINCIPAL_IDD = from IDD_IDENTIFIER
IDD_IDENTIFIER = NAME
ROLE = (role)? SUBJECT_IDENTIFIER
RESOURCE = RESOURCE_IDENTIFIER
SUBJECT_IDENTIFIER = NAME
RESOURCE_IDENTIFIER = NAME

Ejemplos

Herencia de roles: el sujeto de una política de roles puede ser otro rol, así que manager también tiene cada rol asignado a employee.

grant role manager employee

La denegación prevalece sobre la concesión: una denegación aplicable gana a una concesión. Aquí carol está en staff y aun así se le deniega delete sobre journal.

grant group staff read,delete journal
deny user carol delete journal

Una condición: la política se aplica solo cuando la condición es verdadera.

grant user bob read report if department == 'finance'

Son sentencias SPDL, no un servicio de ejemplo completo; consulte Gestión de políticas para los servicios, los roles con ámbito de recurso y ejemplos completos de decisión.

Condición

1. Descripción general

La condición se admite en las definiciones de políticas y de políticas de roles. La política o la política de roles surte efecto solo cuando se cumple la condición.

El punto de aplicación de políticas (PEP) debe aportar cada atributo personalizado que referencien las políticas; los atributos integrados como request_user y request_time los proporciona ADS. Los atributos que aporta el PEP proceden de la aplicación o el servicio de confianza del llamador, no de los usuarios finales, y el PEP responde de los valores que envía. Los atributos aportados por el PEP tienen prioridad sobre los atributos integrados del mismo nombre; en particular, no reenvíe nunca entrada no confiable del usuario final como request_user, request_time ni ningún otro nombre de atributo integrado.

Una condición que referencia un atributo ausente en la solicitud no coincide. Por tanto, un deny condicional no se aplica cuando falta su atributo. Asegúrese de que el PEP aporta siempre los atributos que usan las condiciones de denegación, y pruebe esas solicitudes.

Este documento se centra en qué es una condición y en cómo escribirla.

2. Condición

Una condición es una expresión booleana que se construye con atributos, funciones, constantes, operadores, comparadores o paréntesis y produce un valor booleano.

2.1 Tipos de datos

El tipo de dato de un valor de atributo y de una constante puede ser string, numeric, bool, datetime o un array de string, numeric, bool o datetime.
Los tipos de datos y los operadores y comparadores admitidos se listan en la tabla siguiente.

Tipo de dato Operadores Comparadores Comentario
string + ==
!=
=~
>
>=
<
<=
’+’ concatena cadenas
‘=~’ compara con una expresión regular; vea la nota bajo la tabla.
numeric +
-
*
/
%
==
!=
>
>=
<
<=
bool &&
||
!
==
!=
datetime ==
!=
>
>=
<
<=
array in operador de pertenencia ‘in’: el lado izquierdo debe ser un tipo simple (string, numeric, bool, datetime) y el lado derecho un array

La mayoría de los comparadores se explican solos; esta es la nota de "=~":
"=~" es el comparador de expresiones regulares. Usa el dialecto regexp estándar de Go. El lado izquierdo es la cadena candidata; el lado derecho es el patrón. "=~" indica si la cadena candidata coincide con el patrón de la derecha.

  • Lado izquierdo: string
  • Lado derecho: string
  • Devuelve: bool

2.2 Atributos

Un atributo en una condición representa una variable. El valor se determina en tiempo de ejecución y se obtiene del entorno del Servicio de Decisiones de Autorización (ADS) o del PEP. Los atributos integrados son los valores que rellena el entorno de ADS. Los atributos del cliente son los valores que aporta el PEP —la aplicación o el servicio de confianza del llamador— al pedir una decisión de autorización a ADS, no los usuarios finales. El PEP responde de los valores que envía. Los atributos aportados por el PEP tienen prioridad sobre los atributos integrados del mismo nombre, así que un PEP no debe reenviar entrada no confiable del usuario final con el nombre de un atributo integrado.

2.2.1 Atributos integrados

Los atributos integrados son los siguientes:

Nombre del atributo integrado Tipo de dato Valor de ejemplo Definición
request_user string "Alice" La información de usuario del sujeto que solicita actuar sobre un recurso
request_groups []string []string{"managers"} La información de grupos del sujeto que solicita actuar sobre un recurso
request_entity string "/org1/service1" El nombre de servicio u otra información de entidad del sujeto con el que el servicio o el programa solicita actuar sobre un recurso
request_resource string "commercialLoans" El recurso sobre el que va a actuar el sujeto
request_action string "issue" La acción que el sujeto va a realizar sobre un recurso
request_time datetime '2019-01-02T15:04:05-07:00' La fecha y la hora en que ocurre la solicitud
request_year int 2019 El año en que ocurre la solicitud
request_month int 1, 2, ... 12 El mes en que ocurre la solicitud
request_day int 1, 2, ... 31 El día del mes en que ocurre la solicitud
request_hour int 0, 1, ... 23 La hora del día en que ocurre la solicitud
request_weekday string "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" El día de la semana en que ocurre la solicitud
2.2.2 Atributos del cliente
2.2.2.1 name

Para referencias de condición portables, prefiera [A-Za-z][A-Za-z0-9_]* y evite los nombres de atributos y funciones integrados. La capa REST acepta hasta 256 letras ASCII, dígitos, guiones bajos, guiones y puntos. Pruebe las referencias de expresión que contienen un guion o un punto en lugar de suponer que son identificadores ordinarios y no operadores.

2.2.2.2 value

Cuando una condición usa atributos del cliente, hay que pasar sus valores al solicitar un resultado isAllowed. Si la solicitud no lleva un atributo que la condición referencia, la condición no coincide; un deny condicional no se aplica en ese caso. Asegúrese de que el PEP aporta cada atributo que usan las condiciones de denegación, y pruebe esas solicitudes.

  • Pasar valores de atributos en la API de Go
    Siga estas reglas al pasar valores de atributos del cliente a una API de Go:

    • Use el tipo bool de Go para un valor bool.
    • Use el tipo string de Go para un valor string.
    • Use el tipo float64 de Go para cualquier valor numeric.
    • Para un valor datetime, use un float64 de Go con el tiempo Unix de esa fecha (mediante time.Time.Unix()).
    • Use []interface{} de Go para un valor array.
  • Pasar valores de atributos en la API REST
    Siga estas reglas al pasar valores de atributos del cliente a una API REST:

    • El atributo es una estructura con name, type y value. Consulte la API REST para el detalle.
    • El tipo del atributo solo puede ser “string”, “numeric”, “bool” o “datetime”.
    • El valor del atributo puede ser un valor único o un slice.

2.3 Constantes

Tipos de datos admitidos:

  • string: comillas simples, ‘foobar’
  • numeric: 10, 3.1415926
  • bool: true o false
  • datetime: comillas simples, conforme a RFC3339. El formato RFC3339 es YYYY-MM-DDTHH:mm:SS[.sssssssss]Z, donde Z es [+|-]HH:mm.
  • array: array de tipo string, numeric, bool o datetime

La tabla siguiente muestra constantes de ejemplo.

Tipo de dato Constantes de ejemplo Arrays de ejemplo
string 'a string' ('string1', 'string2')
bool true
false
(true, false, true)
numeric / float 2.1 (1, 2, 3.1)
datetime '2006-01-02T15:04:05-07:00' ('2016-01-02T15:04:05-07:00', '2019-01-02T15:04:05-07:00')

2.4 Funciones

Use funciones cuando los operadores o comparadores existentes no cubren el requisito.

2.4.1 Funciones integradas

Speedle proporciona las siguientes funciones integradas.

Nombre de la función integrada Función Entrada y tipo de dato Salida y tipo de dato Uso de ejemplo
Sqrt Raíz cuadrada de un numeric Un parámetro numeric numeric Sqrt(x)
Sqrt(64)
Max Obtiene el numeric máximo de un conjunto Uno o más parámetros numeric numeric Max(1, 4, x)
Min Obtiene el numeric mínimo de un conjunto Uno o más parámetros numeric numeric Min(x, 5, z)
Sum Obtiene la suma de un conjunto de numeric Uno o más parámetros numeric numeric Sum(1, 3, 5, 7, x)
Avg Obtiene el promedio de un conjunto de numeric Uno o más parámetros numeric numeric Avg(x, 8, 10)
IsSubSet Comprueba si el primer conjunto o array es subconjunto del segundo 2 conjuntos o arrays cuyos elementos tienen el mismo tipo de dato bool IsSubSet(s1, s2)

Las funciones numéricas integradas rechazan entradas o resultados no finitos y raíces cuadradas negativas con BuiltInFuncError. Una función que falla hace que su condición no coincida, igual que otros errores de condición en tiempo de ejecución. Sum() y Avg() conservan el resultado histórico de cero cuando la entrada está vacía. IsSubSet ignora los elementos duplicados, rechaza tipos de elemento no admitidos o mezclados, y conserva el resultado histórico false para un conjunto vacío. Los nombres entre comillas de SPDL conservan las barras invertidas literales; use el otro estilo de comillas cuando un nombre contiene una comilla. Las sentencias deben consumirse por completo: se rechazan el texto sobrante, las condiciones incompletas y las comillas de nombre sin cerrar.

2.4.2 Funciones personalizadas

También se pueden exponer funciones propias mediante una API REST y usarlas en una expresión de condición.
Para el detalle, consulte función personalizada.

2.5 Precedencia de operadores y comparadores

2.5.1 Orden de precedencia

Cuando dos operadores comparten un operando, se aplica primero el de mayor precedencia. Por ejemplo, 1 + 2 * 3 se trata como 1 + (2 * 3), mientras que 1 * 2 + 3 se trata como (1 * 2) + 3 porque la multiplicación tiene mayor precedencia que la suma.

2.5.2 Asociatividad

Cuando una expresión tiene dos operadores de la misma precedencia, se evalúa según su asociatividad. 72 / 2 / 3 se trata como (72 / 2) / 3 porque el operador / es asociativo de izquierda a derecha. Algunos operadores no son asociativos: por ejemplo, las expresiones (x <= y <= z) y x++-- no son válidas.

2.5.3 Precedencia y asociatividad de los operadores y comparadores admitidos

La tabla siguiente resume la sintaxis de expresión documentada, de mayor a menor precedencia. Las comparaciones se ligan antes que el AND/OR lógico; use paréntesis para aclarar las condiciones complejas.

Precedencia (de mayor a menor)Operador o comparadorAsociatividad
1( )N/A
2llamada a funciónN/A
3! y - unarioDe derecha a izquierda
4* / %De izquierda a derecha
5+ -De izquierda a derecha
6== != =~ > >= < <= inN/A
7&&De izquierda a derecha
8||De izquierda a derecha

2.6 Condiciones de ejemplo

Condición Comentario
a=='abc' El valor del atributo 'a' es igual a 'abc'
a!='abc'
a>='abc'
a+b=='ab'
a=~'^get.*'El valor del atributo 'a' coincide con la expresión regular '^get.*'
a==123
a-b>123
a in (1, 2, 3) El valor del atributo 'a' es uno de 1, 2, 3
'manager' in a 'a' es un atributo de array de string y 'manager' es uno de sus elementos
IsSubSet(e, ('s1', 's2', 's3'))'e' es un atributo de array o conjunto de string, y e es subconjunto de ('s1', 's2', 's3')
a in (1, 2, 3) && (b==c || d==3) && IsSubSet(e, ('s1', 's2', 's3'))
request_year==2019 && request_month==12 request_year y request_month son atributos integrados. El año en que se accede a un recurso es 2019 y el mes es 12

Definición de la condición

La condición debe ser una expresión booleana válida. Lo siguiente resume las expresiones habituales; valide las entradas exactas con el analizador actual:

BoolExpr: ('!')BoolExpr
          | BoolExpr ('&&'|'||') BoolExpr
		  | BoolConstant
		  | Attribute
		  | Function
		  | RelationalExpr
		  | '(' BoolExpr ')'


RelationalExpr: NumericExpr ('=='|'!='|'>'|'>='|'<'|'<=') NumericExpr
              | StringExpr ('=='|'!='|'=~'|'>'|'>='|'<'|'<=') StringExpr
			  | BoolExpr ('=='|'!=') BoolExpr
			  | DateTimeExpr ('=='|'!='|'>'|'>='|'<'|'<=') DateTimeExpr
			  | (NumericExpr|StringExpr|BoolExpr|DateTimeExpr) ('in') ArrayExpr


NumericExpr: NumericExpr('+'|'-'|'*'|'/'|'%')NumericExpr
           | NumericConstant
		   | Attribute
		   | Function
		   | '(' NumericExpr ')'

StringExpr: StringExpr('+') StringExpr
           | StringConstant
		   | Attribute
		   | Function
           | '(' StringExpr ')'

DateTimeExpr: DateTimeConstant
           | Attribute
           | Function

ArrayExpr: ArrayConstant
         | Attribute
         | Function

ArrayConstant: '('Constant [, Constant]* ')'

Constant: NumericConstant
         |StringConstant
         |BoolConstant
         |DateTimeConstant

NumericConstant: any numeric float64 data
StringConstant: single quoted string, for example, 'string1'
BoolConstant: true|false
DateTimeConstant: single quoted datetime, datetime should conform to the format defined by RFC3339: YYYY-MM-DDTHH:mm:SS[.sssssssss]Z, Z is [+|-]HH:mm. For example, '2016-01-02T15:04:05-07:00'

Attribute: attribute name should conform to  [a-zA-Z]+[a-zA-Z0-9_]*, prefer simple portable identifiers; REST attribute names are limited to 256 ASCII characters
Function: FunctionName '(' Argument [,Argument]* ')'

Apéndice

Sintaxis completa de SPDL

Sintaxis completa de definición de políticas