패키지 관리, 네임스페이스 설계, 어떻게 해야 할까?
플랫 네임스페이스(Flat Namespace)는 이름 충돌(Name Collision)과 타이포스쿼팅(Typosquatting)에 취약하며, 짧고 기억하기 쉬운 이름 사용의 장점을 가짐.
스코프 네임스페이스(Scoped Namespace)는 조직별 네임스페이스를 제공하여 충돌을 방지하지만, 기존 패키지와의 호환성 문제와 거버넌스(Governance) 문제를 야기함.
계층적 네임스페이스(Hierarchical Namespace)는 도메인 소유권을 기반으로 하지만, 긴 식별자와 도메인 만료에 따른 네임스페이스 하이재킹(Namespace Hijacking) 위험이 존재함.
URL 기반 네임스페이스(URL-based Namespace)는 고유성을 보장하지만, 호스팅 플랫폼 종속성 및 검색, 버전 관리 등의 부가 기능 구현의 어려움이 있음.
플랫 네임스페이스(Flat Namespace)의 근본적인 문제점
플랫 네임스페이스는 이름의 간결함과 접근성을 제공하지만, 이름 고갈(Name Exhaustion)과 타이포스쿼팅(Typosquatting)에 취약하다는 근본적인 문제점을 안고 있다. 특히, PyPI와 같이 패키지 수가 많은 경우, 짧고 직관적인 이름은 이미 사용 중인 경우가 많아 개발자는 대체재를 찾아야 한다. 또한, 타이포스쿼팅 공격은 사용자의 오타를 악용하여 악성 패키지를 설치하도록 유도하며, 이는 공급망 공격(Supply Chain Attack)의 주요 원인이 된다.
스코프 네임스페이스(Scoped Namespace)의 도입과 과제
npm은 스코프 네임스페이스(@org/name)를 도입하여 이름 충돌 문제를 해결하려 했지만, 기존 패키지와의 호환성 문제와 거버넌스(Governance) 문제를 야기했다. 스코프는 새로운 패키지나 조직 단위의 패키지 관리에 주로 사용되며, 기존의 플랫 네임스페이스를 대체하지 못했다. 또한, 스코프 소유권 이전 및 분쟁 해결을 위한 운영 부담(Operational Overhead)이 발생하며, 이는 스코프 네임스페이스의 확산을 저해하는 요인으로 작용한다.
계층적 네임스페이스(Hierarchical Namespace)의 한계
Maven Central은 reverse-domain naming 방식을 사용하여 도메인 소유권을 기반으로 네임스페이스를 관리하지만, 도메인 만료에 따른 네임스페이스 하이재킹(Namespace Hijacking) 위험이 존재한다. 만료된 도메인을 악의적인 사용자가 획득하여 기존 패키지를 위조할 수 있으며, 이는 의존성 혼란(Dependency Confusion)을 야기한다. 또한, 긴 식별자는 빌드 파일의 가독성을 저해하고, IDE 자동 완성 기능에 의존하게 만든다.
URL 기반 네임스페이스(URL-based Namespace)의 장단점
Go modules는 URL을 패키지 식별자로 사용하여 이름 충돌 문제를 해결하지만, 호스팅 플랫폼 종속성 문제를 야기한다. GitHub와 같은 플랫폼의 정책 변경이나 계정 삭제는 패키지 식별자를 변경해야 하는 상황을 초래한다. 또한, URL 기반 네임스페이스는 검색, 버전 관리, 중복 제거 등의 기능을 별도로 구현해야 하며, 이는 레지스트리(Registry)의 역할을 다시 수행하는 결과를 낳는다. Deno의 JSR은 이러한 문제점을 해결하기 위해 스코프 레지스트리를 구축했다.
crates.io의 네임스페이스 도입 시도와 과제
Rust의 crates.io는 플랫 네임스페이스에 네임스페이스를 추가하려는 시도를 하고 있으며, 이는 매우 어려운 과제임을 보여준다. 기존 crate 이름을 네임스페이스 루트로 사용하고, :: 구분자를 사용하여 Rust의 기존 구문과 일관성을 유지하려 한다. 하지만, 기존 crate 이름과의 충돌, 마이그레이션(Migration) 문제, 그리고 하위 호환성 유지를 위한 노력이 필요하다. 이는 네임스페이스 도입이 얼마나 어려운 문제인지 보여주는 사례이다.