SIG Store Ruby 개발 과정과 도전 과제

[EN] The Challenges of Building sigstore-ruby / Samuel Giddins @segiddins

작성자
RubyKaigi
발행일
2025년 05월 27일

핵심 요약

  • 1 Sig Store Ruby는 소프트웨어 공급망 보안을 위한 SIG store의 순수 Ruby 구현체입니다.
  • 2 이 프로젝트는 복잡한 암호화 프로토콜과 Ruby 생태계의 제약으로 인해 많은 기술적 난관에 부딪혔습니다.
  • 3 그럼에도 불구하고 성공적인 구현은 SIG store 사양의 정밀성을 높이고 향후 클라이언트 개발을 용이하게 할 것입니다.

도입

본 발표는 RubyKaigi에서 Samuel Giddens가 진행한 'Sig Store Ruby' 개발 경험에 대한 내용입니다. Samuel Giddens는 RubyGems, Bundler 및 RubyGems.org의 보안 리드이자 핵심 팀원으로서, SIG store Ruby 개발 및 유지보수를 담당하고 있습니다. 이 발표의 주요 목적은 소프트웨어 아티팩트의 출처를 암호학적으로 검증하는 SIG store 시스템을 순수 Ruby로 구현하는 과정에서 겪었던 기술적 난관과 이를 통해 얻은 교훈을 공유하는 것입니다. 특히 RubyGems.org의 젬 페이지 하단에 표시되는 'Provenance built and signed on GitHub actions'와 같은 정보를 제공하는 핵심 기능인 Sig Store Ruby의 중요성을 강조합니다.

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 클라이언트 개발은 더 쉬워질 것으로 예상됩니다.

결론

SIG store Ruby의 개발은 복잡한 암호화 시스템을 순수 Ruby로 구현하는 과정에서 수많은 기술적 도전과제를 극복해야 했습니다. RubyGems와 Bundler에 SIG store 검증 기능을 통합하기 위한 '순수 Ruby' 제약은 기존 라이브러리의 한계를 드러냈고, 개발자는 OpenSSL gem과 JRuby OpenSSL의 부족한 기능을 보완하기 위해 많은 프리미티브를 직접 구현해야 했습니다. 이러한 노력은 단지 하나의 라이브러리를 만드는 것을 넘어, SIG store 사양의 견고성과 이식성을 높이는 데 기여했습니다. SIG store 커뮤니티가 프로토타입 단계를 넘어 생산 시스템으로 성숙해감에 따라, 향후 SIG store 클라이언트 개발은 더 쉬워질 것입니다. Samuel Giddens는 이러한 경험을 통해 얻은 교훈을 바탕으로 Ruby 환경에서 SIG store 구현이 더욱 용이해지기를 바라며, SIG store Ruby 프로젝트에 대한 지속적인 관심과 기여를 독려합니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!