PEP 752 – 패키지 저장소를 위한 암시적 네임스페이스
- Author:
- Ofek Lev <ofekmeister at gmail.com>, Jarek Potiuk <potiuk at apache.org>
- Sponsor:
- Barry Warsaw <barry at python.org>
- PEP-Delegate:
- Dustin Ingram <di at python.org>
- Discussions-To:
- Discourse thread
- Status:
- Accepted
- Type:
- Standards Track
- Topic:
- Packaging
- Created:
- 13-Aug-2024
- Post-History:
- 18-Aug-2024, 07-Sep-2024
- Resolution:
- 29-Jun-2026
Table of Contents
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 조직이 향후 업로드를 위해 패키지 이름 접두사를 예약하는 방법을 명시합니다.
“네임스페이스는 정말 훌륭한 아이디어입니다 – 더 많이 사용합시다!” - PEP 20
동기
현재 생태계에는 많은 패키지를 보유한 프로젝트가 검증된 소유권 패턴을 나타내고, 안전성과 브랜딩을 위해 네임스페이스를 완전히 통제하고자 하는 요구를 충족할 방법이 없습니다. 몇 가지 예는 다음과 같습니다.
- Amazon, Google, Microsoft와 같은 주요 클라우드 제공업체는 각 기능에 해당하는 패키지에 공통 접두사를 사용합니다 [1]. 예를 들어 Google의 패키지 대부분은
google-cloud-를 접두사로 사용하며, 가상 머신 사용을 위한 패키지는google-cloud-compute입니다. - OpenTelemetry는 핵심 API와 SDK를 위한 공식 패키지와 다양한 출처에서 데이터를 수집하기 위한 contrib 패키지를 제공하는 관측 가능성 오픈 표준입니다. 모든 패키지는
opentelemetry-를 접두사로 사용하며, 하위 접두사는opentelemetry-<component>-<name>-형식입니다. contrib 패키지는 중앙 저장소에 있으며 게시할 수 있는 유일한 패키지입니다. - Apache Airflow는 워크플로를 프로그래밍 방식으로 작성하고 예약하며 모니터링하는 플랫폼입니다. 여기에는 provider가 있으며, 각 provider 패키지는
apache-airflow-providers-를 접두사로 사용합니다. - Typeshed는 다양한 패키지의 타입 스텁을 유지 관리하는 커뮤니티 프로젝트입니다. 이들이 유지 관리하는 스텁 패키지는 대상 패키지의 이름을 따르며
types-를 접두사로 사용합니다. 예를 들어requests패키지에는 사용자가 의존할 수 있는types-requests라는 스텁이 있습니다. 비공식 스텁은types-접두사를 사용해서는 안 되며 대신-stubs접미사를 사용해야 합니다.
이러한 프로젝트는 이름 선점 공격에 특히 취약하며, 이는 궁극적으로 dependency confusion으로 이어질 수 있습니다.
예를 들어 모니터링이 유용할 새로운 제품이 출시되었다고 가정해 보겠습니다. Datadog가 결국 이를 공식 통합 기능으로 지원할 것이라고 가정하는 것은 합리적입니다. 로드맵 우선순위 지정과 구현에 필요한 시간 때문에 이러한 통합 기능을 제공하는 데는 상당한 시간이 걸립니다. 잠재적인 모든 패키지의 이름을 예약하는 것은 불가능하므로, 그동안 공격자가 합법적으로 보이는 패키지를 만들어 런타임에 악성 코드(비밀 정보 유출 등)를 실행할 수 있습니다. 사용자가 이러한 패키지를 설치할 가능성이 높아질 뿐만 아니라, 그렇게 하면 프로젝트 전체에 대한 인식도 훼손됩니다. Apache Airflow와 같은 커뮤니티 프로젝트도 이러한 일을 경험했습니다.
이 공격 벡터를 해결하려고 시도하지만, PEP 708은 의존성 해결 과정에서 여러 저장소를 고려하는 경우를 구체적으로 다루며 앞서 언급한 사용 사례를 전혀 보호하지 않습니다.
최근 몇 년 동안 typosquatting은 널리 사용되는 공격 벡터가 되었습니다 [2]. PyPI가 이에 대해 사용하는 현재 보호 기능은 유사한 문자를 정규화하는 것이지만, 이는 이러한 사용 사례에 충분하지 않습니다. 네임스페이스를 사용하면 타이포스쿼팅 발생을 크게 줄일 수 있습니다.
- 오탈자는 normalized 인 접두사 자체에 있어야 하며, 이는
aws-와 같이 짧고 잘 알려진 식별자일 가능성이 높습니다. - 색인은 네임스페이스를 신청하고 승인받도록 요구할 수 있으며, 이러한 이벤트를 악용한 오탈자 스쿼팅의 가능성을 줄입니다.
- 공격자는 네임스페이스를 포함하는 이름을 선점할 수 없습니다.
근거
다른 패키지 생태계에서는 일반적으로 하위 호환성을 최소화하거나 최대화하는 두 가지 접근 방식 중 하나를 취하여 이 문제를 해결해 왔습니다.
- NPM에는 scoped packages라는 개념이 있으며, 이는 사용 가능한 좋은 패키지 이름이 부족한 현상(실제 현상이든 인식된 현상이든)에 주로 대응하기 위해 introduced 되었습니다. 사용자나 조직이 가입하면 이름과 일치하는 스코프가 부여됩니다. 예를 들어 Google Cloud Storage를 사용하기 위한 package는
@google-cloud/storage이며, 여기서@google-cloud/는 스코프입니다. 일반 사용자 계정(조직이 아닌 계정)은 공개적으로 사용할 unscoped 패키지를 게시할 수 있습니다. 모든 설치 프로그램과 도구를 스코프를 처리하도록 수정해야 하므로, 이 접근 방식은 하위 호환성이 가장 낮습니다. - NuGet에는 package ID prefix reservation이라는 개념이 있으며, 이는 패키지가 어디에서 왔는지 알고자 하는 사용자의 요구를 주로 충족하기 위해 introduced 되었습니다. 패키지 이름의 접두사는 하나 이상의 소유자가 사용하도록 예약할 수 있습니다. 예약된 모든 패키지에는 이를 알리는 특별한 표시가 on its page에 있습니다. 예약 후에는 사용자가 해당 접두사의 소유자가 아닌 경우 예약된 접두사를 사용하는 모든 업로드가 실패합니다. 소유권이 있는 접두사를 가진 기존 패키지는 평소와 같이 계속 릴리스할 수 있습니다. 색인(예: PyPI)만 수정하면 되고 설치 프로그램은 변경할 필요가 없으므로, 이 접근 방식은 하위 호환성이 가장 높습니다.
이 PEP는 플랫 네임스페이스 전반에 걸친 NuGet 방식의 승인된 예약을 명시합니다. 새로운 패키지 구문이 필요한 모든 해결책은 기존 플랫 네임스페이스를 기반으로 구축되어야 하므로, 예약 메커니즘을 통해 획득하는 암시적 네임스페이스는 그러한 명시적 네임스페이스의 전제 조건이 됩니다.
기존 패키지 중 예약된 네임스페이스와 일치하는 패키지는 영향을 받지 않지만, 향후 무단 업로드를 방지하고 악의적인 사례에 전략적으로 PEP 541 삭제 요청을 적용하면 사용자에 대한 위험을 무시할 수 있는 수준으로 줄일 수 있습니다.
용어
이 문서에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”이라는 핵심 단어는 RFC 2119에 설명된 대로 해석해야 합니다.
- 소유자
- 소유자는 특정 패키지 이름을 업로드할 수 있는 주체입니다.
- 권한 부여
- 권한 부여는 패키지 저장소를 위한 네임스페이스 예약입니다.
- 상위 네임스페이스
- 네임스페이스의 상위 네임스페이스는 끝의 하이픈으로 연결된 구성 요소가 없는 네임스페이스를 의미합니다. 예를 들어
foo-bar의 상위 네임스페이스는foo입니다. - 하위 네임스페이스
- 네임스페이스의 하위 네임스페이스는 끝에 하이픈으로 연결된 구성 요소가 하나 추가된 네임스페이스를 의미합니다. 예를 들어
foo-bar는foo의 유효한 하위 네임스페이스입니다.
사양
이름 지정
네임스페이스는 valid 프로젝트 이름이어야 하며 내부적으로 normalized 상태여야 합니다. 예를 들어 foo.bar는 foo-bar가 됩니다.
의미 체계
네임스페이스 권한 부여는 다음 항목에 대한 소유권을 부여합니다.
- 네임스페이스 자체와 정확히 일치하는 프로젝트입니다.
- 네임스페이스 뒤에 하이픈이 이어지는 프로젝트입니다. 예를 들어 네임스페이스
foo는 정규화된 프로젝트 이름foo-bar와 일치하지만 프로젝트 이름foobar와는 일치하지 않습니다.
패키지 이름 일치는 normalized 네임스페이스를 대상으로 수행됩니다.
네임스페이스는 패키지 저장소별로 관리되며 저장소 간에 공유되어서는 안 됩니다. 예를 들어 PyPI에 회사 Acme가 소유한 acme 네임스페이스가 있는 경우, 다른 PyPI 비미러 저장소에서 제공되는 acme-로 시작하는 패키지에는 동일한 수준의 신뢰가 부여되지 않습니다.
권한 부여는 소유권이 중복되어서는 안 됩니다. 예를 들어 foo-bar에 대한 기존 권한 부여가 있다면 foo에 대한 새로운 권한 부여는 전자의 소유자만 받을 수 있습니다. 중복 여부는 제안된 normalized 네임스페이스와 기존 모든 루트 권한 부여의 정규화된 네임스페이스를 비교하여 결정합니다. 각 비교에서는 제안된 네임스페이스와 기존 네임스페이스의 끝에 하이픈을 추가해야 합니다. 기존 네임스페이스 중 하나라도 제안된 네임스페이스로 시작하면 중복으로 판단합니다.
저장소는 네임스페이스의 하이픈 수에 깊이 제한을 두어야 합니다. 예를 들어 깊이 제한이 1이면 네임스페이스 foo-bar는 허용되지만 foo-bar-baz에는 권한을 부여할 수 없습니다.
네임스페이스를 부여하고 관리하는 정책은 각 색인에 따라 다르므로 여기에서는 논의하지 않습니다. PyPI에 대해 제안된 네임스페이스 정책은 PEP 755에 설명되어 있습니다.
업로드
업로드되는 패키지의 이름이 예약된 네임스페이스와 일치하고 프로젝트 소유자에게 해당 네임스페이스에 대한 활성 권한 부여가 없는 경우, 업로드는 409 Conflict HTTP 상태 코드와 함께 실패해야 합니다.
저장소는 네임스페이스가 예약되기 전에 존재했던 프로젝트에 대해서는 이 규칙의 예외를 두어야 합니다.
저장소 메타데이터
JSON API 버전(JSON API)은 1.4에서 1.5로 증가합니다. 이 PEP를 지원하는 저장소는 다음 API 변경 사항을 구현해야 합니다. 이 PEP를 지원하지 않는 저장소는 API 사용자가 해당 저장소가 이 PEP를 지원하는지 확인할 수 있도록 이러한 변경 사항을 구현해서는 안 됩니다.
다음 API 변경 사항을 통해 설치 프로그램은 사용자에게 추가 security policies를 제공할 수 있습니다.
프로젝트 세부 정보
다음과 같이 project detail 응답이 수정됩니다.
프로젝트가 활성 네임스페이스 권한 부여와 일치하지 않으면 namespaces 키는 null이어야 합니다. 프로젝트가 네임스페이스 권한 부여와 일치하면 값은 일치하는 각 네임스페이스를 나타내는 매핑의 배열이어야 합니다. 모든 매핑에는 다음 키가 있어야 합니다.
네임스페이스 목록
이 URL의 형식은 /namespaces입니다.
응답은 예약된 각 네임스페이스를 나타내는 매핑의 배열이어야 합니다. 모든 매핑에는 정규화된 네임스페이스인 name 키가 반드시 있어야 합니다. 예를 들어 foo-bar입니다.
네임스페이스 세부 정보
이 URL의 형식은 <namespace>가 정규화된 네임스페이스인 /namespace/<namespace>입니다. 예를 들어 foo.bar 네임스페이스의 URL은 /namespace/foo-bar입니다.
응답은 다음 키를 가진 매핑이어야 합니다.
name: 네임스페이스의 정규화된 버전입니다. 예를 들어foo-bar입니다.parent: 존재하는 경우 상위 네임스페이스입니다. 예를 들어 네임스페이스가foo-bar이고foo에 활성 grant가 있으면 이 값은"foo"가 됩니다. 상위 네임스페이스가 없으면 이 키는null이 됩니다.children: 직접적인 하위 네임스페이스의 배열입니다. 예를 들어 네임스페이스가foo이고foo-bar및foo-bar-baz에 활성 grant가 있으면 이 값은["foo-bar"]가 됩니다.
매핑에는 네임스페이스의 현재 소유자를 가리키는 owner 키가 있을 수 있습니다.
Grant 제거
예약된 네임스페이스의 소유자가 없어지면 저장소는 API에서 namespaces 키를 null로 반드시 설정해야 합니다.
커뮤니티의 지지
다음 조직의 대표자들은 토론 링크와 함께 이 PEP에 대한 지지를 표명했습니다.
- Apache Airflow (확장된)
- pytest
- Typeshed
- Project Jupyter (확장된)
- Microsoft
- Sentry (다른 방식보다 NuGet 접근 방식을 지지하지만 현재 기능 부재로 부정적인 영향을 받지는 않습니다)
- DataDog
하위 호환성
프로젝트가 기존 명명 의미를 계속 사용하므로 본질적인 우려 사항은 없습니다. 사용자의 관점에서는 네임스페이스가 있는 프로젝트와 없는 프로젝트를 구별할 수 없습니다. 설치 프로그램은 수정할 필요가 없습니다.
또한 많은 프로젝트가 이미 typeshed has done 같은 접두사로 공유 목적을 나타내기로 선택했습니다.
보안 영향
설치 프로그램은 특정 네임스페이스 집합과 일치하고 소유자가 해당 네임스페이스에 대한 활성 승인을 보유한 패키지만 허용하는 보안 정책을 활성화하는 기능을 지원할 수 있습니다.
가르치는 방법
API가 반환하는 새로운 PyPUG documentation 에서 metadata를 설명하도록 문서를 업데이트할 예정입니다.
향후에는 설치 중에 네임스페이스를 활용하여 추가적인 보안 보장을 제공하는 도구도 언급할 수 있습니다.
참조 구현
이 PEP의 완전한 참조 구현은 PR #17691에서 확인할 수 있습니다.
거부된 아이디어
명시적인 비사용자 소유권
패키지 저장소는 평면 네임스페이스를 가지므로 모든 사용자가 네임스페이스를 예약하도록 허용하는 것은, contention for a finite resource 가 발생할 뿐 아니라 어떤 저장소도 임의의 수의 사용자를 심사할 충분한 인력을 보유하지 못하기 때문에 실행할 수 없습니다.
이 PEP의 이전 버전에서는 이러한 현실적인 고려 사항 때문에 organizations 만 네임스페이스를 예약할 수 있도록 제안했습니다. 그러나 조직이라는 개념이 명세화되지 않았고, 예상되는 PyPI 구현을 바탕으로 이러한 제한을 부과하는 것은 불필요하므로 이 제안은 거부되었습니다.
조직 범위 지정
이 PEP의 주요 동기는 의존성 혼동 공격을 줄이는 것이며, 기존 평면 네임스페이스를 허용하는 NPM 스타일의 범위 지정은 위험을 높이게 됩니다. 문서에서 사용자에게 foo 네임스페이스에 bar를 설치하도록 안내한다면, 사용자는 @foo/bar 를 설치하고 foo-bar는 설치하지 않도록, 또는 그 반대로 주의해야 합니다. Python 패키징 생태계에는 의사소통의 편의성을 극대화하기 위한 이름 정규화 규칙이 있으며, 이는 퇴보에 해당합니다.
Python의 런타임 환경 역시 범위 지정에 적합하지 않습니다. 동일한 JavaScript 패키지의 여러 버전이 공존할 수 있는 반면, Python은 하나의 전역 네임스페이스만 허용합니다. 언어 자체에 큰 변경을 가하지 않는 한 이를 변경하는 것은 거의 불가능합니다.
범위 지정은 시간이 지남에 따라 필연적으로 발생하는 조직 변경의 영향을 특히 크게 받습니다. 조직은 내부 개편, 인수 또는 그 밖의 이유로 이름을 변경할 수 있습니다. 이러한 일이 발생할 때마다 해당 조직이 소유한 모든 프로젝트의 이름이 사실상 변경되므로 사용자는 빈번하게 불필요한 혼란을 겪게 됩니다.
마지막으로, 모든 패키지 관리자, 보안 검사기, IDE 등을 업데이트해야 하므로 커뮤니티에 미치는 혼란은 막대할 것입니다. 범위 지정을 사용하여 출시된 새로운 패키지는 오래된 도구와 호환되지 않으며, 유지 관리자가 이러한 불만을 분류하고 처리해야 하는 부담과 함께 사용자에게 혼란을 초래할 것입니다.
아티팩트 수준 네임스페이스 연결
이 PEP의 이전 버전에서는 릴리스 시점에 개별 아티팩트에 메타데이터를 연결하도록 제안했습니다. 이는 특정 릴리스가 발생한 시점이 아니라 현재 부여된 권한을 기준으로 네임스페이스 권한 부여 보장이 프로젝트 수준에 적용될 것이라고 기대하는 사용자들에게 혼란을 일으킬 가능성이 있었기 때문에 거부되었습니다.
HTML Simple API 지원
Simple API의 HTML 버전에서 프로젝트 수준 메타데이터를 노출하는 방법은 두 가지 중 하나일 수 있습니다.
첫 번째 방법은 모든 프로젝트를 열거하는 /simple/페이지에 data-속성을 노출하는 것입니다. 이 방식에 대한 선례가 없으며, 설치 프로그램은 일반적으로 이 페이지를 사용하지 않습니다. 또한 이 페이지는 장기간( PyPI의 경우 24시간) 캐시되는 경우가 많습니다.
다른 방법은 모든 아티팩트에 data-속성을 추가하는 것입니다. 이는 거부된 artifact-level association 아이디어와 유사한 혼란을 일으킬 수 있으므로 차선책입니다. 또 다른 고려 사항은 실제로 많은 사설 색인이 CDN을 기반으로 클라우드 스토리지가 제공하는 정적 페이지로 구현된다는 점입니다. 이 시나리오에서는 네임스페이스가 변경될 때마다 일치하는 프로젝트의 모든 아티팩트를 대규모로 업데이트해야 합니다.
전용 패키지 저장소 장려
중요한 점은 이 방식이 프로젝트에 자체 인프라를 유지 관리해야 하는 부담을 준다는 것입니다. 이는 대다수 기업에 비현실적인 기대이며 커뮤니티 프로젝트에는 전혀 실행할 수 없는 방안입니다.
대부분의 패키지 관리자의 기본 동작이 PyPI를 사용하는 것이므로, 간단한 pip install을 실행하려는 사용자는 이미 악성 패키지에 취약할 수 있기 때문에 이는 대부분의 경우 도움이 되지 않습니다.
이론적으로 이러한 미래에는 모든 프로젝트가 의존성 해결에 자신의 저장소를 추가하는 방법을 문서화해야 하며, 이는 패키지 관리자마다 달라집니다. 특정 저장소에서 특정 의존성을 다운로드할 수 있는 패키지 관리자는 거의 없으며, 일반적인 경우 사용자가 장황한 설정을 사용해야 합니다.
이를 지원하지 않는 패키지 관리자는 대신 저장소를 순서대로 열거하여 주어진 패키지를 찾게 되므로 의존성 혼란이 발생합니다. 예를 들어 사용자가 두 개의 사용자 지정 저장소인 X와 Y에서 두 패키지를 가져오려고 한다고 가정하십시오. 각 저장소에 두 패키지가 모두 있지만 X에서는 하나가 악성이고 Y에서는 다른 하나가 악성이라면, 사용자는 악성 패키지를 마주치지 않고는 요구 사항을 충족할 수 없습니다.
개방형 네임스페이스
이 PEP의 이전 버전에서는 권한 부여의 소유자가 다른 사람들이 연결된 네임스페이스로 새 프로젝트를 릴리스하도록 허용할 수 있다고 제안했습니다. 이는 동기가 충분하지 않았고 저장소가 표준 권한 부여 의미 체계로 이러한 사용 사례를 기술적으로 충족할 수 있다는 사실 때문에 삭제되었습니다.
숨겨진 권한 부여
이 PEP의 이전 버전에서는 저장소가 공개적으로 표시되지 않으며 다른 사람들이 해당 네임스페이스를 차지하지 못하도록 하는 숨겨진 권한 부여를 생성할 수 있다고 제안했습니다. 이는 동기가 충분하지 않았기 때문에 삭제되었습니다.
출처 증명 어설션에 대한 전적인 의존
여기서의 아이디어 [3]는 클라이언트가 각각 사용자 지정 구문을 사용하여 의존성의 특정 속성을 검증하기 위한 출처 증명 어설션을 작성할 수 있는 범용 방식을 설계하는 것입니다. 몇 가지 예는 다음과 같습니다.
- 특정 조직 또는 사용자 이름으로 패키지가 업로드되었습니다. 예:
pip install "azure-loganalytics from microsoft" - 특정 도메인 이름의 소유자가 패키지를 업로드했습니다. 예:
pip install "google-cloud-compute from cloud.google.com" - 특정 이메일 주소를 가진 사용자가 패키지를 업로드했습니다. 예:
pip install "aws-cdk-lib from contact@amazon.com" - 네임스페이스와 일치하는 패키지는 권한이 있는 주체에 의해 업로드되었습니다(이 PEP).
근본적인 단점은 여러 저장소와 함께 사용할 때 원활하게 작동하지 않는다는 점입니다. 예를 들어 사용자가 azure-loganalytics 패키지를 원하며, 해당 패키지가 microsoft라는 조직에서 제공된 것인지 확인하려 한다고 가정하십시오. PyPI에서 Microsoft의 조직 이름이 microsoft라면, PyPI를 기본값으로 사용하는 패키지 관리자는 azure-loganalytics from microsoft를 허용할 수 있습니다. 그러나 의존성 해결에 여러 저장소를 사용하는 경우 사용자는 정의의 일부로 저장소를 지정해야 하는데, 이는 패키지 소유자 이름 확인 전용 섹션에서 설명한 이유로 현실적이지 않습니다.
이 접근 방식의 또 다른 일반적인 약점은 가장 일반적인 시나리오인 특수한 구문 없이 간단한 pip install을 수행하려는 사용자가 이미 악성 패키지에 취약해진다는 점입니다. 이를 극복하려면 일종의 기본 신뢰 메커니즘이 필요하며, 이는 모든 경우에 모든 도구에 특정한 UX 또는 리졸버 로직을 부과하게 됩니다.
예를 들어 패키지 관리자를 변경하여 패키지가 처음 설치될 때 사용자에게 출처 세부 정보를 표시하는 확인 메시지를 제공하도록 할 수 있습니다. 이는 특히 신규 사용자에게 매우 혼란스럽고 지나치게 많은 정보를 제공하게 되며, 기존 사용자에게는 UX를 깨뜨리는 변경이 됩니다. CI에서 실행하거나 요구 사항 파일에서 설치하는 것과 같이, 이 시나리오에서는 많은 설치 방법이 작동하지 않을 수 있으며 사용자는 잠재적으로 수백 개의 메시지를 받게 됩니다.
사용자에게 미치는 이러한 방해를 줄이는 한 가지 방법은 신뢰할 수 있는 세부 정보(조직/사용자 이름, 도메인 이름, 이메일 주소 등) 목록을 수동으로 유지 관리하는 것입니다. 이는 entry points 를 제공하는 패키지를 통해 검색 가능하게 만들 수 있으며, 패키지 관리자는 이를 감지하는 방법을 학습하고 기업 환경에서는 기본적으로 설치할 수 있습니다. 이 방법의 주요 단점은 자동 보장을 제공하지 않는다는 것이며, 이로 인해 영향을 받을 가능성이 더 높은 일반 사용자를 위한 유용성이 제한됩니다.
자동 보호를 제공하는 데 사용할 수 있는 두 가지 아이디어가 있으며, 이는 PEP 740 인증을 기반으로 하거나 메타데이터를 호스팅하는 서드파티 API를 활용하는 새로운 메커니즘을 기반으로 할 수 있습니다.
먼저 각 저장소는 적절하다고 판단하는 기준을 사용하여 패키지 소유자를 검증하는 서비스를 제공할 수 있습니다. 검증 후 저장소는 세부 정보를 전용 패키지에 추가하고, 해당 패키지는 기본적으로 설치됩니다.
이를 위해서는 전담 유지 관리가 필요하며, 현재의 PyPI를 포함한 대부분의 저장소에서는 현실적이지 않습니다. 도메인 이름과 같은 것을 위한 자원이 없는 커뮤니티 프로젝트가 어떻게 지원될 수 있을지는 분명하지 않습니다. 특히 여러 저장소가 있는 경우 각 저장소가 자체적인 검증 절차, 인증 기준 및 검증된 세부 정보를 포함하는 기본 패키지를 가질 수 있으므로, 이 해결책은 사용자에게 추가적인 혼란을 초래합니다. 의존성 해결 전에 모든 패키지 관리자가 각 저장소가 선택한 검증 패키지를 인지하고 이를 기본적으로 설치하도록 커뮤니티의 동의를 얻는 일은 어려울 것입니다.
디지털 인증이 선택된 메커니즘이 된다면, 사용자 지정 패키지 저장소에서 이를 구현하려면 상당한 작업이 필요하다는 단점이 있습니다. PyPI의 경우 Trusted Publishing에 대한 사전 작업과 이후의 PEP 740 implementation자체에 기업 후원자가 비용을 부담한 전일제 엔지니어 1년 상당의 시간이 소요되었습니다. 더 단순한 메커니즘으로 재현 가능한 빌드를 구현할 수 있으므로 다른 조직이 유사한 작업을 구현할 가능성은 낮습니다. 모든 것이 내부적으로 관리되는 경우 인증도 그다지 유용하지 않습니다. 커뮤니티 프로젝트는 필요한 인프라를 직접 유지 관리할 자원이 부족할 가능성이 높아 이 작업에 착수할 가능성이 낮으며, 더구나 전용 패키지 저장소를 장려하는 것 에는 상당한 단점이 있습니다.
다른 아이디어는 출처 주장을 외부에서 호스팅하고 더 많은 로직을 클라이언트 측으로 이동하는 것입니다. 가능한 구현 방식으로는 /provenance와 같은 지정된 상대 경로에서 호스팅할 수 있는 출처 API를 지정하는 방법이 있습니다. 그런 다음 각 저장소의 프로젝트를 특정 도메인을 가리키도록 구성할 수 있으며, 설치 중에 이 정보가 클라이언트로 전달됩니다.
이 분산 방식은 저장소에 부과되는 인프라 부담을 줄이지만, 보안 위험이 될 가능성이 있습니다. 외부 출처 증명 API가 손상되면 악성 패키지가 설치될 수 있습니다. 외부 API가 중단되면 패키지 설치가 실패하거나 패키지 관리자가 경고만 표시할 수 있으며, 이 경우 보안상의 이점이 없습니다.
또한 이러한 API를 유지 관리할 자원이 없는 커뮤니티 프로젝트에는 불리합니다. 많은 프로젝트가 문서에 사용하는 것과 같은 무료 호스팅 솔루션을 이용할 수 있지만, 기술적으로 인프라를 소유하지 않으므로 관대한 제공이 제한되면 손상될 수 있습니다.
마지막으로, 이 두 가지 이론적 접근 방식은 아직 규범적이지 않지만, 이미 rejected idea 로 거부된 아티팩트 수준의 주장을 암시합니다.
패키지 소유자 이름 주장
이는 패키지가 특정 조직 또는 사용자 이름에서 비롯되었다고 주장하는 것입니다. 기본 가정이 평면 네임스페이스라는 점을 제외하면 organization scoping 아이디어와 상당히 유사합니다.
이를 위해서는 지원되는 각 저장소의 JSON API를 수정해야 하며, 추가 메타데이터를 노출하거나 적절한 provenance assertions 로 구현할 수 있습니다.
조직 범위 지정 아이디어와 마찬가지로 microsoft::azure-loganalytics와 같은 새로운 syntax가 필요하며, 여기서 microsoft는 조직이고 azure-loganalytics는 패키지입니다. 기존의 평면 네임스페이스와 비교하면 잘 조화되지만, 필요한 변경 사항이 커뮤니티에 혼란을 초래한다는 중요한 단점은 그대로 유지됩니다.
한 가지 고유한 단점은 이름이 저장소의 구현 세부 사항이라는 점입니다. PyPI에서는 조직 이름과 사용자 이름이 서로 분리되어 있으므로 충돌이 발생할 가능성이 있습니다. 여러 저장소를 사용하는 경우, 사용자는 Encourage Dedicated Package Repositories 거부된 아이디어의 끝부분에 있는 사례와 유사한 의존성 혼동 사례를 겪을 수 있습니다.
이를 개선하기 위해, microsoft@pypi.org::azure-loganalytics와 같이 예상되는 저장소 URL도 포함하도록 구문을 확장하자는 제안이 나왔습니다. 이 구문 또는 이와 유사한 구문은 너무 장황하여 사용자 혼란을 일으킬 수 있으며, 전용 인프라를 유지 관리할 수 있는 사용자 사이에서 채택이 확대되면 더 나아가 불만을 초래할 수 있습니다(커뮤니티 프로젝트에는 도움이 되지 않습니다).
확장된 구문은 의존성 지정자 내에서 리졸버의 동작과 구성을 표준화하려는 시도입니다. 이는 도구의 UX를 의무화할 뿐만 아니라, 패키지 저장소라는 개념이 있든 없든 언어 생태계의 패키지 관리자에는 전례가 없습니다. 이러한 경우 리졸버 구성은 의존성 정의와 분리됩니다.
| 언어 | 도구 | 해결 동작 |
|---|---|---|
| Rust | Cargo | Cargo.toml내에서 [patch] 테이블을 사용하여 의존성
해결을 modified할 수 있습니다. |
| JS | Yarn | 이들은 (우리의 direct references URL 스킴과 유사한)
protocols 개념을 사용하지만, 사용자는 package.json
파일의 resolutions 필드를 구성합니다. |
| JS | npm | 사용자는 package.json 파일의 overrides 필드를 구성할
수 있습니다. |
| Ruby | Bundler | Gemfile에서는 젬에 대한 explicit source를 지정할
수 있습니다. |
| C# | NuGet | Directory.Packages.props 파일을 구성하여 override
package versions할 수 있습니다. |
| PHP | Composer | composer.json 파일에서는 특정 패키지에 대한
repository 소스를 지정할 수 있습니다. |
| Go | go | go.mod 파일에서는 replace 지시어를 지정할 수
있습니다. 이는 직접 의존성과 전이 의존성 모두에 사용된다는
점에 유의하십시오. |
고정 접두사 사용
여기서의 아이디어는 네임스페이스 예약에 사용되는 하나 이상의 최상위 고정 접두사를 두는 것입니다:
com-: 기업 조직용으로 예약됩니다.org-: 커뮤니티 조직용으로 예약됩니다.
그러면 조직은 조직 유형을 나타내는 접두사가 붙은 네임스페이스를 신청하게 됩니다.
프로젝트가 시작될 때는 사용자 기반이 네임스페이스 예약을 정당화할 만큼 충분히 커질지 알 수 없으므로 지속적인 혼란이 발생합니다. 그런 상황이 발생할 때마다 프로젝트 이름을 변경해야 하며, 이로 인해 프로젝트 유지 관리자에게 큰 유지 관리 부담이 생기고 프로젝트 패키지를 참조하는 새로운 방법을 배워야 하는 사용자에게 혼란이 발생합니다. 이로 인해 프로젝트가 네임스페이스를 전혀 예약하지 않게 될 가능성이 높습니다.
이 접근 방식의 또 다른 문제는 프로젝트에 브랜딩이 중요한 경우가 많아 (example) 패키지 이름을 변경하기를 꺼린다는 점입니다.
DNS 사용
여기서의 idea는 API의 프로젝트에 domain-authority라는 새 메타데이터 필드를 추가하는 것입니다. 리포지터리는 HTTPS를 통해 도메인을 확인하기 위한 새 엔드포인트를 지원하게 됩니다. 그러면 클라이언트는 특정 도메인을 허용하는 옵션을 지원하게 됩니다.
이는 패키지가 어디에서 제공되는지 확인하지 않는 대상 사용자에게는 문제를 해결하지 못하며, 이미 PEP 740에서 더 안전한 방식으로 지원되는 업로드 무결성 확인에 더 가깝습니다.
대부분의 프로젝트에는 도메인이 없으므로 이를 활용할 수 없으며, 도메인을 확보할 재정적 수단이 있는 조직을 부당하게 우대하게 됩니다.
미해결 문제
현재는 없습니다.
각주
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.