TECH 으로 돌아가기
TECH HACKER NEWS 오늘 6분 읽기 53 READS

쿠버네티스가 쓰는 표현식 언어 CEL, C#으로 직접 구현해본 이야기

사용자한테 '조건식'을 입력받아야 할 때, 어떻게 하세요?

어드민 화면에서 '금액이 1만 원 넘고 국가가 KR이면 통과' 같은 규칙을 운영자가 직접 입력하게 하고 싶은 상황, 개발하다 보면 꼭 한 번은 만나거든요. 이때 제일 위험한 선택이 eval로 코드를 그대로 실행하는 거예요. 사용자 입력이 곧 임의 코드 실행으로 이어지니까요. 그래서 나온 해법이 '표현식 언어'인데, 이 분야에서 사실상 표준으로 자리 잡아가는 게 구글이 만든 CEL(Common Expression Language)이에요. 최근 이 CEL 엔진을 C#/.NET용으로 처음부터 네이티브로 구현한 경험을 정리한 글이 올라와서 소개해드릴게요.

CEL이 뭐냐면요

CEL은 작고, 빠르고, 안전한 것을 목표로 설계된 표현식 언어예요. request.amount > 10000 && request.country == 'KR' 같은 식을 쓰면, 엔진이 이걸 파싱하고 평가해서 결과를 돌려줘요. 가장 중요한 특징은 튜링 완전하지 않다는 건데요. 이게 뭐냐면, 반복문이나 재귀가 아예 없어서 어떤 식을 넣어도 반드시 유한한 시간 안에 실행이 끝난다는 뜻이에요. 사용자가 무한 루프를 만들어 서버를 멈추게 하는 일이 원천적으로 불가능한 거죠. 타입 검사도 실행 전에 해주니까, 잘못된 규칙을 저장 시점에 걸러낼 수 있고요. 이런 안전성 덕분에 쿠버네티스의 ValidatingAdmissionPolicy와 CRD 검증 규칙, 구글 클라우드의 IAM 조건, Envoy 프록시, Firebase 보안 규칙까지, 인프라 세계의 굵직한 곳들이 CEL을 채택했어요.

왜 C# 네이티브 구현이 필요했냐면요

CEL의 레퍼런스 구현은 Go로 된 cel-go이고, cel-cpp, cel-java, cel-rust 같은 구현도 있는데, 유독 .NET 진영에는 제대로 된 네이티브 구현이 없었어요. 그동안 .NET 개발자들의 우회로는 이랬어요. 하나는 Roslyn 스크립팅으로 C# 코드 자체를 동적 실행하는 방법인데, 강력하지만 완전한 언어라서 샌드박스로 가두는 게 사실상 불가능하고 보안 위험이 커요. 다른 하나는 Dynamic LINQ나 NCalc 같은 대안 라이브러리인데, 이건 CEL 문법과 호환이 안 돼서 Go나 Java로 만든 다른 서비스와 규칙을 공유할 수 없다는 한계가 있고요. 네이티브 구현이 생기면 이야기가 달라져요. 같은 CEL 규칙 파일을 Go 서비스와 .NET 서비스가 그대로 공유할 수 있고, 프로세스 간 통신이나 interop 오버헤드도 없고, AOT 컴파일 환경에서도 잘 돌아가거든요. 구현 과정 자체도 흥미로운데, 표현식 언어 엔진은 보통 문법을 해석하는 파서, 타입을 검증하는 타입 체커, 실제 값을 계산하는 평가기의 세 단계로 만들고, CEL은 공식 스펙 준수 테스트(conformance test) 모음이 있어서 내 구현이 표준에 맞는지 기계적으로 검증할 수 있어요.

업계 맥락: 정책을 코드에서 분리하는 흐름

요즘 인프라 업계의 큰 흐름 중 하나가 '정책을 애플리케이션 코드에서 분리하기'예요. 배포 규칙, 접근 제어, 검증 로직을 코드에 하드코딩하지 않고 별도의 규칙 언어로 관리하자는 거죠. 이 분야에는 OPA의 Rego, JsonLogic 같은 경쟁자들이 있는데, Rego는 표현력이 좋은 대신 배우기 어렵다는 평이 많고, JsonLogic은 너무 단순하다는 아쉬움이 있어요. CEL은 그 중간에서 '자바스크립트 비슷한 익숙한 문법 + 안전성 보장'이라는 균형을 잡았고, 쿠버네티스가 공식 채택하면서 무게중심이 확실히 CEL 쪽으로 기울고 있어요. 언어별 네이티브 구현이 늘어날수록 '정책은 CEL로 한 번 작성하고 어디서나 평가한다'는 그림이 현실이 되는 거고요.

한국 개발자에게 주는 시사점

.NET은 국내에서 게임 서버, 엔터프라이즈 시스템, 금융권에서 여전히 큰 지분을 갖고 있잖아요. 이런 환경에서 피처 플래그 조건식, 이벤트 필터링 규칙, 어드민 규칙 엔진, 알림 발송 조건 같은 기능을 만들 때 CEL을 도입하면, eval의 보안 위험 없이 유연한 규칙 시스템을 얻을 수 있어요. 그리고 이 글은 학습 소재로도 훌륭해요. 파서와 인터프리터를 직접 만들어보는 건 컴파일러 이론을 몸으로 익히는 최고의 방법인데, 표현식 언어 정도의 규모면 입문용으로 딱 적당하거든요.

정리하면

'안전하게 실행할 수 있는 작은 규칙 언어'라는 CEL의 생태계가 .NET까지 확장되고 있다는 이야기예요. 여러분은 사용자 정의 규칙이나 조건식 기능을 어떻게 구현하고 계세요? 직접 파서를 짜셨나요, 아니면 기존 라이브러리로 해결하셨나요?


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://bsid.io/writing/building-a-cel-engine-for-net
SHARE
처리 중...