一般運算語言 (CEL) 是一種通用運算式語言,設計宗旨是執行快速、可攜式且安全。您可以單獨使用 CEL,也可以將其嵌入較大的產品。CEL 適用於各種應用程式,從遠端程序呼叫 (RPC) 的路由到定義安全政策,都能派上用場。CEL 具有擴充性,不受平台限制,且經過最佳化,適用於編譯一次/評估多次的工作流程。
CEL 專為安全執行使用者程式碼而設計。盲目對使用者的 Python 程式碼呼叫 eval()
很危險,但您可以安全地執行使用者的 CEL 程式碼。此外,由於 CEL 會避免導致效能降低的行為,因此評估作業可在奈秒或微秒內安全完成。CEL 的速度和安全性非常適合用於效能至關重要的應用程式。
CEL 會評估類似單行函式或 lambda 運算式的運算式。雖然 CEL 通常用於布林決策,但您也可以使用 CEL 建構更複雜的物件,例如 JSON 或通訊協定緩衝區訊息。
為什麼要使用 CEL?
許多服務和應用程式都會評估宣告式設定。舉例來說,角色型存取控管 (RBAC) 是一種宣告式設定,可根據使用者角色和一組使用者做出存取決策。雖然宣告式設定檔在大多數情況下都夠用,但有時您需要更具表現力的功能。這時 CEL 就能派上用場。
以使用 CEL 擴充宣告式設定為例,請考慮 Google Cloud Identity and Access Management (IAM) 的功能。雖然 RBAC 是常見情況,但 IAM 提供 CEL 運算式,可讓使用者根據要求或存取資源的 Proto 訊息屬性,進一步限制角色型授權的範圍。透過資料模型描述這類條件,會導致 API 介面複雜難用。相較之下,搭配屬性型存取權控管 (ABAC) 使用 CEL,是 RBAC 的強大擴充功能,可提供更豐富的控制選項。
CEL 核心概念
在 CEL 中,運算式會根據環境編譯。編譯步驟會產生 Protocol Buffers 格式的抽象語法樹狀結構 (AST)。編譯後的運算式會儲存起來,供日後使用,盡可能加快評估速度。單一編譯運算式可使用許多不同的輸入內容進行評估。
以下將進一步說明其中一些概念。
運算式
運算式是由使用者撰寫。運算式類似於單行函式主體或 lambda 運算式。宣告輸入內容的函式簽章會寫在 CEL 運算式外部,而 CEL 可用的函式庫會自動匯入。
舉例來說,下列 CEL 運算式會採用要求物件,且要求包含 claims
權杖。運算式會傳回布林值,指出 claims
權杖是否仍有效。
驗證權杖的 CEL 運算式範例
// Check whether a JSON Web Token has expired by inspecting the 'exp' claim.
//
// Args:
// claims - authentication claims.
// now - timestamp indicating the current system time.
// Returns: true if the token has expired.
//
timestamp(claims["exp"]) < now
使用者定義 CEL 運算式時,服務和應用程式會定義運算式的執行環境。
環境
環境是由服務定義。內嵌 CEL 的服務和應用程式會宣告運算式環境。環境是可在 CEL 運算式中使用的變數和函式集合。
舉例來說,下列 textproto
程式碼會宣告環境,其中包含來自 CEL 服務的 CompileRequest
訊息,並使用 request
和 now
變數。
CEL 環境宣告範例
# Format: $SOURCE_PATH/service.proto#CompileRequest
declarations {
name: "request"
ident {
type { message_type: "google.rpc.context.AttributeContext.Request" }
}
}
declarations {
name: "now"
ident {
type { we
ll_known: "TIMESTAMP" }
}
}
CEL 型別檢查程式會使用以 Proto 為基礎的宣告,確保運算式中的所有 ID 和函式參照都已宣告並正確使用。
運算式處理階段
系統會分三個階段處理 CEL 運算式:
- 剖析
- 檢查
- 評估
最常見的 CEL 用法是在設定時剖析及檢查運算式、儲存 AST,然後在執行階段重複擷取及評估 AST。
CEL 處理階段的插圖
CEL 會使用 ANTLR 詞法分析器和剖析器文法,從人類可解讀的運算式剖析為 AST。剖析階段會發出以 Proto 為基礎的 AST,其中 AST 中的每個 Expr
節點都包含整數 ID,用於索引剖析和檢查期間產生的中繼資料。剖析期間產生的 syntax.proto
檔案,代表以字串形式輸入的運算式抽象表示法。
剖析運算式後,系統會根據環境進行型別檢查,確保運算式中的所有變數和函式 ID 都已宣告,且使用方式正確。型別檢查器會產生 checked.proto
檔案,其中包含型別、變數和函式解析度中繼資料,可大幅提升評估效率。
最後,在剖析及檢查運算式後,系統會評估儲存的 AST。
CEL 評估工具需要三項資訊:
- 任何自訂擴充功能的函式繫結
- 變數繫結
- 要評估的 AST
函式和變數繫結應與用於編譯 AST 的繫結相符。這些輸入內容都可以在多項評估中重複使用,例如在多組變數繫結中評估的 AST、用於多個 AST 的相同變數,或是在程序生命週期中使用的函式繫結 (常見情況)。