Ortak İfade Dili (CEL)

Common Expression Language (CEL); hızlı, taşınabilir ve güvenli olacak şekilde tasarlanmış genel amaçlı bir ifade dilidir. CEL'i tek başına kullanabilir veya daha büyük bir ürünün içine yerleştirebilirsiniz. CEL, uzak prosedür çağrılarını (RPC'ler) yönlendirmekten güvenlik politikaları tanımlamaya kadar çok çeşitli uygulamalar için idealdir. CEL genişletilebilir, platformdan bağımsızdır ve bir kez derleme/birçok iş akışı için optimize edilmiştir.

CEL, kullanıcı kodunu çalıştırmak için özel olarak güvenli şekilde tasarlanmıştır. Bir kullanıcının python kodunda gizlice eval() çağırmak tehlikeli olsa da kullanıcının CEL kodunu güvenle çalıştırabilirsiniz. CEL, daha az performans gösteren davranışları önlediğinden nanosaniye veya mikrosaniye cinsinden güvenli bir şekilde değerlendirme yapar. CEL, hızı ve güvenliği sayesinde performans açısından kritik uygulamalar için idealdir.

CEL, tek satırlı işlevlere veya lambda ifadelerine benzer ifadeleri değerlendirir. CEL, boole kararları için yaygın olarak kullanılır. Bununla birlikte CEL, JSON veya protokol arabellek mesajları gibi daha karmaşık nesneler oluşturmak için de kullanılabilir.

Neden CEL?

Birçok hizmet ve uygulama bildirim temelli yapılandırmaları değerlendirir. Örneğin, rol tabanlı erişim denetimi (RBAC), bir kullanıcı rolü ve bir kullanıcı grubu için erişim kararı oluşturan bildirim temelli bir yapılandırmadır. Bildirim temelli yapılandırmalar çoğu durumda yeterli olsa da bazen daha ifade gücüne ihtiyacınız olur. Bu noktada CEL devreye girer.

CEL ile bildirim temelli bir yapılandırmayı genişletme örneği olarak Google Cloud Identity and Access Management (IAM) özelliklerini göz önünde bulundurun. RBAC yaygın görülen bir uygulama olsa da IAM, kullanıcıların isteğin proto mesaj özelliklerine veya erişilen kaynaklara göre rol tabanlı iznin kapsamını daha fazla sınırlamasına olanak tanımak için CEL ifadeleri sunar. Bu tür koşulların veri modeli aracılığıyla açıklanması, çalışması zor olan karmaşık bir API yüzeyine neden olur. CEL'i özellik tabanlı erişim denetimi (ABAC) ile kullanmak, RBAC için anlamlı ve güçlü bir uzantıdır.

CEL ile ilgili temel kavramlar

CEL'de bir ifade ortama karşı derlenir. Derleme adımı, protokol arabelleği biçiminde soyut bir söz dizimi ağacı (AST) oluşturur. Derlenen ifadeler, değerlendirmeyi mümkün olduğunca hızlı tutmak için ileride kullanılmak üzere depolanır. Tek bir derlenmiş ifade birçok farklı girişle değerlendirilebilir.

Aşağıda, bu kavramlardan bazılarına daha yakından bakalım.

İfadeler

İfadeler kullanıcılar tarafından yazılır. İfadeler, tek satırlı işlev gövdelerine veya lambda ifadelerine benzer. Girişi açıklayan işlev imzası, CEL ifadesinin dışına yazılır ve CEL'in kullanabildiği işlev kitaplığı otomatik olarak içe aktarılır.

Örneğin, aşağıdaki CEL ifadesi bir istek nesnesi alır ve istek bir claims jetonu içerir. İfade, claims jetonunun hâlâ geçerli olup olmadığını gösteren bir boole değeri döndürür.

Hak talebi jetonunun kimliğini doğrulamak için örnek CEL ifadesi

// 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

Kullanıcılar CEL ifadesini tanımlarken hizmetler ve uygulamalar çalıştırıldığı ortamı tanımlar.

Ortam

Ortamlar hizmetler tarafından tanımlanır. CEL yerleştiren hizmetler ve uygulamalar ifade ortamını bildirir. Ortam, CEL ifadelerinde kullanılabilecek değişkenlerin ve işlevlerin koleksiyonudur.

Örneğin, aşağıdaki textproto kodu bir CEL hizmetinden gelen CompileRequest mesajını kullanarak request ve now değişkenlerini içeren bir ortamı tanımlar.

Örnek CEL ortamı beyanı

# Format: $SOURCE_PATH/service.proto#CompileRequest
declarations {
  name: "request"
  ident {
    type { message_type: "google.rpc.context.AttributeContext.Request" }
  }
}
declarations {
  name: "now"
  ident {
    type { well_known: "TIMESTAMP" }
  }
}

Proto tabanlı bildirimler, bir ifade içindeki tüm tanımlayıcı ve işlev referanslarının doğru tanımlandığından ve kullanıldığından emin olmak için CEL tür denetleyicisi tarafından kullanılır.

İfade işleme aşamaları

CEL ifadeleri üç aşamada işlenir:

  1. Ayrıştır
  2. İşaretle
  3. Değerlendirme

CEL kullanımının en yaygın kalıbı, ifadeleri yapılandırma anında ayrıştırıp kontrol etmek, AST'yi depolamak ve ardından AST'yi çalışma zamanında tekrar tekrar alıp değerlendirmektir.

CEL işleme aşamalarını gösteren görsel

İfadeler, yapılandırma yollarında ayrıştırılır ve kontrol edilir, depolanır ve ardından okuma yollarındaki bir veya daha fazla bağlama göre değerlendirilir.

CEL, ANTLR lexer ve ayrıştırıcı dil bilgisi kullanılarak insanlar tarafından okunabilen bir ifadeden AST'ye ayrıştırılır. Ayrıştırma aşaması, AST'deki her Expr düğümünün, ayrıştırma ve kontrol sırasında oluşturulan meta verileri dizine eklemek için kullanılan bir tam sayı kimliği içerdiği proto tabanlı bir AST yayınlar. Ayrıştırma sırasında oluşturulan syntax.proto dosyası, ifadenin dize formuna yazılanların soyut temsilini temsil eder.

Bir ifade ayrıştırıldıktan sonra, ifadedeki tüm değişken ve işlev tanımlayıcılarının bildirildiğinden ve doğru şekilde kullanıldığından emin olmak için ortama göre tür denetimi gerçekleştirilir. Tür denetleyici, değerlendirme verimliliğini büyük ölçüde artırabilecek tür, değişken ve işlev çözünürlüğü meta verilerini içeren bir checked.proto dosyası oluşturur.

Son olarak, bir ifade ayrıştırılıp kontrol edildikten sonra depolanan AST değerlendirilir.

CEL değerlendiricisinin üç şeye ihtiyacı vardır:

  • Özel uzantılar için işlev bağlamaları
  • Değişken bağlamalar
  • Değerlendirilecek bir AST

İşlev ve değişken bağlamaları, AST'yi derlemek için kullanılanla eşleşmelidir. Bu girişlerden herhangi biri, birçok değişken bağlama grubunda değerlendirilen bir AST, birçok AST'de kullanılan aynı değişkenler veya sürecin ömrü boyunca kullanılan işlev bağlamaları (yaygın bir durum) gibi birden fazla değerlendirmede yeniden kullanılabilir.