{i>Common Expression Language

Common Expression Language (CEL) adalah bahasa ekspresi tujuan umum yang dirancang agar cepat, portabel, dan aman untuk dijalankan. Anda dapat menggunakan CEL sendiri atau menyematkannya ke produk yang lebih besar. CEL sangat cocok untuk berbagai aplikasi, mulai dari merutekan panggilan prosedur jarak jauh (RPC) hingga menentukan kebijakan keamanan. CEL dapat diperluas, tidak bergantung pada platform, dan dioptimalkan untuk alur kerja kompilasi-sekali/evaluasi-banyak.

CEL dirancang khusus agar aman dalam mengeksekusi kode pengguna. Meskipun berbahaya untuk memanggil eval() secara membabi buta pada kode python pengguna, Anda dapat menjalankan kode CEL pengguna dengan aman. Karena CEL mencegah perilaku yang akan membuatnya berperforma rendah, CEL akan mengevaluasi dengan aman dalam nanodetik atau mikrodetik. Kecepatan dan keamanan CEL membuatnya ideal untuk aplikasi yang sangat penting bagi performa.

CEL mengevaluasi ekspresi yang mirip dengan fungsi baris tunggal atau ekspresi lambda. Meskipun CEL biasa digunakan untuk membuat keputusan boolean, Anda juga dapat menggunakannya untuk membuat objek yang lebih kompleks seperti pesan JSON atau buffering protokol.

Mengapa CEL?

Banyak layanan dan aplikasi mengevaluasi konfigurasi deklaratif. Misalnya, kontrol akses berbasis peran (RBAC) adalah konfigurasi deklaratif yang menghasilkan keputusan akses dengan peran pengguna dan sekelompok pengguna. Meskipun konfigurasi deklaratif sudah memadai untuk sebagian besar kasus, terkadang Anda memerlukan kekuatan yang lebih ekspresif. Di situlah CEL berperan.

Sebagai contoh untuk memperluas konfigurasi deklaratif dengan CEL, pertimbangkan kemampuan Identity and Access Management (IAM) Google Cloud. Meskipun RBAC merupakan kasus umum, IAM menawarkan ekspresi CEL untuk memungkinkan pengguna membatasi lebih lanjut cakupan hibah berbasis peran sesuai dengan properti pesan proto dari permintaan atau resource yang diakses. Menjelaskan kondisi tersebut melalui model data akan menghasilkan platform API yang rumit dan sulit digunakan. Sebaliknya, penggunaan CEL dengan kontrol akses berbasis atribut (ABAC) merupakan ekstensi yang ekspresif dan efektif untuk RBAC.

Konsep inti CEL

Dalam CEL, ekspresi dikompilasi terhadap lingkungan. Langkah kompilasi menghasilkan hierarki sintaksis abstrak (AST) dalam format protocol buffer. Ekspresi yang dikompilasi disimpan untuk digunakan di masa mendatang guna menjaga evaluasi secepat mungkin. Ekspresi yang dikompilasi dapat dievaluasi dengan berbagai input yang berbeda.

Berikut adalah beberapa konsep tersebut dengan lebih dekat.

Ekspresi

Ekspresi ditulis oleh pengguna. Ekspresi mirip dengan isi fungsi baris tunggal atau ekspresi lambda. Tanda tangan fungsi yang mendeklarasikan input ditulis di luar ekspresi CEL, dan library fungsi yang tersedia untuk CEL akan diimpor secara otomatis.

Misalnya, ekspresi CEL berikut mengambil objek permintaan, dan permintaan menyertakan token claims. Ekspresi tersebut menampilkan nilai boolean yang menunjukkan apakah token claims masih valid.

Contoh ekspresi CEL untuk mengautentikasi token klaim

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

Saat pengguna menentukan ekspresi CEL, layanan dan aplikasi menentukan lingkungan tempatnya dijalankan.

Lingkungan

Lingkungan ditentukan oleh layanan. Layanan dan aplikasi yang menyematkan CEL mendeklarasikan lingkungan ekspresi. Lingkungan adalah kumpulan variabel dan fungsi yang dapat digunakan dalam ekspresi CEL.

Misalnya, kode textproto berikut mendeklarasikan lingkungan yang berisi variabel request dan now menggunakan pesan CompileRequest dari layanan CEL.

Contoh deklarasi lingkungan CEL

# 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" }
  }
}

Deklarasi berbasis proto digunakan oleh pemeriksa jenis CEL untuk memastikan bahwa semua referensi ID dan fungsi dalam ekspresi dideklarasikan dan digunakan dengan benar.

Fase pemrosesan ekspresi

Ekspresi CEL diproses dalam tiga fase:

  1. Parse
  2. Periksa
  3. Evaluasi

Pola penggunaan CEL yang paling umum adalah mengurai dan memeriksa ekspresi pada waktu konfigurasi, menyimpan AST, lalu mengambil dan mengevaluasi AST berulang kali selama runtime.

Ilustrasi fase pemrosesan CEL

Ekspresi diuraikan dan diperiksa di jalur konfigurasi, disimpan, lalu dievaluasi berdasarkan satu atau beberapa konteks pada jalur baca.

CEL diuraikan dari ekspresi yang dapat dibaca manusia menjadi AST menggunakan lexer ANTLR dan tata bahasa parser. Fase penguraian akan memunculkan AST berbasis proto, dengan setiap node Expr di AST berisi ID bilangan bulat yang digunakan untuk mengindeks ke metadata yang dihasilkan selama penguraian dan pemeriksaan. File syntax.proto yang dihasilkan selama penguraian mewakili representasi abstrak dari apa yang diketik dalam bentuk string ekspresi.

Setelah diurai, ekspresi akan diperiksa jenisnya terhadap lingkungan untuk memastikan semua ID variabel dan fungsi dalam ekspresi telah dideklarasikan dan digunakan dengan benar. Pemeriksa jenis menghasilkan file checked.proto yang menyertakan metadata resolusi jenis, variabel, dan fungsi yang dapat meningkatkan efisiensi evaluasi secara drastis.

Akhirnya, setelah ekspresi diuraikan dan diperiksa, AST yang disimpan akan dievaluasi.

Evaluator CEL memerlukan tiga hal:

  • Binding fungsi untuk semua ekstensi kustom
  • Binding variabel
  • AST untuk mengevaluasi

Binding fungsi dan variabel harus cocok dengan yang digunakan untuk mengompilasi AST. Salah satu input ini dapat digunakan kembali di beberapa evaluasi, seperti AST yang dievaluasi di banyak kumpulan binding variabel, variabel yang sama yang digunakan terhadap banyak AST, atau binding fungsi yang digunakan sepanjang waktu proses (kasus umum).