[Provisional] PEP 708 - Extending the Repository API to Mitigate Dependency Confusion Attacks
원문 링크: PEP 708 - Extending the Repository API to Mitigate Dependency Confusion Attacks
상태: Provisional 유형: Standards Track 작성일: 20-Feb-2023
PEP 708: 의존성 혼란 공격 완화를 위한 저장소 API 확장 번역 및 요약
요약 (Abstract)
의존성 혼란 공격(Dependency confusion attacks)은 사용자가 예상한 패키지 대신 악성 패키지가 설치되는 형태로, 점점 더 흔해지는 공급망 위협입니다. Python 의존성에 대한 대부분의 공격(최근 PyTorch 사건 포함)은 여러 패키지 저장소에서 발생하는데, 특정 저장소(예: 사용자 정의 인덱스)에서 올 것으로 예상되는 의존성이 다른 저장소(예: PyPI)에서 설치되는 경우입니다.
이 문제를 해결하기 위해 PEP 708은 Simple Repository API를 확장하여 저장소 운영자가 자신의 저장소에 있는 프로젝트가 다른 저장소의 프로젝트를 “추적(tracks)”하거나, 프로젝트가 여러 저장소에 걸쳐 네임스페이스를 확장할 수 있도록 제안합니다. 이러한 기능은 설치 프로그램이 특정 저장소 조합에서 제공되는 프로젝트가 예상된 것이고 허용되어야 하는 경우와 그렇지 않은 경우를 판단하여, 후자의 경우 사용자 보호를 위해 설치를 오류로 중단시킬 수 있게 합니다.
동기 (Motivation)
오랫동안 “의존성 혼란(dependency confusion)” 공격이라는 종류의 공격이 존재해왔는데, 이는 사용자가 패키지 A를 기대했지만 대신 패키지 B를 받게 되는 상황으로 요약할 수 있습니다. Python에서는 거의 항상 여러 저장소(PyPI 기본값 포함) 설정 때문에 발생합니다. 사용자가 저장소 X에서 패키지 A를 기대했지만, 누군가 저장소 Y에 동일한 이름으로 악성 패키지 B를 게시할 수 있기 때문입니다.
의존성 혼란 공격은 오래전부터 가능했지만, 최근 성공적으로 실행된 사례들이 공개되면서 주목받고 있습니다. 대표적인 예는 PyTorch 프로젝트의 내부 패키지인 torchtriton
사례입니다. 이 패키지는 https://download.pytorch.org/
에 있는 PyTorch 저장소에서만 설치되도록 의도되었지만, PyPI에 해당 이름이 등록되지 않아 공격자가 같은 이름을 사용하여 악성 버전을 게시할 수 있었습니다.
현재 이러한 공격을 완화하는 여러 방법이 있지만, 모두 최종 사용자가 스스로 보호하기 위해 추가적인 노력을 기울여야 하며, 기본적으로 보호되지 않습니다. 이는 대부분의 사용자가 이러한 공격 유형을 인지하더라도 여전히 취약한 상태로 남아있을 가능성이 높다는 것을 의미합니다.
궁극적으로 이러한 공격의 근본 원인은 모든 Python 패키지 이름이 나오는 전역적으로 고유한(globally unique) 네임스페이스가 없다는 사실에서 기인합니다. 대신 각 저장소는 자체적인 고유한 네임스페이스이며, spam
과 같은 “추상적인” 이름을 설치하도록 주어지면, 설치 프로그램은 암묵적으로 이를 pypi.org:spam
또는 example.com:spam
과 같은 “구체적인” 이름으로 변환해야 합니다. 현재 Python 설치 도구의 표준 동작은 이러한 여러 네임스페이스를 모든 네임스페이스의 파일을 포함하는 하나의 네임스페이스로 암묵적으로 통합하는 것입니다.
네임스페이스를 통합하는 것이 예상된 동작이라는 가정은, 다른 저장소에 있는 동일한 이름의 패키지가 서로 다른 당사자에 의해 작성될 때(예: torchtriton
사례), 의존성 혼란 공격이 가능해진다는 것을 의미합니다. 또한, 두 저장소를 하나의 네임스페이스로 병합하려는 유효한 사용 사례와 두 저장소를 별개의 네임스페이스로 처리하려는 유효한 사용 사례가 모두 존재하므로 “정답”이 없습니다. 따라서 설치 프로그램은 항상 병합하거나 절대 병합하지 않는 규칙 대신, 여러 저장소의 네임스페이스를 언제 병합하고 언제 병합하지 않아야 할지 결정할 수 있는 메커니즘이 필요합니다.
이 기능은 최종 사용자에게 직접 전달될 수도 있지만, 저장소 사양을 확장하여 저장소가 안전한 경우를 표시할 수 있게 함으로써, 개별 프로젝트와 저장소가 여러 별개의 네임스페이스에 걸쳐 자연스럽게 존재하더라도 “기본적으로 작동”할 수 있도록 하고, 설치 프로그램이 기본적으로 안전할 수 있는 능력을 유지할 수 있습니다.
이 PEP는 의존성 혼란 공격을 단독으로 해결하지는 않지만, 설치 프로그램이 유효하고 안전한 사용 사례에 과도한 피해를 주지 않으면서 공격을 방지할 수 있는 충분한 정보를 제공합니다.
이론적 근거 (Rationale)
이 PEP는 저장소 간 이름 병합에 대한 두 가지 광범위한 사용 사례를 가능하게 합니다.
-
다른 저장소에 정의된 이름을 확장하는 경우: 한 저장소가 자체 이름을 정의하지 않고, 다른 저장소에 정의된 이름을 확장하는 경우입니다. 이는 프로젝트가 한 저장소에서 다른 저장소로 미러링되거나(Bandersnatch 참조), 저장소가 특정 플랫폼에 대한 보조 아티팩트를 제공하는 경우(Piwheels 참조)에 흔히 발생합니다. 이 경우 확장되는 저장소나 프로젝트는 자신이 확장되고 있는지, 누구에 의해 확장되는지 알지 못할 수 있으므로, “확장하는” 저장소 자체에 존재하지 않는 정보에 의존할 수 없습니다.
-
프로젝트가 여러 저장소에 게시하는 경우: 프로젝트가 하나의 “주요” 저장소에 게시하지만, 추가 플랫폼, GPU, CPU 등을 위한 바이너리를 제공하는 추가 저장소를 갖는 경우입니다. 현재 Wheel 태그는 이러한 유형의 바이너리 호환성을 충분히 표현할 수 없으므로, 이를 사용하려는 프로젝트는 여러 저장소를 설정하고 사용자가 자신의 플랫폼, GPU, CPU 등에 맞는 올바른 바이너리를 얻기 위해 수동으로 구성하도록 해야 합니다. 이 사용 사례는 첫 번째와 유사하지만, 누가 정보를 제공하고 그들의 신뢰 수준이 어떤지에 대한 중요한 차이점이 있어 별개의 사용 사례가 됩니다.
사용자가 특정 저장소를 구성할 때(또는 기본값에 의존할 때) 어떤 저장소를 의미하는지에 대한 모호성은 없습니다. 저장소는 URL로 식별되며, 도메인 시스템을 통해 URL은 전역적으로 고유한 식별자입니다. 이러한 모호성 부족은 설치 프로그램이 저장소 운영자를 신뢰할 수 있고, 제공하는 메타데이터를 유효성 검사 없이 신뢰할 수 있다고 가정할 수 있음을 의미합니다.
반대로, 설치 프로그램이 여러 저장소에서 동일한 이름을 발견하면 어떤 저장소를 신뢰해야 하는지에 대한 모호성이 발생합니다. 이러한 모호성 때문에 설치 프로그램은 어느 저장소의 프로젝트 소유자도 신뢰할 수 있다고 가정할 수 없으며, 실제로 동일한 프로젝트인지, 또는 의존성 혼란 공격이 아닌지 유효성 검사를 해야 합니다.
설치 프로그램이 여러 저장소 간의 메타데이터를 검증할 방법이 없다면, 프로젝트는 이 사용 사례를 안전하게 지원하기 위해 저장소 운영자가 되어야 할 것입니다. 이는 나쁜 선택은 아니지만, 저장소가 프로젝트 소유자가 이 관계를 안전하게 표현할 수 있는 방법을 제공하지 않으면, 저장소 운영자의 메타데이터를 사용하도록 유도되어 원래의 불안정성이 재도입될 위험이 있습니다.
사양 (Specification)
이 사양은 Simple Repository API 버전 1.2의 변경 사항을 정의하며, 두 가지 새로운 메타데이터 항목인 “Repository ‘Tracks’” 및 “‘Alternate Locations’“를 추가합니다.
Repository “Tracks” Metadata (저장소 “추적” 메타데이터)
하나의 저장소가 다른 저장소에서 호스팅되는 프로젝트를 “확장”하기 위해, 확장하는 저장소는 특정 프로젝트가 다른 저장소 또는 여러 저장소의 프로젝트를 “추적”한다고 선언할 수 있습니다. 이는 확장하는 프로젝트 및 저장소의 URL을 추가함으로써 이루어집니다.
이는 JSON에서는 meta.tracks
키로, HTML에서는 프로젝트별 URL($root/$project/
)에 pypi:tracks
라는 meta
요소로 노출됩니다.
이 메타데이터를 사용할 때 반드시 유지되어야 할 몇 가지 중요한 속성이 있습니다:
- 이것은 저장소를 사용하는 개별 게시자가 아닌, 저장소 운영자 자신의 통제하에 있어야 합니다.
- “저장소 운영자”는 특정 저장소의 전체 네임스페이스를 관리하는 사람도 포함할 수 있습니다. 예를 들어, 한 엔티티가 소프트웨어를 운영하지만 다른 엔티티가 저장소의 전체 네임스페이스를 소유/관리하는 호스팅된 저장소 서비스와 같은 상황이 해당됩니다.
- 모든 URL은 확장하는 저장소의 프로젝트와 동일한 “프로젝트”를 나타내야 합니다.
- 이는 동일한 파일을 제공해야 한다는 의미는 아닙니다. 다른 플랫폼용으로 빌드된 바이너리, 로컬 패치가 적용된 복사본 등을 포함하는 것이 유효합니다. 이는 궁극적으로 사용자와 저장소 운영자가 “동일한” 프로젝트가 무엇을 구성하는지에 대한 기대에 달려 있으므로 의도적으로 모호하게 남겨두었습니다.
- 네임스페이스를 “소유”하는 저장소를 가리켜야 하며, 해당 네임스페이스를 추적하는 다른 저장소를 가리켜서는 안 됩니다.
- 정확히 동일한 이름(정규화 후)을 가진 프로젝트를 가리켜야 합니다.
- 확장된 저장소의 기본 URL이 아닌, 해당 프로젝트의 실제 URL을 가리켜야 합니다.
- 저장소의 모든 이름이 동일한 저장소를 추적하거나, 아예 어떤 저장소도 추적해야 하는 것은 아닙니다. 일부 이름은 저장소를 추적하고 일부 이름은 추적하지 않는 혼합 사용 저장소도 명시적으로 허용됩니다.
JSON 예시:
{
"meta": {
"api-version": "1.2",
"tracks": ["https://pypi.org/simple/holygrail/", "https://test.pypi.org/simple/holygrail/"]
},
"name": "holygrail",
"files": [
{
"filename": "holygrail-1.0.tar.gz",
"url": "https://example.com/files/holygrail-1.0.tar.gz",
"hashes": {"sha256": "...", "blake2b": "..."},
"requires-python": ">=3.7",
"yanked": "Had a vulnerability"
},
{
"filename": "holygrail-1.0-py3-none-any.whl",
"url": "https://example.com/files/holygrail-1.0-py3-none-any.whl",
"hashes": {"sha256": "...", "blake2b": "..."},
"requires-python": ">=3.7",
"dist-info-metadata": true
}
]
}
HTML 예시:
<!DOCTYPE html>
<html>
<head>
<meta name="pypi:repository-version" content="1.2">
<meta name="pypi:tracks" content="https://pypi.org/simple/holygrail/">
<meta name="pypi:tracks" content="https://test.pypi.org/simple/holygrail/">
</head>
<body>
<a href="https://example.com/files/holygrail-1.0.tar.gz#sha256=...">
<a href="https://example.com/files/holygrail-1.0-py3-none-any.whl#sha256=...">
</body>
</html>
“Alternate Locations” Metadata (“대체 위치” 메타데이터)
프로젝트가 여러 저장소에 걸쳐 네임스페이스를 확장할 수 있도록, 이 PEP는 프로젝트 소유자가 프로젝트의 “대체 위치(alternate locations)” 목록을 선언할 수 있도록 합니다. 이는 JSON에서는 alternate-locations
키로, HTML에서는 여러 번 사용될 수 있는 pypi-alternate-locations
라는 meta
요소로 노출됩니다.
이 메타데이터를 사용할 때 반드시 준수해야 할 몇 가지 중요한 속성이 있습니다:
- 이 메타데이터를 신뢰하려면, 해당 프로젝트가 발견되는 모든 위치 간에 대체 위치가 무엇인지에 대한 합의가 있어야 합니다.
- 대체 위치를 사용할 때, 클라이언트는 응답이 가져온 URL이 목록에 포함되어 있다고 암묵적으로 가정해야 합니다. 즉,
https://pypi.org/simple/foo/
에서 가져온 응답에["https://example.com/simple/foo/"]
라는alternate-locations
메타데이터가 있다면, 이를["https://example.com/simple/foo/", "https://pypi.org/simple/foo/"]
와 같이 처리해야 합니다. - 배열 내 요소의 순서는 특별한 의미를 가지지 않습니다.
설치 프로그램이 대체 위치 메타데이터를 사용하는 프로젝트를 발견하면, 명명된 모든 저장소가 여러 저장소에 걸쳐 동일한 네임스페이스를 확장한다고 간주해야 합니다.
참고: 이 대체 위치 메타데이터는 아티팩트 레벨 메타데이터가 아니라 프로젝트 레벨 메타데이터입니다. 즉, 핵심 메타데이터 사양의 일부로 포함되지 않으며, 각 저장소가 (지원하기로 선택한 경우) 구성 옵션을 제공해야 하는 사항입니다.
JSON 예시:
{
"meta": {
"api-version": "1.2"
},
"name": "holygrail",
"alternate-locations": ["https://pypi.org/simple/holygrail/", "https://test.pypi.org/simple/holygrail/"],
"files": [
{
"filename": "holygrail-1.0.tar.gz",
"url": "https://example.com/files/holygrail-1.0.tar.gz",
"hashes": {"sha256": "...", "blake2b": "..."},
"requires-python": ">=3.7",
"yanked": "Had a vulnerability"
},
{
"filename": "holygrail-1.0-py3-none-any.whl",
"url": "https://example.com/files/holygrail-1.0-py3-none-any.whl",
"hashes": {"sha256": "...", "blake2b": "..."},
"requires-python": ">=3.7",
"dist-info-metadata": true
}
]
}
HTML 예시:
<!DOCTYPE html>
<html>
<head>
<meta name="pypi:repository-version" content="1.2">
<meta name="pypi:alternate-locations" content="https://pypi.org/simple/holygrail/">
<meta name="pypi:alternate-locations" content="https://test.pypi.org/simple/holygrail/">
</head>
<body>
<a href="https://example.com/files/holygrail-1.0.tar.gz#sha256=...">
<a href="https://example.com/files/holygrail-1.0-py3-none-any.whl#sha256=...">
</body>
</html>
권고 사항 (Recommendations)
이 섹션은 규범적이지 않으며, 이 PEP가 사용자를 기본적으로 보호하고 기존 워크플로우의 중단을 최소화하는 최상의 절충안을 제공한다고 느끼는 메타데이터 해석 방법에 대한 권고를 설치 프로그램에 제공합니다. 이러한 권고는 구속력이 없으며, 설치 프로그램은 이를 무시하거나 특정 상황에 맞게 선택적으로 적용할 수 있습니다.
파일 발견 알고리즘 (File Discovery Algorithm)
현재 “표준” 파일 발견 알고리즘은 다음과 같습니다:
- 구성된 모든 저장소에서 모든 파일 목록을 생성합니다.
- 록파일(lockfile) 또는 요구사항 파일(requirements file)에서 알려진 해시와 일치하지 않는 파일을 필터링합니다.
- 현재 플랫폼, Python 버전 등과 일치하지 않는 파일을 필터링합니다.
- 해당 파일 목록을 리졸버(resolver)에 전달하여, 어떤 저장소에서 왔는지에 관계없이 해당 파일 중 “최적”의 일치를 해결하려고 시도합니다.
설치 프로그램은 새로운 메타데이터를 고려하도록 파일 발견 알고리즘을 변경하는 것이 권고되며, 대신 다음을 수행합니다:
- 구성된 모든 저장소에서 모든 파일 목록을 생성합니다.
- 록파일 또는 요구사항 파일에서 알려진 해시와 일치하지 않는 파일을 필터링합니다.
- 최종 사용자가 설치 프로그램에 특정 저장소에서 프로젝트를 가져오도록 명시적으로 지시했다면, 다른 모든 저장소를 필터링하고 5단계로 건너뜁니다.
- 발견된 파일이 여러 저장소에 걸쳐 있는지 확인합니다. 만약 그렇다면, “Tracks” 또는 “Alternate Locations” 메타데이터가 발견된 모든 저장소를 안전하게 병합할 수 있는지 확인합니다. 해당 메타데이터가 이를 허용하지 않는다면 오류를 생성하고, 그렇지 않으면 계속 진행합니다.
- 참고: 이는 원격 저장소에만 적용됩니다. 로컬 파일 시스템에 존재하는 저장소는 항상 모든 원격 저장소와 암묵적으로 병합될 수 있도록 허용되어야 합니다.
- 현재 플랫폼, Python 버전 등과 일치하지 않는 파일을 필터링합니다.
- 해당 파일 목록을 리졸버에 전달하여, 어떤 저장소에서 왔는지에 관계없이 해당 파일 중 “최적”의 일치를 해결하려고 시도합니다.
이 알고리즘은 설치 프로그램이 두 개의 이질적인 네임스페이스가 하나로 평면화될 수 있다고 가정하지 않도록 보장하며, 이는 실질적으로 모든 종류의 의존성 혼란 공격 가능성을 제거합니다.
최종 사용자를 위한 명시적 구성 (Explicit Configuration for End Users)
이 PEP는 설치 프로그램이 최종 사용자가 특정 패키지를 설치하려는 저장소를 정확히 구성할 수 있도록 하는 특정 메커니즘을 지시하거나 권장하지 않습니다. 그러나 설치 프로그램이 최종 사용자에게 해당 구성을 제공할 수 있는 메커니즘을 제공할 것을 권장합니다.
전달 방법 (How to Communicate This)
이 섹션은 변경 사항을 전달하기 위한 예시 “게시물”로 읽어야 합니다.
pip 사용자를 보호하고 이러한 유형의 공격으로부터 보호하기 위해, pip이 패키지를 설치하는 방법을 변경할 것입니다.
무엇이 변경됩니까? (What is Changing?)
pip이 동일한 프로젝트가 여러 원격 저장소에서 사용 가능하다고 감지하면, 기본적으로 오류를 생성하고 어떤 저장소에서 설치해야 할지 추측하는 대신 진행을 거부합니다. 여러 저장소에 기본적으로 게시하는 프로젝트에는 pip이 해당 저장소들을 함께 사용할 때 오류가 발생하지 않도록 저장소들을 안전하게 “연결”할 수 있는 기능이 제공됩니다. pip의 최종 사용자에게는 특정 프로젝트에 유효한 하나 이상의 저장소를 명시적으로 정의할 수 있는 기능이 제공되어, pip이 해당 프로젝트에 대해 해당 저장소만 고려하고 오류 생성을 완전히 피할 수 있습니다.
누가 영향을 받습니까? (Who is Affected?)
여러 원격(예: 로컬 파일 시스템에 없는) 저장소에서 설치하는 사용자는 다음과 같은 경우 pip이 성공적으로 설치하는 대신 오류를 발생시켜 영향을 받을 수 있습니다:
- 동일한 “이름”이 여러 원격 저장소에서 제공되는 프로젝트를 설치하는 경우.
- 여러 원격 저장소에서 사용 가능한 프로젝트 이름이 해당 저장소를 함께 연결하기 위해 정의된 메커니즘 중 하나를 사용하지 않은 경우.
- pip을 호출하는 사용자가 특정 프로젝트에 유효한 저장소를 명시적으로 제어하기 위해 정의된 메커니즘을 사용하지 않은 경우.
단일 원격 저장소만 사용하는 사용자(로컬 파일 시스템 “wheel house”를 사용하는 사용자 포함)는 전혀 영향을 받지 않습니다.
무엇을 해야 합니까? (What do I need to do?)
pip 사용자로서:
- 단일 원격 저장소만 사용하는 경우 아무것도 할 필요가 없습니다.
- 여러 원격 저장소를 사용하는 경우,
pip
호출에--use-feature=TBD
를 추가하여 새 동작을 선택하여 의존성 중 여러 원격 저장소에서 제공되는 것이 있는지 확인할 수 있습니다. - 이 동작이 기본값이 되면,
pip
호출에--use-deprecated=TBD
를 추가하여 일시적으로 선택 해제할 수 있습니다. - 공개 저장소에 호스팅되지 않는 프로젝트를 사용하지만 공개 저장소를 대체(fallback)로 사용하는 경우,
pip
을 저장소 파일로 구성하여 해당 의존성이 어디에서 와야 하는지 명시적으로 지정하는 것을 고려하여 공개 저장소에 해당 이름이 등록되어pip
이 오류를 발생시키는 것을 방지하십시오.
프로젝트 소유자로서:
- 프로젝트를 단일 저장소에만 게시하는 경우 아무것도 할 필요가 없습니다.
- 프로젝트를 여러 저장소에 동시에 사용하도록 의도된 경우, 최종 사용자의 문제 발생을 방지하기 위해 모든 저장소가 대체 저장소 메타데이터를 제공하도록 구성하십시오.
- 프로젝트를 단일 저장소에 게시하지만 다른 저장소와 함께 흔히 사용되는 경우, 제3자가 사용자
pip install
호출이 실패하는 것을 방지하기 위해 해당 저장소에 이름을 선제적으로 등록하는 것을 고려하십시오.
저장소 운영자로서:
- 개인 저장소의 경우, 사용자가 의존하는 공개 프로젝트를 자체 저장소로 미러링하고, 공개 프로젝트가 개인 프로젝트와 병합되지 않도록 주의하며, 사용자에게
--index-url
옵션을 사용하여 자신의 저장소만 사용하도록 지시하는 것을 권장합니다. - 공개 저장소의 경우, 프로젝트가 둘 이상의 저장소에서 사용 가능한 경우 프로젝트 소유자가 해당 프로젝트가 사용 가능한 저장소 목록을 구성할 수 있도록 대체 저장소 메커니즘을 구현하고 활성화해야 합니다.
- 다른 저장소를 “추적”하지만 특정 플랫폼용으로 빌드된 Wheel과 같은 보조 아티팩트를 제공하는 공개 저장소의 경우, 저장소에 대한 “tracks” 메타데이터를 구현해야 합니다. 그러나 이 정보는 저장소에 프로젝트를 게시하는 최종 사용자가 설정할 수 없어야 합니다.
기각된 아이디어 (Rejected Ideas)
이 PEP는 여러 가지 다른 아이디어들을 고려했으나 다음과 같은 이유로 기각되었습니다:
- 파일 목록이 동일한 경우 미러를 암묵적으로 허용: 정확히 동일한 복사본인 미러만 해결하며, 결국 일관성이 없는 분산 시스템에서 산발적인 실패를 초래할 수 있습니다.
- 저장소 순서를 지정하는 메커니즘 제공: 사용자들이 저장소 순서가 의미 없다고 15년 이상 교육받았기 때문에 되돌리기 어렵고, 암묵적 순서는 사용자의 의도와 다를 수 있으며, 잘못된 경우 사용자에게 아무런 피드백 없이 조용히 잘못된 것을 설치할 수 있습니다.
- 저장소 프록시에 의존: 사용자가 인프라를 유지하거나 옵트인해야 하며, 복잡한 요구사항에 대한 좋은 경험을 제공할 수 있지만, 대부분의 사용자가 단순히 안전하게 여러 저장소와 상호작용하기 위해 프록시를 설정하고 싶어하지 않을 것입니다.
- 해시 검사에만 의존: 사용자가 옵트인해야 하며 기본적으로 보호되지 않고, 사용자가 해시를 관리하는 데 많은 노력이 필요하며,
requirements.txt
파일을 사용하지 않는 경우 보호를 얻기 어렵습니다. - 모든 프로젝트가 “기본” 저장소에 존재하도록 요구:
--extra-index-url
의 범위를 좁히는 것은 사용자가 이해하기 어렵고, 기본 저장소에 등록되지 않은 프로젝트에 대한 대안을 제공하지 않으며, 이질적인 네임스페이스를 통합하는 근본적인 문제를 해결하지 못합니다. - 전역적으로 고유한 이름으로 이동: 전역적으로 고유하고 인간에게 의미 있는 이름을 생성하는 것은 거의 불가능하며, 수십 년 된 시스템에 이를 소급 적용하는 것은 현실적으로 어렵습니다.
- 설치 프로그램이 명시적 구성만 제공하도록 권고: 옵트인 방식이므로 평균 사용자를 보호하지 못하며, 모든 최종 사용자가 PyPI 미러와 같은 경우에도 동일한 문제를 반복적으로 해결해야 합니다.
- npm 방식의 스코프(Scopes) 도입: 스코프는 관련 프로젝트를 그룹화하고 특정 레지스트리에 이름을 할당하는 메커니즘을 제공하지만, npm.org와 같이 중앙화된 레지스트리가 일반적인 환경에서는 유용할 수 있으나, Python에서는 사용자가 자체 레지스트리를 사용하는 것이 장려되므로 이 문제의 근본적인 해결책은 아닙니다.
- “명시적 구성” 정의 및 표준화: 이 메커니즘은 각 설치 프로그램의 UX와 밀접하게 관련되어 있어 표준화를 강제하기 어려우며, 필요하다면 별도의 PEP로 다루는 것이 적절합니다.
저작권 (Copyright)
이 문서는 퍼블릭 도메인 또는 CC0-1.0-Universal 라이선스 중 더 관대한 조건으로 배포됩니다.
⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.
Comments