SPDL は Speedle ポリシーおよびロールポリシーを記述するための言語です。このページでは構文、命名規則、およびサンプルを説明します。
構文

キーワード
grant、deny、user、group、entity、role、from、on、if、in はそれぞれの構文上の位置で特別な意味を持ちます。ステートメントのキーワードは大文字と小文字を区別しません。条件内では in または IN を使用し、関数名は大文字と小文字を区別します。プリンシパル、アクション、およびリソース名も大文字と小文字を区別します。現在のパーサーは一部の名前の位置でキーワードに類似した名前を受け入れますが、一律の禁止を検証ルールとして前提にしないでください。レビューとクライアント間の相互運用性を高めるため、曖昧さのない名前を推奨します。
命名規則
シンプルで安定した識別子を推奨します。空白や区切り文字を含む名前は、パーサーがサポートする単一引用符または二重引用符で囲み、実際の入力でテストしてください。過去の Java 正規表現の文字クラスは、現在の Go パーサーの検証コントラクトではありません。リソースプレフィックス expr: はシェルの glob ではなく Go の正規表現を使用します。条件内の属性および関数名については後述します。
構文定義
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
サンプル
ロール継承: ロールポリシーのサブジェクトは別のロールにすることができるため、manager は employee に割り当てられたすべてのロールも保持します。
grant role manager employee拒否の優先: 該当する拒否(deny)は許可(grant)よりも優先されます。以下の例では、carol は staff に属していますが、journal に対する delete は拒否されます。
grant group staff read,delete journal
deny user carol delete journal条件: 条件が真の場合にのみポリシーが適用されます。
grant user bob read report if department == 'finance'これらは SPDL ステートメントの例であり、完全なサービス設定ではありません。サービス、リソーススコープのロール、および完全な決定例については ポリシー管理 を参照してください。
条件(Condition)
1. 概要
認可ポリシーおよびロールポリシーの両方で条件がサポートされています。条件が満たされた場合に*のみ*、ポリシーまたはロールポリシーが有効になります。
ポリシー適用ポイント (PEP) は、ポリシーが参照するすべてのカスタム属性を提供する必要があります。request_user や request_time などの組み込み属性は ADS によって提供されます。PEP から提供される属性は、エンドユーザーから直接取得するのではなく、呼び出し元の信頼できるアプリケーションまたはサービスから提供される必要があり、PEP は送信する値に責任を持ちます。PEP から提供される属性は、同じ名前の組み込み属性よりも優先されます。特に、信頼できないエンドユーザーの入力を request_user、request_time、またはその他の組み込み属性名として転送しないでください。
リクエストに存在しない属性を参照する条件は一致しません。したがって、条件付きの deny は、その属性が存在しない場合には適用されません。拒否条件が使用する属性を PEP が常に提供していることを確認し、それらのリクエストをテストしてください。
このドキュメントでは、条件とは何か、および条件の記述方法に焦点を当てています。
2. 条件の構成
条件は、属性、関数、定数、演算子、比較演算子、または括弧を使用して構築され、ブール値を生成するブール式です。
2.1 データ型
属性値および定数のデータ型は、string、numeric、bool、datetime、またはこれらの型の配列です。
サポートされているデータ型と対応する演算子および比較演算子を以下の表に示します。
| データ型 | 演算子 | 比較演算子 | 説明 |
|---|---|---|---|
| string | + | == != =~ > >= < <= |
+ は文字列の連結に使用されます。=~ は正規表現マッチング用です。表の下の注記を参照してください。 |
| numeric | + - * / % |
== != > >= < <= |
|
| bool | && || ! |
== != |
|
| datetime | == != > >= < <= |
||
| array | in | 所属を表す in 演算子: 左辺は単一の型(string、numeric、bool、datetime)、右辺は配列である必要があります |
"=~" についての注記:
"=~" は正規表現比較演算子です。Go 言語の標準 regexp 構文を使用します。左辺は候補文字列、右辺は正規表現パターンです。候補文字列が右辺で指定された正規表現パターンに一致するかどうかをブール値で返します。
- 左辺: string
- 右辺: string
- 戻り値: bool
2.2 属性
条件内の属性は変数を表します。属性値はランタイムで決定され、認可決定サービス (ADS) のランタイムまたは PEP のいずれかから取得されます。
組み込み属性は、ADS ランタイムによって自動的に設定される値です。
カスタム属性は、認可決定を要求する際に、エンドユーザーからではなく呼び出し元の信頼できるアプリケーションまたはサービス(PEP)によって提供される値です。PEP は送信する値に責任を持ちます。PEP から提供される属性は同名の組み込み属性よりも優先されるため、PEP は信頼できないエンドユーザーの入力を組み込み属性名として転送してはなりません。
2.2.1 組み込み属性
組み込み属性は以下のとおりです:
| 組み込み属性名 | データ型 | サンプル値 | 定義 |
|---|---|---|---|
| request_user | string | "Alice" | リソースに対する操作を要求しているサブジェクト内のユーザー情報 |
| request_groups | []string | []string{"managers"} | リソースに対する操作を要求しているサブジェクト内のグループ情報 |
| request_entity | string | "/org1/service1" | サービスまたはプログラムがリソースに対する操作を要求しているサブジェクト内のサービス名またはその他のエンティティ情報 |
| request_resource | string | "commercialLoans" | サブジェクトが操作対象とするリソース |
| request_action | string | "issue" | サブジェクトがリソースに対して実行するアクション |
| request_time | datetime | '2019-01-02T15:04:05-07:00' | リクエストが発生した日時 |
| request_year | int | 2019 | リクエストが発生した年 |
| request_month | int | 1, 2, ... 12 | リクエストが発生した月 |
| request_day | int | 1, 2, ... 31 | リクエストが発生した月の日 |
| request_hour | int | 0, 1, ... 23 | リクエストが発生した時刻(時) |
| request_weekday | string | "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" | リクエストが発生した曜日 |
2.2.2 カスタム属性
2.2.2.1 属性名
移植性の高い条件参照のため、[A-Za-z][A-Za-z0-9_]* に適合する名前を推奨し、組み込みの属性名や関数名との重複を避けてください。REST レイヤーは最大 256 文字の ASCII 文字、数字、アンダースコア、ハイフン、およびドットを受け入れます。ハイフンやドットを含む式参照は、演算子として誤認されないよう実際にテストしてください。
2.2.2.2 属性値
カスタム属性が条件で使用されている場合、クライアントは isAllowed 結果をリクエストする際にカスタム属性値を渡す必要があります。リクエストに条件が参照する属性が含まれていない場合、条件は一致しません。その場合、条件付きの deny は適用されません。拒否条件が使用するすべての属性を PEP が提供していることを確認し、それらのリクエストをテストしてください。
Go API での属性値の受け渡し
Go API にカスタム属性値を渡す際は、以下の規則に従ってください:- bool 属性値には Go の bool 型を使用します。
- string 属性値には Go の string 型を使用します。
- 数値属性値には Go の float64 型を使用します。
- datetime 属性値には、その日時の Unix 時間を表す Go の float64 表現(
time.Time.Unix()を使用)を使用します。 - 配列属性値には Go の []interface{} を使用します。
REST API での属性値の受け渡し
REST API にカスタム属性値を渡す際は、以下の規則に従ってください:- 属性は、属性の名前、型、値を含む構造体です。詳細については REST API を参照してください。
- 属性の型は “string”、”numeric”、”bool”、または “datetime” のみ指定できます。
- 属性値は単一の値またはスライスにすることができます。
2.3 定数
サポートされているデータ型:
- string: 単一引用符、’foobar’
- numeric: 10、3.1415926
- bool: true または false
- datetime: 単一引用符、RFC3339 に準拠。RFC3339 形式の日時は YYYY-MM-DDTHH:mm:SS[.sssssssss]Z(Z は [+|-]HH:mm)です。
- array: string、numeric、bool、datetime 型の配列
以下の表は定数のサンプルを示しています。
| データ型 | 定数の例 | 定数配列の例 |
|---|---|---|
| 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 関数
既存の演算子や比較演算子では要件を満たせない場合に関数を使用します。
2.4.1 組み込み関数
Speedle は以下の組み込み関数を提供します。
| 組み込み関数名 | 機能 | 入力とデータ型 | 出力とデータ型 | 使用例 |
|---|---|---|---|---|
| Sqrt | 数値の平方根を計算 | 1 つの数値パラメータ | numeric | Sqrt(x) Sqrt(64) |
| Max | 集合内の最大値を取得 | 1 つ以上の数値パラメータ | numeric | Max(1, 4, x) |
| Min | 集合内の最小値を取得 | 1 つ以上の数値パラメータ | numeric | Min(x, 5, z) |
| Sum | 数値の集合の合計を取得 | 1 つ以上の数値パラメータ | numeric | Sum(1, 3, 5, 7, x) |
| Avg | 数値の集合の平均値を取得 | 1 つ以上の数値パラメータ | numeric | Avg(x, 8, 10) |
| IsSubSet | 最初の集合/配列が 2 番目の集合/配列の部分集合であるか確認 | 同じデータ型の要素を持つ 2 つの集合/配列 | bool | IsSubSet(s1, s2) |
数値組み込み関数は、非有限の入力/結果および負の平方根に対して BuiltInFuncError を返します。関数の失敗は、他のランタイム条件エラーと同様に条件を不一致にします。Sum() および Avg() は、空の入力に対してゼロを返す従来の動作を保持しています。IsSubSet は重複要素を無視し、サポートされていない要素型や混在した要素型を拒否し、空の集合に対して false を返す従来の動作を保持しています。SPDL で引用符で囲まれた名前はリテラルのバックスラッシュを保持します。名前に引用符が含まれる場合は、別の種類の引用符を使用してください。ステートメントは完全に消費される必要があり、末尾の余計なテキスト、不完全な条件、および閉じられていない名前の引用符は拒否されます。
2.4.2 カスタム関数
REST API を通じて独自の関数を公開し、条件式でカスタム関数を使用することもできます。
詳細については カスタム関数 を参照してください。
2.5 演算子および比較演算子の優先順位
2.5.1 優先順位
2 つの演算子がオペランドを共有する場合、優先順位の高い演算子が先に評価されます。たとえば、乗算は加算よりも優先順位が高いため、1 + 2 * 3 は 1 + (2 * 3) として扱われ、1 * 2 + 3 は (1 * 2) + 3 として扱われます。
2.5.2 結合性
式に同じ優先順位の演算子が 2 つある場合、式はその結合性に従って評価されます。/ 演算子は左から右への結合性を持つため、72 / 2 / 3 は (72 / 2) / 3 として扱われます。一部の演算子は結合性を持ちません。たとえば、式 (x <= y <= z) や x++-- は無効です。
2.5.3 サポートされている演算子および比較演算子の優先順位と結合性
以下の表は、ドキュメント化された式の構文を優先順位の高い順にまとめたものです。比較は論理 AND/OR よりも前に結合します。複雑な条件を明確にするには括弧を使用してください。
| 優先順位(高い順) | 演算子 / 比較演算子 | 結合性 |
|---|---|---|
| 1 | ( ) | 該当なし |
| 2 | 関数呼び出し | 該当なし |
| 3 | ! および単項 - | 右から左 |
| 4 | * / % | 左から右 |
| 5 | + - | 左から右 |
| 6 | == != =~ > >= < <= in | 該当なし |
| 7 | && | 左から右 |
| 8 | || | 左から右 |
2.6 条件のサンプル
| 条件 | 説明 |
|---|---|
| a=='abc' | 属性 'a' の値が 'abc' に等しい |
| a!='abc' | |
| a>='abc' | |
| a+b=='ab' | |
| a=~'^get.*' | 属性 'a' の値が正規表現 '^get.*' に一致する |
| a==123 | |
| a-b>123 | |
| a in (1, 2, 3) | 属性 'a' の値が 1、2、3 のいずれかである |
| 'manager' in a | 'a' は文字列配列属性であり、'manager' はその配列要素の 1 つである |
| IsSubSet(e, ('s1', 's2', 's3')) | 'e' は文字列配列/集合の属性であり、e は配列/集合 ('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 と request_month は組み込み属性です。リソースにアクセスした年が 2019 であり、アクセスした月が 12 であることを要求します |
条件の文法定義
条件は有効なブール式である必要があります。以下は一般的な式のまとめです。正確な入力については現在のパーサーで検証してください:
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]* ')'付録
SPDL 完全構文
