SIG store는 소프트웨어 젬이 어떤 커밋에서 빌드되었고, 어떤 저장소에서 나왔으며, 어떤 CI 시스템에서 언제 빌드되었는지 등 아티팩트의 출처를 암호학적으로 검증 가능하게 하여 소프트웨어 안전성을 확보하는 것을 목표로 합니다. 이러한 SIG store 클라이언트를 처음부터 작성하는 것은 근본적인 암호화 프로토콜의 복잡성, 다양한 서비스와의 통합, 그리고 광범위한 보안 문제 처리로 인해 매우 어렵습니다. Chat GPT조차도 SIG store 프로토콜의 복잡성, 방대한 암호화 기초 지식, 다양한 서비스 인터페이스, 보안 구성, API 설계, 테스트 및 디버깅 등 모든 측면이 어렵다고 답변할 정도입니다.
순수 Ruby로 SIG store를 구현하는 것은 추가적인 도전 과제를 안겨주었습니다. ‘순수 Ruby’의 정의는 ISO Ruby, Mini Ruby, 표준 라이브러리만 사용하는 Ruby, JRuby, TruffleRuby 등 다양하게 해석될 수 있으며, 결국 MRI(Ruby 3.2 이상), JRuby, TruffleRuby의 최신 버전을 모두 지원해야 한다는 의미로 귀결됩니다. 이는 RubyGems 및 Bundler의 벤더링 목표와도 일치합니다. 그러나 Ruby 생태계의 많은 산업 표준 라이브러리가 C로 작성되어 있고, Ruby 표준 라이브러리 프리미티브 역시 대부분 네이티브 코드로 구현되어 있어 ‘순수 Ruby’ 구현은 임피던스 불일치와 여러 래퍼 계층을 다뤄야 하는 어려움을 야기합니다. 또한, 오래된 Ruby 버전과 다양한 구현체를 지원해야 하므로 의존할 수 있는 범위가 매우 제한적입니다.
초기에는 Rust 라이브러리를 래핑하는 방안이 제안되었으나, RubyGems 내부에 포함되어야 하는 특성상 네이티브 코드 컴파일 의존성은 허용되지 않았습니다. Rust 코드가 Java와 C 환경을 모두 다뤄야 하는 복잡성, Ruby 릴리스와 독립적으로 Sig Store Ruby를 업데이트해야 하는 필요성, 그리고 다양한 Ruby 플랫폼 지원의 어려움 때문에 Rust 래핑은 적절한 해결책이 아니었습니다. 결국, Samuel Giddens는 순수 Ruby 구현을 선택했습니다.
SIG store Ruby는 작년 2월에 첫 코드가 작성되어 10월에 첫 릴리스를 거쳐 11월에 프로덕션에 사용되기 시작했습니다. 이 짧은 라이브러리를 개발하는 데 상당한 시간이 소요된 이유는 SIG store 검증 흐름이 광범위한 작업을 포함하기 때문입니다. 여기에는 TUF(The Update Framework) 처리, SIG store 번들 JSON 파일 읽기 및 유효성 검사, 아티팩트 해싱, 신뢰할 수 있는 시간 소스 설정, X.509 경로 유효성 검사, SCT 유효성 검사, 투명성 로그 포함 여부 확인, 정책 기반 인증서 유효성 검사, 서명 유효성 검사, 그리고 번들 페이로드와 정책 간의 일관성 확인 등 13단계의 복잡한 과정이 포함됩니다.
이러한 과정을 구현하기 위해서는 다양한 핵심 프리미티브가 필요했습니다. Google의 Protocol Buffers(JSON 인코딩), RSA, EC DSA, ED25519와 같은 다양한 암호화 서명 알고리즘, X.509 서명 인증서, RFC 3161 SCT, Go의 Signed Note 형식, 머클 트리, 두 가지 JSON 정규화 형식, OpenID Connect 신원을 나타내는 JWT, 키 생성, 서명 생성, 그리고 Rekor 및 Fulcio와 같은 SIG store 서비스와의 통신을 위한 HTTP 클라이언트 등이 그것입니다. 불행히도 Ruby 표준 라이브러리에서는 OpenSSL gem과 JSON 모듈 정도만이 유일하게 사용 가능했습니다.
OpenSSL gem은 ED25519 지원 부족, 특정 X.509 인증서 속성 쿼리, SCT 유효성 검사, RFC 3161 유효성 검사 기능 등 필요한 기능이 누락되어 있었습니다. JRuby OpenSSL은 Bouncy Castle 기반으로, X.509 경로 유효성 검사 버그, ED25519 미지원 등 더욱 많은 기능이 부족했습니다. 특히 JRuby에서는 Java.security
API를 직접 사용하여 누락된 기능을 재구현해야 했습니다.
결과적으로 Sig Store Ruby 자체적으로 X.509 래퍼, RFC 8785 JSON 정규화, X.509 인증서의 ASN.1 바이트 수동 처리, SCT 및 RFC 3161 지원, DESI(Dead Simple Security Envelopes), 그리고 TUF 클라이언트(두 번째 JSON 정규화 포함) 등 많은 부분을 직접 구현해야 했습니다. 이러한 복잡성은 SIG store가 PKI를 위한 X.509, 신뢰할 수 있는 자료 배포를 위한 TUF, 투명성 로그 포함을 위한 머클 트리, 체크포인트를 위한 Signotes 등 여러 독립적인 시스템의 조합이기 때문입니다. 이러한 모든 요소에 대한 라이브러리가 다른 언어 생태계(예: Go)에서는 잘 갖춰져 있지만, Ruby에서는 그렇지 않으며, 특히 표준 라이브러리에는 거의 존재하지 않습니다.
그럼에도 불구하고, 이러한 재구현 노력은 중요한 의미를 가집니다. 이는 다른 구현체에서 발견될 수 있는 버그의 영향을 완화하고, SIG store 사양을 더욱 정밀하고 이식 가능하게 만드는 데 기여합니다. 각 새로운 구현은 다른 엣지 케이스를 발견하고, 사양에 대해 새로운 관점을 제공합니다. 2024년에는 다수의 적합성 테스트 스위트, 잘 정리된 SIG store 클라이언트 관련 자료, 그리고 구현체 간의 컨버전스 덕분에 다음 SIG store 클라이언트 개발은 더 쉬워질 것으로 예상됩니다.