PEP 710 – 설치된 패키지의 출처 기록하기
- Author:
- Fridolín Pokorný <fridolin.pokorny at gmail.com>
- Sponsor:
- Donald Stufft <donald at stufft.io>
- PEP-Delegate:
- Paul Moore <p.f.moore at gmail.com>
- Discussions-To:
- Discourse thread
- Status:
- Draft
- Type:
- Standards Track
- Topic:
- Packaging
- Created:
- 27-Mar-2023
- Post-History:
- 03-Dec-2021, 30-Jan-2023, 14-Mar-2023, 03-Apr-2023
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 설치된 Python 배포의 출처(provenance)를 기록하는 방법을 설명합니다. 이 기록은 설치 프로그램이 생성하며, .dist-info 디렉터리에 있는 JSON 파일 provenance_url.json 형태로 사용자에게 제공됩니다. 이 JSON 파일은 설치된 배포판의 해시와 함께 distribution package의 URL을 기록할 수 있도록 추가 메타데이터를 담습니다. 이 제안은 PEP 610을 기반으로 그에 해당하는 표준 PyPA 명세를 따르며, 패키지를 이름으로(그리고 선택적으로 버전으로) 식별하는 경우를 위해 provenance_url.json으로 direct_url.json을 보완합니다.
동기
Python Project를 설치하려면 Package Index에서 Distribution Package를 내려받아 그 내용을 적절한 위치에 압축 해제해야 합니다. 설치 과정이 끝나면 사용된 릴리스 아티팩트와 그 출처에 대한 정보는 일반적으로 사라집니다. 그러나 패키지 설치에 사용된 배포판과 그 출처를 기록해 두어야 하는 사용 사례가 있습니다.
Python 휠은 서로 다른 컴파일러 플래그로 빌드되거나 서로 다른 휠 태그를 지원할 수 있습니다. 두 경우 모두 설치 프로그램이 (서로 다른 패키지 색인에서 온 것일 수도 있는) 여러 휠을 후보로 고려하는 상황이 생길 수 있으며, 이때 설치 중에 실제로 어떤 wheel 파일이 사용되었는지 바로 알 수 있다면 도움이 됩니다. 그러면 개발자는 휠에 대한 정보를 활용해 원하는 휠이 실제로 설치되었는지 확인하면서 문제를 디버깅할 수 있습니다. 또 다른 사용 사례로는 SBOM(Software Bill of Materials, 소프트웨어 자재 명세서)을 보고하는 도구처럼 설치된 소프트웨어를 보고하는 도구가 있으며, 이러한 도구는 더 정확한 보고서를 제공할 수 있습니다. 또 다른 사용 사례로, 설치된 각 패키지를 Python 패키지 색인에서 가져온 특정 배포 아티팩트에 고정하여 Python 환경을 재구성할 수도 있습니다.
근거
이 PEP에서 설명하는 동기는 설치된 배포판의 직접 URL 출처 기록 명세를 확장한 것입니다. 직접 URL로 설치된 패키지의 출처 정보를 기록하는 것과 더불어, 설치 프로그램은 Python 패키지 색인에서 이름(그리고 선택적으로 버전)으로 설치된 패키지의 출처 정보도 기록해야 합니다.
이 PEP에서 설명하는 아이디어는 컨테이너 환경에 배포 패키지를 설치하는 데 사용되는 micropipenv라는 도구에서 비롯되었습니다(보고된 이슈 thoth-station/micropipenv#206을 참조하십시오). 현재 조립된 컨테이너화 애플리케이션은 설치된 배포 패키지의 출처에 대한 정보를 암묵적으로 담고 있지 않습니다(전체 URL로 설치되어 direct_url.json에 기록된 경우는 예외입니다). 이 때문에 컨테이너 환경에 있는 소프트웨어를 감사해야 하는 경우, 컨테이너 이미지 공급자는 요구 사항 파일을 확인할 수 있도록 컨테이너 이미지를 해당 빌드 과정과 그 구성, 애플리케이션 소스 코드에 연결해야 합니다.
Discourse 스레드에서 이어진 논의에서는 설치 과정에 대한 상세한 JSON 보고서를 생성할 수 있는 pip의 새로운 --report 옵션도 언급되었습니다. 이 옵션은 이 PEP가 다루는 출처 문제를 해결하는 데 도움이 될 수 있습니다. 그러나 출처 정보를 얻으려면 이 옵션을 pip에 명시적으로 전달해야 하며, 이 옵션은 출처 확인에는 필요하지 않을 수 있는 추가 메타데이터(예: 각 배포 패키지의 Python 버전 요구 사항)도 함께 포함합니다. 또한 이 PEP를 작성하는 시점에서 이 옵션은 pip에만 있습니다.
현재의 설치된 패키지 기록 명세는 설치된 파일을 기록하는 RECORD 파일을 정의하지만, 그 파일들을 얻어 온 배포 아티팩트는 기록하지 않는다는 점에 유의하십시오. RECORD 파일에 나열된 항목을 대조하여 설치된 아티팩트를 감사할 수 있습니다. 그러나 이 기법을 쓰려면 각 아티팩트가 제공하는 파일을 미리 계산해 둔 데이터베이스가 있거나 실제 아티팩트 내용과 비교해야 합니다. 두 방법 모두 비교적 비용이 크고 시간이 많이 드는 작업이며, 제안된 provenance_url.json 파일을 사용하면 이러한 작업을 없앨 수 있습니다.
직접 URL로 얻은 배포 패키지와 색인에서 이름/버전으로 얻은 배포 패키지 모두에 대해 출처 정보를 기록하면, 앞서 언급한 컨테이너화된 애플리케이션이라는 특정 사용 사례를 넘어 Python 환경 전반의 감사를 단순화할 수 있습니다. 커뮤니티 프로젝트인 pip-audit는 pypa/pip-audit#170에서 관심을 표명했습니다.
명세
이 문서의 “MUST”, “MUST NOT”, “REQUIRED”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 키워드는 RFC 2119에 기술된 대로 해석합니다.
설치 프로그램은 이름으로(그리고 선택적으로 Version Specifier로) 지정된 Distribution Package를 설치할 때 .dist-info 디렉터리에 provenance_url.json 파일을 생성해야 합니다(SHOULD).
직접 URL 참조(VCS URL 포함)를 지정하는 요구 사항으로부터 배포 패키지를 설치할 때는 이 파일을 생성해서는 안 됩니다(MUST NOT).
주어진 .dist-info 디렉터리에는 provenance_url.json 파일과 direct_url.json 파일(설치된 배포의 직접 URL 출처 기록 명세 및 이에 대응하는 직접 URL 데이터 구조 명세에서 정의) 중 하나만 존재할 수 있습니다. 설치 프로그램은 두 파일을 모두 추가해서는 안 됩니다(MUST NOT).
provenance_url.json JSON 파일은 RFC 8259를 준수하고 UTF-8로 인코딩된 딕셔너리여야 합니다(MUST).
파일이 존재한다면 정확히 두 개의 키를 포함해야 합니다(MUST). 첫 번째 키는 string 타입의 url이어야 합니다(MUST). 두 번째 키는 아래에 정의된 값을 갖는 archive_info여야 합니다(MUST).
url 키의 값은 배포 패키지를 다운로드한 URL이어야 합니다(MUST). 휠이 소스 배포판으로부터 빌드된 경우, url 값은 반드시(MUST) 그 소스 배포판을 내려받은 URL이어야 합니다. 휠을 직접 다운로드하여 설치한 경우, url 필드는 휠을 다운로드한 URL이어야 합니다(MUST). 직접 URL 데이터 구조 명세에서와 마찬가지로, 보안상의 이유로 url 값에서는 민감한 인증 정보를 모두 제거해야 합니다(MUST).
그러나 URL의 user:password 부분은 다음 정규 표현식과 일치하는 환경 변수로 구성될 수 있습니다(MAY):
\$\{[A-Za-z0-9-_]+\}(:\$\{[A-Za-z0-9-_]+\})?
또한 URL의 user:password 부분은 잘 알려져 있고 보안상 민감하지 않은 문자열일 수 있습니다(MAY). 대표적인 예는 ssh://git@gitlab.com 같은 URL에서의 git입니다.
archive_info의 값은 단일 키 hashes를 갖는 딕셔너리여야 합니다(MUST). hashes의 값은 해시 함수 이름을 url 값이 참조하는 파일의 16진수 인코딩 다이제스트에 매핑하는 딕셔너리입니다. 최소 하나의 해시를 기록해야 합니다(MUST). 여러 해시를 포함할 수 있으며(MAY), 여러 해시를 어떻게 처리할지는 소비자가 결정합니다(모두 검증하거나, 일부만 검증하거나, 전혀 검증하지 않을 수도 있습니다).
각 해시는 hashlib.algorithms_guaranteed가 제공하는 단일 인자 해시 중 하나여야 하며(MUST), 사용해서는 안 되는(MUST NOT) sha1과 md5는 제외합니다. Python 3.11 기준으로, 다중 인자인 shake_128과 shake_256을 제외하면 허용되는 해시 집합은 다음과 같습니다:
>>> import hashlib
>>> sorted(hashlib.algorithms_guaranteed - {"shake_128", "shake_256", "sha1", "md5"})
['blake2b', 'blake2s', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512', 'sha512']
각 해시는 해시의 정식 이름으로, 항상 소문자로 참조해야 합니다(MUST).
sha1 해시와 md5 해시는 해당 해시 알고리즘의 보안상 한계 때문에 존재해서는 안 됩니다(MUST NOT). 반대로, sha256 해시는 포함해야 합니다(SHOULD).
패키지 색인에서 가져온 배포 패키지를 캐시하는 설치 프로그램은 캐시된 배포 아티팩트와 관련된 정보를 보관하여, 설치 프로그램의 캐시에서 배포 패키지를 설치할 때에도 provenance_url.json 파일을 생성할 수 있도록 해야 합니다(SHOULD).
하위 호환성
Recording installed projects 명세에 따라, 설치 프로그램은 .dist-info 디렉터리에 설치 프로그램 고유의 추가 파일을 보관할 수 있습니다. 이 PEP가 하위 호환성 문제를 일으키지 않도록 설치 프로그램 및 라이브러리에 대한 포괄적인 조사를 수행한 결과, 비슷한 이름의 파일을 사용하는 현재 도구나 기타 주요한 실현 가능성 문제는 발견되지 않았습니다.
휠 명세는 .dist-info 디렉터리에 존재할 수 있는 파일들을 나열합니다. 이 파일 이름 중 어느 것도 이 PEP에서 제안하는 provenance_url.json 파일과 충돌하지 않습니다.
설치 프로그램 및 라이브러리에서의 provenance_url.json 존재 여부
Python 생태계의 기존 설치 프로그램, 라이브러리, 의존성 관리자를 포괄적으로 조사하여 각 도구에 provenance_url.json 지원을 추가할 때의 영향을 분석했습니다. 요약하면, 이 PEP를 작성하는 시점까지 중대한 하위 호환성 문제나 충돌, 실현 가능성을 가로막는 요인은 발견되지 않았습니다. 조사에 대한 자세한 내용은 Appendix: Survey of installers and libraries 절에서 확인할 수 있습니다.
direct_url.json과의 호환성
이 제안은 PEP 610과 이에 대응하는 정식 PyPA 명세에 기술된 direct_url.json 파일을 전혀 변경하지 않습니다.
provenance_url.json 파일의 내용은, 직접 URL이 소스 아카이브나 휠을 가리킬 때 설치 프로그램이 결국 direct_url.json을 지원하는 로직의 일부를 재사용할 수 있도록 설계되었습니다.
provenance_url.json 파일과 direct_url.json 파일의 주된 차이점은 provenance_url.json 파일에 있는 필수 키와 그 값입니다. 이를 통해 .dist-info 디렉터리에 파일이 있는 경우 provenance_url.json 파일을 사용하는 쪽에서 그 내용을 신뢰할 수 있습니다.
보안 영향
provenance_url.json 파일의 주요 보안 기능 중 하나는 Python 환경에 설치된 아티팩트를 감사할 수 있다는 점입니다. 도구는 Python 배포 패키지를 설치하는 데 어떤 Python 패키지 색인이 사용되었는지와 해당 릴리스 아티팩트의 해시 다이제스트를 확인할 수 있습니다.
예로 PyTorch 사건에서 최근 발생한 의존성 체인 침해를 들 수 있습니다. PyTorch 색인은 torchtriton이라는 패키지를 제공했습니다. 공격자는 PyPI에 torchtriton을 게시했고, 이 패키지는 악성 바이너리를 실행했습니다. 도구는 provenance_url.json 파일에 기재된, 설치된 Python 배포의 URL을 확인하여 설치된 Python 배포의 출처를 자동으로 검사할 수 있습니다. PyTorch 사건의 경우 torchtriton의 URL은 PyPI가 아니라 PyTorch 색인을 가리켜야 합니다. 도구는 설치된 Python 배포의 URL을 확인하여 이처럼 설치된 악성 Python 배포를 식별하는 데 도움을 줄 수 있습니다. 더 정확하게 검사하려면 provenance_url.json 파일에 기재된, 설치된 Python 배포의 해시도 함께 확인할 수 있습니다. 이러한 해시 검사는 소스 URL만으로는 Python 배포를 구별할 수 없는 미러링된 Python 패키지 색인에서 원하는 Python 패키지 배포만 설치되도록 보장하는 데 도움이 될 수 있습니다.
악의적인 행위자는 설치된 Python 배포의 출처 정보를 숨기기 위해 provenance_url.json의 내용을 의도적으로 조작할 수 있습니다. 이러한 악의적인 활동을 밝혀내는 보안 검사는 파일 시스템에서 일어나는 작업을 모니터링하고 궁극적으로 사용자 권한이나 파일 권한까지 검토해야 하므로 이 PEP의 범위를 벗어납니다.
교육 방법
provenance_url.json 메타데이터 파일은 도구를 위한 것이며 최종 사용자에게 직접 보이지 않습니다.
예시
유효한 provenance_url.json 예시
여러 해시를 나열하는 유효한 provenance_url.json:
{
"archive_info": {
"hashes": {
"blake2s": "fffeaf3d0bd71dc960ca2113af890a2f2198f2466f8cd58ce4b77c1fc54601ff",
"sha256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f",
"sha3_256": "c856930e0f707266d30e5b48c667a843d45e79bb30473c464e92dfa158285eab",
"sha512": "6bad5536c30a0b2d5905318a1592948929fbac9baf3bcf2e7faeaf90f445f82bc2b656d0a89070d8a6a9395761f4793c83187bd640c64b2656a112b5be41f73d"
}
},
"url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"
}
해시 항목 하나를 나열하는 유효한 provenance_url.json:
{
"archive_info": {
"hashes": {
"sha256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f"
}
},
"url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"
}
휠을 빌드하고 설치하는 데 사용된 소스 배포판을 기재한 유효한 provenance_url.json의 예는 다음과 같습니다:
{
"archive_info": {
"hashes": {
"sha256": "8bfe29f17c10e2f2e619de8033a07a224058d96b3bfe2ed61777596f7ffd7fa9"
}
},
"url": "https://files.pythonhosted.org/packages/1d/43/ad8ae671de795ec2eafd86515ef9842ab68455009d864c058d0c3dcf680d/micropipenv-0.0.1.tar.gz"
}
유효하지 않은 provenance_url.json 예시
다음 예는 Recording the Direct URL Origin of installed distributions에 문서화된 자료 구조에서 원래 설계된 대로 archive_info 딕셔너리에 hash 키를 포함합니다. hashes와 혼동될 가능성을 막고 해시 값을 동기화하는 데 필요한 추가 검사를 피하기 위해 hash 키는 존재해서는 안 됩니다(MUST NOT).
{
"archive_info": {
"hash": "sha256=236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f",
"hashes": {
"sha256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f"
}
},
"url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"
}
또 다른 예시는 유효하지 않은 해시 이름을 보여 줍니다. 참조된 해시 이름은 이 PEP와 Python 문서의 hashlib.hash.name에 설명된 정식 해시 이름에 해당하지 않습니다.
{
"archive_info": {
"hashes": {
"SHA-256": "236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f"
}
},
"url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"
}
마지막 예시는 다운로드한 아티팩트에 사용할 수 있는 해시가 없는 provenance_url.json 파일을 보여 줍니다:
{
"archive_info": {
"hashes": {}
}
"url": "https://files.pythonhosted.org/packages/07/51/2c0959c5adf988c44d9e1e0d940f5b074516ecc87e96b1af25f59de9ba38/pip-23.0.1-py3-none-any.whl"
}
pip 명령 예시와 이 명령들이 provenance_url.json 및 direct_url.json에 미치는 영향
이 명령들은 direct_url.json 파일을 생성하지만 provenance_url.json 파일은 생성하지 않습니다. 이 예시들은 직접 URL 데이터 구조 명세의 예시를 따릅니다:
pip install https://example.com/app-1.0.tgzpip install https://example.com/app-1.0.whlpip install "git+https://example.com/repo/app.git#egg=app&subdirectory=setup"pip install ./apppip install file:///home/user/apppip install --editable "git+https://example.com/repo/app.git#egg=app&subdirectory=setup"(이 경우url은 git 저장소가 복제된 로컬 디렉터리가 되고,dir_info는"editable": true와 함께 존재하며,vcs_info는 설정되지 않습니다)pip install -e ./app
provenance_url.json 파일을 생성하지만 direct_url.json 파일은 생성하지 않는 명령:
pip install apppip install app~=2.2.0pip install app --no-index --find-links "https://example.com/"
이 동작은 PR pypa/pip#11865에서 구현된 pip 변경 사항을 사용하여 테스트할 수 있습니다.
참조 구현
Python 배포 패키지를 설치할 때 provenance_url.json 메타데이터 파일을 생성하는 개념 증명은 pip에 대한 PR pypa/pip#11865에서 확인할 수 있습니다. 이 구현은 direct_url.json이 생성되지 않는 경우에 provenance_url.json 메타데이터 파일을 제공하기 위해 이미 존재하는 직접 URL 데이터 구조 구현을 재사용합니다.
PDM에서 provenance_url.json 파일을 지원하는 참조 구현은 pdm-project/pdm#3013에서 확인할 수 있습니다.
direct_url.json 및 provenance_url.json 메타데이터 파일을 고려하여 requirements.txt 파일을 생성하는 방법을 보여 주기 위해 pip-preserve라는 프로토타입이 개발되었습니다. 이 도구는 pip freeze 기능을 모방하지만, 설치된 패키지 목록에 Python 배포 아티팩트의 해시도 포함합니다.
이 제안을 더욱 뒷받침하기 위해, pip-sbom은 SPDX 형식의 SBOM 생성을 보여 줍니다. 이 도구는 provenance_url.json 파일에 저장된 정보를 사용합니다.
기각된 아이디어
파일 이름을 provenance_url.json 대신 direct_url.json으로 지정하기
설치된 배포의 직접 URL 출처 기록과의 하위 호환성을 유지하기 위해, 해당 명세의 본문에 따라 파일 이름을 direct_url.json으로 지정할 수 없습니다:
다른 유형의 요구 사항(즉, 이름과 버전 지정자)으로 배포를 설치할 때에는 이 파일을 생성해서는 안 됩니다(MUST NOT).
이러한 변경은 직접 URL 참조로 배포가 설치된 경우에만 direct_url.json이 존재한다는 점에 의존하는 direct_url.json 소비자에게 하위 호환성 문제를 일으킬 수 있습니다.
direct_url.json을 폐기하고 provenance_url.json만 사용하기
direct_url.json 파일은 직접 URL 데이터 구조 명세로 이미 잘 정립되어 있으며 설치 프로그램에서 이미 사용하고 있습니다. 예를 들어, pip은 pip freeze에서 직접 URL 참조를 보고하는 데 direct_url.json을 사용합니다. direct_url.json을 폐기하려면 pip의 pip freeze 구현을 추가로 변경해야 하며(PR fridex/pip#2 참조), 이미 존재하는 direct_url.json 소비자에게 하위 호환성 문제를 일으킬 수 있습니다.
archive_info 딕셔너리에 hash 해시 키 유지하기
Direct URL Data Structure 명세는 archive_info 딕셔너리에 hashes 키와 함께 hash 키를 포함할 가능성을 논의합니다. 이 PEP는 provenance_url.json 파일에 hash 키를 명시적으로 포함하지 않으며, hashes 키만 존재하도록 허용합니다. 이렇게 함으로써 파일 내의 잠재적인 중복과 혼란, 그리고 해시가 서로 일치하는지 확인하기 위해 수행해야 할 추가 검사를 모두 없앱니다.
해시가 명시되지 않은 경우 허용하기
wheel 파일이 pip 캐시에서 설치되었고 이전 버전의 pip로 빌드된 경우, pip는 내려받은 소스 배포판의 해시를 기록하지 않습니다. 이렇게 다운로드한 소스 배포판의 해시가 없으므로, provenance_url.json 파일의 hashes 키에는 아무 항목도 포함되지 않게 됩니다. 이러한 경우 출처 정보가 완전하지 않으므로 pip는 provenance_url.json 파일을 생성하지 않습니다. 이러한 경우 소비자는 더 새로운 버전의 pip로 휠을 다시 빌드할 것을 권장합니다.
uv는 명시적으로 요구되지 않는 한 배포판 해시를 계산하지 않으므로, uv 개발자들은 provenance_url.json 파일에 최소 하나의 해시를 요구하는 것에 대한 우려를 제기했습니다. 그러나 최소 하나의 해시를 요구하면 배포판의 무결성 검사에 도움이 됩니다. 이는 잠금 파일이 관련된 시나리오나 SBOM의 일부로 배포판을 식별할 때 중요합니다. provenance_url.json 파일은 다운로드한 배포판에 대해 최소 하나의 해시를 반드시 포함하도록 규정합니다. 설치 과정에서 (예: 성능상의 이유로) 배포의 해시를 계산하지 않는 설치 프로그램은 provenance_url.json 파일을 생성하지 않아도 됩니다.
hashes 해시 키를 선택 사항으로 만들기
PEP 610과 이에 대응하는 정식 PyPA 명세는 direct_url.json 파일에 archive_info의 hashes 키를 포함할 것을 권장하지만, (RFC 2119의 표현에 따르면) 필수는 아닙니다.
hashes 키는 해시 이름을 16진수로 인코딩된 파일 다이제스트에 매핑하는 딕셔너리로 존재해야 합니다(SHOULD).
이 PEP는 provenance_url.json 파일이 생성되는 경우 해당 파일의 archive_info에 hashes 키를 포함할 것을 요구합니다. 이 PEP에 따르면 다음과 같습니다.
archive_info의 값은 단일 키hashes를 가진 딕셔너리여야 합니다(MUST).
이렇게 하면 설치 프로그램이 provenance_url.json 파일을 생성했을 때 provenance_url.json을 사용하는 쪽에서 아티팩트 다이제스트를 확인할 수 있습니다.
색인 URL 저장하기
색인 URL을 파일 내용의 일부로 저장하자는 의견이 제기되었습니다. 이 색인 URL은 pip 설정에 구성되었거나 --index-url 또는 --extra-index-url 옵션으로 지정된 색인을 나타냅니다. 특히 --find-links와 같은 다른 설치 옵션을 사용할 때 이 정보를 저장하면 혼란스럽다고 판단되었습니다. 실제 색인 URL은 wheel 파일을 내려받은 위치와 엄밀하게 연결되어 있지 않으므로, provenance_url.json 파일에 색인 URL을 저장하지 않기로 했습니다.
미해결 문제
Conda에서의 provenance_url.json 파일 가용성
provenance_url.json 파일에 대해 Conda 유지 관리자의 의견을 듣고자 합니다. Conda가 provenance_url.json 파일을 도입하려는지는 분명하지 않습니다. Conda는 이미 설치 중 수행하는 동작에 따라 출처 관련 정보(이 PEP에서 제안하는 출처 정보와 유사함)를 conda-meta 디렉터리에 있는 JSON 파일에 저장합니다.
다운스트림 설치 프로그램에서 provenance_url.json 사용하기
제안된 provenance_url.json 파일은 주로 Python 설치 프로그램에서 채택하도록 의도되었습니다. APT나 DNF 같은 다른 설치 프로그램은 설치된 다운스트림 Python 배포의 출처를 다운스트림 패키지 관리에 특화된 고유한 방식으로 기록할 수 있습니다. 제안된 파일은 이러한 다운스트림 패키지 설치 프로그램이 생성할 것으로 예상되지 않으므로, 이들은 의도적으로 이 PEP에서 제외되었습니다. 그러나 이러한 설치 프로그램의 개발자나 유지 관리자의 의견은 어떤 식으로든 도움이 될 정보로 provenance_url.json 파일을 보강할 수 있다는 점에서 가치가 있습니다.
부록: 설치 프로그램과 라이브러리 조사
pip
휠 설치를 담당하는 pip 내부 API의 함수인 _install_wheel은 .dist-info 디렉터리에 어떠한 provenance_url.json 파일도 저장하지 않습니다. 또한 pypa/pip#11865 에서 언급된 파일을 pip에 도입하는 프로토타입은 provenance_url.json 파일을 처리하는 로직을 pip 소스 코드에 통합하는 방법을 보여 줍니다.
아래에 언급된 도구 중 일부는 Python 패키지 배포를 설치하는 데 pip을 사용하므로 pip에 대한 조사 결과가 이러한 도구에도 적용되며, 또한 pip은 내부 API에서 .dist-info 디렉터리의 파일 생성을 매개변수화하는 것을 허용하지 않습니다. 아래에 언급된 도구 중 pip을 사용하는 대부분은 pip을 서브프로세스로 호출하며, 이는 .dist-info 디렉터리에 provenance_url.json 파일이 최종적으로 존재하는지에 아무런 영향을 미치지 않습니다.
distlib
distlib은 dist-info 디렉터리를 조작하는 저수준 기능을 구현합니다. distlib의 소스 코드에 따르면, 설치된 배포물의 데이터베이스는 provenance_url.json이라는 이름의 파일을 사용하지 않습니다.
Pipenv
Pipenv는 파이썬 패키지 배포물을 설치하기 위해 pip을 사용합니다. .dist-info 디렉터리에 provenance_url.json 파일을 도입할 때 하위 호환성 문제를 일으킬 만한 추가 로직은 발견되지 않았습니다.
installer(설치 프로그램)
installer는 provenance_url.json 파일을 명시적으로 생성하지 않습니다. 그럼에도 Recording Installed Projects 명세에 따라, 설치 프로그램 installer는 additional_metadata 인자를 전달하여 .dist-info 디렉터리에 파일을 생성할 수 있도록 허용합니다. 소스 코드를 참조하십시오. 하위 호환성 문제를 피하기 위해, 설치 프로그램 installer를 사용하는 라이브러리나 도구는 앞서 언급한 additional_metadata 인자를 사용하여 provenance_url.json 파일 생성을 요청해서는 안 됩니다.
Poetry
Poetry의 설치 로직은 installer.modern-installer 설정 옵션에 따라 달라집니다(문서 참조).
installer.modern-installer 설정 옵션이 false로 설정된 경우, Poetry는 pip을 사용하여 파이썬 패키지 배포물을 설치합니다.
반면 installer.modern-installer 설정 옵션이 true로 설정된 경우, Poetry는 installer를 사용하여 파이썬 패키지 배포물을 설치합니다. 링크된 소스에서 볼 수 있듯이, 이 PEP와 호환성 문제를 일으킬 provenance_url.json이라는 이름의 추가 메타데이터 파일은 전달되지 않습니다.
Conda
Conda는 파이썬 패키지 배포물이 설치될 때 어떠한 provenance_url.json 파일도 생성하지 않습니다.
Hatch
Hatch는 프로젝트 의존성을 설치하기 위해 pip를 사용합니다.
micropipenv
micropipenv는 pip 위에 구축된 래퍼이므로, 잠금 파일과 요구 사항 파일 모두에 대해 Python 배포판을 설치할 때 pip를 사용합니다.
Thamos
Thamos는 Python 패키지 배포판을 설치하기 위해 micropipenv를 사용하므로, micropipenv에 대한 모든 조사 결과는 Thamos에도 적용됩니다.
PDM
PDM은 바이너리 배포를 설치하기 위해 설치 프로그램 installer를 사용합니다. PDM이 .dist-info 디렉터리에 추가로 생성할 수 있는 유일한 메타데이터 파일은 REFER_TO 파일입니다.
uv
uv는 Rust로 작성되었으며, 휠을 설치할 때 자체 설치 로직을 사용합니다. uv는 .dist-info 디렉터리에 provenance_url.json 파일 이름과 충돌할 만한 추가 파일을 전혀 생성하지 않습니다.
참고 문헌
감사의 글
이 아이디어가 처음 나온 초기 논의를 함께해 주신 Dustin Ingram, Brett Cannon, Paul Moore에게 감사드립니다.
초기 피드백을 주시고 이 PEP 작업을 지원해 주신 Donald Stufft, Ofek Lev, Trishank Kuppusamy에게 감사드립니다.
Gregory P. Smith, Stéphane Bidoul, C.A.M. Gerlach, Adam Turner에게 이 PEP를 검토하고 귀중한 제안을 해 주신 데 대해 감사드립니다.
지원과 귀중한 제안, 그리고 pip-sbom 프로토타입을 제안해 주신 Seth Michael Larson에게 감사드립니다.
PEP 610과 관련 명세인 설치된 배포판의 Direct URL 출처 기록 및 Direct URL 데이터 구조를 작성해 주신 Stéphane Bidoul과 Chris Jerdonek에게 감사드립니다.
provenance_url.json 파일에 색인 URL을 저장하는 것과 관련해 우려될 수 있는 점을 제기해 주시고 PDM에서 PEP 710을 처음 지원해 주신 Frost Ming에게 감사드립니다.
uv 설치 프로그램과 관련하여 의견을 주신 Charlie Marsh와 Zanie Blue에게 감사드립니다.
마지막으로, 이 PEP를 후원해 주신 Donald Stufft에게 감사드립니다.
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.