Common Expression Language (CEL) adalah bahasa ekspresi serbaguna yang dirancang agar cepat, portabel, dan aman untuk dieksekusi. Anda dapat menggunakan CEL secara terpisah atau menyematkannya ke dalam produk yang lebih besar. CEL sangat cocok untuk berbagai aplikasi, mulai dari merutekan remote procedure call (RPC) hingga menentukan kebijakan keamanan. CEL dapat diperluas, tidak bergantung pada platform, dan dioptimalkan untuk alur kerja kompilasi sekali/evaluasi berkali-kali.
CEL dirancang khusus agar aman untuk mengeksekusi kode pengguna. Meskipun berbahaya untuk memanggil eval()
secara membabi buta pada kode python pengguna, Anda dapat menjalankan kode CEL pengguna dengan aman. Selain itu, karena CEL mencegah perilaku yang akan membuatnya
kurang berperforma, CEL dievaluasi dengan aman dalam nanodetik atau mikrodetik. Kecepatan dan keamanan CEL menjadikannya ideal untuk aplikasi yang penting performanya.
CEL mengevaluasi ekspresi yang mirip dengan fungsi satu baris atau ekspresi lambda. Meskipun umumnya digunakan untuk keputusan boolean, Anda juga dapat menggunakan CEL untuk membuat objek yang lebih kompleks seperti pesan JSON atau buffer protokol.
Mengapa CEL?
Banyak layanan dan aplikasi mengevaluasi konfigurasi deklaratif. Misalnya, kontrol akses berbasis peran (RBAC) adalah konfigurasi deklaratif yang menghasilkan keputusan akses berdasarkan peran pengguna dan sekumpulan pengguna. Meskipun konfigurasi deklaratif sudah cukup untuk sebagian besar kasus, terkadang Anda memerlukan kemampuan ekspresif yang lebih besar. Di sinilah CEL berperan.
Sebagai contoh memperluas konfigurasi deklaratif dengan CEL, pertimbangkan kemampuan Identity and Access Management (IAM) Google Cloud. Meskipun RBAC adalah kasus umum, IAM menawarkan ekspresi CEL untuk memungkinkan pengguna membatasi lebih lanjut cakupan pemberian berbasis peran sesuai dengan properti pesan proto permintaan atau resource yang diakses. Mendeskripsikan kondisi tersebut melalui model data akan menghasilkan permukaan API yang rumit dan sulit digunakan. Sebagai gantinya, penggunaan CEL dengan kontrol akses berbasis atribut (ABAC) adalah ekstensi RBAC yang ekspresif dan canggih.
Konsep inti CEL
Di CEL, ekspresi dikompilasi terhadap lingkungan. Langkah kompilasi menghasilkan pohon sintaksis abstrak (AST) dalam format protocol buffer. Ekspresi yang dikompilasi disimpan untuk digunakan pada masa mendatang agar evaluasi tetap secepat mungkin. Satu ekspresi yang dikompilasi dapat dievaluasi dengan banyak input yang berbeda.
Berikut adalah penjelasan lebih lanjut tentang beberapa konsep ini.
Ekspresi
Ekspresi ditulis oleh pengguna. Ekspresi mirip dengan isi fungsi satu baris atau ekspresi lambda. Tanda tangan fungsi yang mendeklarasikan input ditulis di luar ekspresi CEL, dan library fungsi yang tersedia untuk CEL diimpor secara otomatis.
Misalnya, ekspresi CEL berikut mengambil objek permintaan, dan permintaan menyertakan token claims
. Ekspresi 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 tempat ekspresi tersebut berjalan.
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 { we
ll_known: "TIMESTAMP" }
}
}
Deklarasi berbasis proto digunakan oleh pemeriksa jenis CEL untuk memastikan bahwa semua referensi fungsi dan ID dalam ekspresi dideklarasikan dan digunakan dengan benar.
Fase pemrosesan ekspresi
Ekspresi CEL diproses dalam tiga fase:
- Parse
- Cek
- Evaluasi
Pola penggunaan CEL yang paling umum adalah mengurai dan memeriksa ekspresi pada waktu konfigurasi, menyimpan AST, lalu mengambil dan mengevaluasi AST berulang kali pada waktu runtime.
Ilustrasi fase pemrosesan CEL
CEL diuraikan dari ekspresi yang mudah dibaca manusia menjadi AST menggunakan tata bahasa parser dan leksikal ANTLR. Fase penguraian memancarkan AST berbasis proto yang setiap node Expr
dalam AST berisi ID bilangan bulat yang digunakan untuk mengindeks metadata yang dihasilkan selama penguraian dan pemeriksaan. File
syntax.proto
yang dihasilkan selama penguraian merepresentasikan
representasi abstrak dari apa yang diketik dalam bentuk string dari
ekspresi.
Setelah ekspresi diuraikan, ekspresi tersebut kemudian 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 mencakup metadata penyelesaian jenis, variabel, dan fungsi yang dapat meningkatkan efisiensi evaluasi secara drastis.
Terakhir, setelah ekspresi diuraikan dan diperiksa, AST yang disimpan akan dievaluasi.
Evaluator CEL memerlukan tiga hal:
- Pengikatan fungsi untuk ekstensi kustom
- Binding variabel
- AST yang akan dievaluasi
Binding fungsi dan variabel harus cocok dengan yang digunakan untuk mengompilasi AST. Setiap input ini dapat digunakan kembali di beberapa evaluasi, seperti AST yang dievaluasi di banyak set pengikatan variabel, variabel yang sama yang digunakan terhadap banyak AST, atau pengikatan fungsi yang digunakan selama masa aktif proses (kasus umum).