Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 480 – PyPI 침해에서 살아남기: 패키지의 종단 간 서명

Author:
Trishank Karthik Kuppusamy <karthik at trishank.com>, Vladimir Diaz <vladimir.diaz at nyu.edu>, Justin Cappos <jcappos at nyu.edu>, Marina Moore <mm9693 at nyu.edu>
BDFL-Delegate:
Donald Stufft <donald at stufft.io>
Discussions-To:
Discourse thread
Status:
Draft
Type:
Standards Track
Topic:
Packaging
Requires:
458
Created:
08-Oct-2014

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

종단 간 서명과 최대 보안 모델을 지원하는 PEP 458의 확장이 제안되었습니다. 종단 간 서명을 사용하면 PyPI와 개발자가 모두 클라이언트가 다운로드하는 배포 패키지에 서명할 수 있습니다. 최소 보안 모델은 PEP 458에서 제안한 것으로, 배포 파일의 지속적인 제공을 지원하지만(온라인 키로 서명되기 때문입니다), PyPI가 침해되는 경우에는 배포 파일을 보호하지 못합니다. 최소 보안 모델에서는 PyPI 인프라에 저장된 서명 키를 침해한 공격자가 악성 배포 패키지에 서명할 수 있습니다. 이 PEP에서 설명하는 최대 보안 모델은 PEP 458의 이점(예: PyPI에 업로드된 배포 패키지를 즉시 사용할 수 있다는 점)을 유지하면서, PyPI가 침해되더라도 최종 사용자가 위조된 소프트웨어를 설치할 위험에 처하지 않도록 추가로 보장합니다.

이 PEP에서는 PyPI 인프라에 대한 일부 변경과 종단 간 서명에 참여하려는 개발자를 위한 몇 가지 권장 변경이 필요합니다. 이러한 변경에는 개발자 키에 대한 위임을 포함하도록 PEP 458의 메타데이터 레이아웃을 업데이트하는 작업, 개발자 키를 PyPI에 등록하는 프로세스를 추가하는 작업, 종단 간 서명을 활용하는 개발자의 업로드 작업 흐름을 변경하는 작업이 포함됩니다. 이러한 변경 사항은 모두 이 PEP의 뒷부분에서 자세히 설명합니다. 종단 간 서명을 활용하려는 패키지 관리자는 PEP 458에 설명된 메타데이터를 사용하기 위해 필요한 작업 외에 추가 작업을 수행할 필요가 없습니다.

이 PEP에서는 PEP 458에 적용된 변경 사항을 다루지만, 최대 보안 모델에 주로 초점을 맞추기 위해 정보 제공 요소는 제외합니다. 예를 들어 The Update Framework의 개요나 PEP 458의 기본 메커니즘은 여기에서 다루지 않습니다. 관련 PEP 458의 변경 사항에는 스냅샷 프로세스 수정, 키 침해 분석, 스냅샷 감사 및 PyPI 침해 발생 시 취해야 하는 단계가 포함됩니다. PyPI가 MAY RECOMMEND할 수 있는 서명 및 키 관리 프로세스를 논의하지만, 엄격하게 정의하지는 않습니다. 키와 메타데이터를 관리하기 위한 릴리스 프로세스를 어떻게 구현할지는 서명 도구 구현자의 몫으로 남겨 둡니다. 즉, 이 PEP에서는 배포 패키지의 종단 간 검증을 지원하기 위해 개발자가 업로드해야 하는 메타데이터에 포함될 예상 암호화 키 유형과 서명 형식을 규정합니다.

PEP 상태

커뮤니티에서는 2014년부터 2018년까지 이 PEP를 논의했습니다. 이 PEP를 구현하는 데 필요한 작업량 때문에 PEP 458의 선행 단계가 승인된 후까지 논의를 연기했습니다. 2020년 중반 기준으로 PEP 458은 승인되었고 구현이 진행 중이며, PEP 작성자들은 구현에 필요한 적절한 자금을 확보할 수 있도록 승인을 받는 것을 목표로 합니다.

근거

PEP 458에서는 PyPI를 The Update Framework(TUF) [2]와 통합하는 방법을 제안합니다. PyPI를 서버 측에서 수정하여 TUF 메타데이터를 포함하면 pip와 같은 최신 패키지 관리자를 더욱 안전하게 만들 수 있는 방법과 방지할 수 있는 공격 유형을 설명합니다. 패키지 관리자는 PyPI에서 사용할 수 있는 TUF 메타데이터를 참조하여 배포 패키지를 더욱 안전하게 다운로드할 수 있습니다.

PEP 458에서는 PyPI 저장소의 메타데이터 레이아웃도 설명하며, 프로젝트의 지속적 배포를 지원하고 개발자가 업로드한 배포 패키지에 서명하기 위해 온라인 암호화 키를 사용하는 최소 보안 모델을 적용합니다. 최소 보안 모델은 mix-and-match 공격과 불필요한 종속성 공격 같은 소프트웨어 업데이트 프로그램에 대한 대부분의 공격 [5] [6]을 방어하지만, PyPI가 침해되는 경우 종단 간 서명을 지원하고 위조된 배포 패키지를 차단하도록 개선할 수 있습니다.

PEP 480은 개발자 서명 지원을 추가하고 악성 배포 패키지를 방지하기 위해 온라인 키에 대한 의존도를 줄이는 방식으로 PEP 458을 확장합니다. 관련 PEP 458 및 최소 보안 모델의 주요 강점은 자동화되고 간소화된 릴리스 프로세스입니다. 즉, 개발자는 배포물을 업로드한 다음 PyPI가 해당 배포물에 서명하도록 할 수 있습니다. 릴리스 프로세스의 상당 부분은 온라인 역할에 의해 자동화된 방식으로 처리되며, 이 접근 방식에서는 PyPI 인프라에 암호화 서명 키를 저장해야 합니다. 안타깝게도 온라인에 저장된 암호화 키는 도난에 취약합니다. 이 PEP에서 제안하는 최대 보안 모델에서는 개발자가 PyPI 사용자에게 제공하는 배포 패키지에 서명할 수 있으며, PyPI 인프라에 저장된 온라인 키가 침해되더라도 최종 사용자가 악성 배포 패키지를 다운로드할 위험에 처하지 않습니다.

위협 모델

위협 모델은 다음을 가정합니다:

  • 오프라인 키는 안전하며 안전하게 저장됩니다.
  • 공격자는 온라인에 저장된 PyPI의 신뢰할 수 있는 키 중 하나 이상을 손상시킬 수 있으며, 이를 한 번에 또는 일정 기간에 걸쳐 수행할 수 있습니다.
  • 공격자는 클라이언트 요청에 응답할 수 있습니다.
  • 공격자는 클라이언트가 설치하지 않으려는 프로젝트의 개발자 키를 얼마든지 제어할 수 있습니다.

공격자가 클라이언트가 업데이트 중인 소프트웨어의 최신 버전이 아닌 것을 설치하도록(또는 설치된 상태로 두도록) 만들 수 있다면 공격이 성공한 것으로 간주합니다. 공격자가 업데이트 설치를 방해하는 경우, 공격자의 목표는 클라이언트가 무언가 잘못되었다는 사실을 알아차리지 못하게 하는 것입니다.

정의

이 문서에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 키워드는 RFC 2119에 설명된 대로 해석해야 합니다.

이 PEP는 TUF를 PyPI와 통합하는 데 중점을 둡니다. 그러나 독자는 TUF의 설계 원칙 [2]을 읽어 보는 것이 좋습니다. 또한 독자는 TUF 사양 [3]과 이 PEP가 확장하는 PEP 458에 익숙할 것이 RECOMMENDED됩니다.

이 PEP에서 사용되는 다음 용어는 Python 패키징 용어집 [4]: project, release, distribution에 정의되어 있습니다.

이 PEP에서 사용되는 용어는 다음과 같이 정의합니다:

  • 배포 파일: 릴리스를 배포하는 데 사용되는 Python 패키지, 모듈 및 기타 리소스 파일을 포함하는 버전이 지정된 아카이브 파일입니다. 이 PEP에서는 배포 파일, 배포 패키지 [4], 또는 단순히 배포물 또는 패키지를 서로 바꾸어 사용할 수 있습니다.
  • 단순 색인: 배포 파일로 연결되는 내부 링크를 포함하는 HTML 페이지입니다.
  • 대상 파일: 일반적으로 대상 파일은 TUF를 사용하여 무결성이 보장되어야 하는 PyPI의 모든 파일입니다. 일반적으로 여기에는 배포 파일과 단순 색인 같은 PyPI 메타데이터가 포함됩니다.
  • 역할: TUF의 역할은 당사자가 수행하도록 권한을 부여받은 작업 집합을 포괄하며, 여기에는 당사자가 서명할 수 있는 메타데이터와 담당하는 패키지가 포함됩니다. PyPI에는 root 역할이 하나 있습니다. root 역할이 직접 또는 간접적으로 책임을 위임한 여러 역할이 있습니다. “최상위 역할”이라는 용어는 root 역할과 root 역할이 위임한 모든 역할을 가리킵니다. 각 역할에는 제공할 것을 신뢰받는 단일 메타데이터 파일이 있습니다.
  • 메타데이터: 메타데이터는 역할, 기타 메타데이터 및 대상 파일을 설명하는 파일입니다.
  • 저장소: 저장소는 이름이 지정된 메타데이터와 대상 파일로 구성된 리소스입니다. 클라이언트는 저장소에 저장된 메타데이터와 대상 파일을 요청합니다.
  • 일관된 스냅샷: 특정 시점에 존재했던 PyPI의 모든 프로젝트 전체 상태를 포착하는 TUF 메타데이터 및 대상 파일 집합입니다.
  • 개발자: 특정 프로젝트에 대한 TUF 메타데이터와 배포 메타데이터 및 파일을 업데이트할 수 있는 프로젝트의 소유자 또는 유지 관리자입니다.
  • 온라인 키: PyPI 서버 인프라에 반드시 저장해야 하는 개인 암호화 키입니다. 이를 통해 일반적으로 키를 사용한 자동 서명이 가능해집니다. PyPI 인프라를 손상시킨 공격자는 이러한 키를 즉시 읽을 수 있습니다.
  • 오프라인 키: PyPI 서버 인프라와 독립적으로 저장되어야 하는 개인 암호화 키입니다. 이를 통해 해당 키를 사용한 자동 서명을 방지합니다. PyPI 인프라를 침해한 공격자는 이 키를 즉시 읽을 수 없습니다.
  • 임계값 서명 체계: 역할은 메타데이터에 서명하는 데 n개 키 중 최소 t개가 반드시 필요하도록 지정하여 키 침해에 대한 복원력을 높일 수 있습니다. t-1개 키가 침해되어도 역할 자체를 침해하기에는 충분하지 않습니다. 역할에 (t, n) 키가 필요하다고 표현하는 것은 임계값 서명 속성을 의미합니다.

최대 보안 모델

최대 보안 모델에서는 개발자가 프로젝트에 서명하고 서명된 메타데이터를 PyPI에 업로드할 수 있습니다. 이 PEP에서 제안하는 모델에서는 PyPI 인프라가 침해되더라도 공격자가 해당 프로젝트의 개발자 키에 접근하지 않고는 claimed 프로젝트의 악성 버전을 제공할 수 없습니다. 그림 1은 최소 보안 모델의 메타데이터 배치에 적용된 변경 사항을 보여 줍니다. 즉, 이제 개발자 역할이 지원되며 claimed, recently-claimed, unclaimed라는 세 가지 새로운 위임 역할이 존재합니다. 최소 보안 모델의 bins 역할은 unclaimed 역할로 이름이 변경되었으며, claimed 역할에 추가되지 않은 모든 프로젝트를 포함할 수 있습니다. unclaimed 역할은 이전과 동일하게 작동합니다(즉, PEP 458에서 설명한 것처럼 이 역할에 추가된 프로젝트는 온라인 키로 PyPI가 서명합니다). 개발자가 제공하는 오프라인 키는 최대 보안 모델이 최소 모델보다 강력하도록 보장합니다. 최소 보안 모델은 프로젝트의 지속적 배포를 지원하지만, 모든 프로젝트는 온라인 키로 서명됩니다. 즉, 공격자는 개발자의 키까지 침해하지 않고도 최소 보안 모델에서는 패키지를 변조할 수 있지만 최대 보안 모델에서는 변조할 수 없습니다.

../_images/pep-0480-1.png

그림 1: 최대 보안 모델의 메타데이터 배치 개요입니다. 최대 보안 모델은 지속적 배포와 키 침해에 대한 생존성을 지원합니다.

개발자가 서명하고 처음으로 PyPI에 업로드한 프로젝트는 recently-claimed 역할에 추가됩니다. recently-claimed 역할은 온라인 키를 사용하므로 처음 업로드된 프로젝트를 클라이언트에서 즉시 사용할 수 있습니다. 일정 시간이 지난 후 PyPI 관리자는 최대 보안을 위해 recently-claimed에 나열된 프로젝트를 claimed로 주기적으로 이동할 수 있습니다(예: 매월). claimed 역할은 오프라인 키를 사용하므로 PyPI가 침해되더라도 이 역할에 추가된 프로젝트를 쉽게 위조할 수 없습니다.

recently-claimed 역할은 보안이 아니라 사용성과 효율성을 위해 unclaimed 역할과 분리되어 있습니다. 새 프로젝트 위임을 unclaimed 메타데이터 앞에 추가한다면, 프로젝트가 키를 얻을 때마다 unclaimed 역할을 다시 다운로드해야 합니다. 새 프로젝트를 분리하면 가져오는 데이터의 양이 줄어듭니다. 사용성 측면에서도 관리자가 현재 어떤 프로젝트가 클레임되었는지 더 쉽게 확인할 수 있습니다. 이 정보는 키를 recently-claimed에서 claimed로 이동할 때 필요하며, 이에 대해서는 “일관된 스냅샷 생성” 절에서 더 자세히 설명합니다.

종단 간 서명

종단 간 서명을 사용하면 PyPI와 개발자 모두 클라이언트가 다운로드하는 메타데이터에 서명할 수 있습니다. PyPI는 업로드된 프로젝트를 클라이언트에서 사용할 수 있도록 하는 신뢰를 받으며(이 과정의 해당 부분에 대해 PyPI가 메타데이터에 서명합니다), 개발자는 PyPI에 업로드하는 배포 패키지에 서명합니다.

프로젝트에 대한 신뢰를 위임하려면 개발자는 PyPI에 하나 이상의 공개 키를 제출해야 합니다. 개발자는 동일한 프로젝트에 대해 여러 개의 공개 키를 제출할 수 있습니다(예를 들어 프로젝트의 각 관리자마다 키 하나씩 제출할 수 있습니다). PyPI는 프로젝트의 모든 공개 키를 가져와 PyPI가 서명하는 상위 메타데이터에 추가합니다. 초기 신뢰가 설정된 후 개발자는 공개 키 중 하나에 대응하는 개인 키를 사용하여 PyPI에 업로드하는 배포물에 서명해야 합니다. 개발자가 PyPI에 업로드하는 서명된 TUF 메타데이터에는 배포물의 파일 크기와 해시 같은 정보가 포함되며, 패키지 관리자는 이를 사용하여 다운로드한 배포물을 검증합니다.

종단 간 서명의 실질적인 의미는 프로젝트에 대한 신뢰를 위임하는 데 필요한 추가 관리 작업과 개발자가 배포물과 함께 PyPI에 반드시 업로드해야 하는 서명된 메타데이터입니다. 구체적으로 PyPI는 프로젝트를 claimed 메타데이터 파일에 추가하고 해당 파일에 서명하여 오프라인 키로 메타데이터에 주기적으로 서명할 것으로 예상됩니다. 반면 최소 보안 모델에서는 프로젝트에 온라인 키로만 서명합니다. 종단 간 서명에는 신뢰를 위임하기 위한 수동 개입(즉, 오프라인 키로 메타데이터에 서명하는 작업)이 필요하지만, 이는 일회성 비용이며 이후 프로젝트는 PyPI 침해에 대해 더 강력한 보호를 받습니다.

메타데이터 서명, 키 관리 및 배포물 서명

이 절에서는 PyPI가 서명 도구 구현자에게 권장할 수 있는 도구, 서명 체계 및 서명 방법을 설명합니다. 개발자는 이러한 도구를 사용하여 배포물에 서명하고 PyPI에 업로드해야 합니다. 아래 하위 절에서 논의하는 권장 도구와 체계를 요약하면, 개발자는 배포물의 진위를 검증하는 데 필요한 정보가 메타데이터에 포함되도록 일부 자동화된 방식으로 암호화 키를 생성하고 메타데이터에 서명할 수 있습니다(Ed25519 서명 체계 사용). 그런 다음 개발자는 메타데이터를 PyPI에 업로드하며, 여기서 pip와 같은 패키지 관리자(TUF 메타데이터를 지원하는 패키지 관리자)가 다운로드할 수 있게 됩니다. 전체 과정은 PyPI에서 배포물을 다운로드하는 최종 사용자(TUF를 지원하는 패키지 관리자를 사용하는 사용자)에게 투명하게 진행됩니다.

처음 세 하위 절(암호화 서명 체계, 암호화 키 파일 및 키 관리)에서는 개발자 릴리스 프로세스의 암호화 구성 요소를 다룹니다. 즉, PyPI가 지원하는 키 유형, 키를 저장하는 방법 및 키를 생성하는 방법을 다룹니다. 처음 세 하위 절 다음에 나오는 두 하위 절에서는 TUF 메타데이터를 지원하도록 수정해야 하는 PyPI 모듈을 설명합니다. 예를 들어 Twine과 Distutils는 수정해야 하는 두 프로젝트입니다. 마지막으로 마지막 하위 절에서는 서명 도구에 권장되는 자동화된 키 관리 및 서명 솔루션을 설명합니다.

TUF의 설계는 암호화 키 유형, 서명 및 서명 방법과 관련하여 유연합니다. 다음 절에서 논의하는 도구, 수정 사항 및 방법은 서명 도구 구현자를 위한 권장 사항입니다.

암호화 서명 체계: Ed25519

CPython과 함께 제공되는 패키지 관리자(pip)는 CPython이 아닌 인터프리터에서 반드시 작동해야 하며 컴파일해야 하는 종속성을 가질 수 없습니다(즉, PyPI+TUF 통합은 암호화 서명을 검증하기 위해 C 확장을 컴파일하도록 요구해서는 안 됩니다). 서명 검증은 Python에서 수행해야 하며, 순수 Python으로 RSA [8] 서명을 검증하는 것은 속도 때문에 실용적이지 않을 수 있습니다. 따라서 PyPI는 Ed25519 서명 체계를 사용할 수 있습니다.

Ed25519 [9] 는 작은 암호화 서명과 키를 사용하는 공개 키 서명 시스템입니다. Ed25519 서명 체계의 pure-Python implementation을 사용할 수 있습니다. Ed25519 서명 검증은 Python에서 수행하는 경우에도 빠릅니다.

암호화 키 파일

구현은 AES-256-CTR-Mode로 키 파일을 암호화하고 PBKDF2-HMAC-SHA256으로 비밀번호를 강화할 수 있습니다(기본값은 100K회 반복이지만 개발자가 이를 재정의할 수 있습니다). 현재 TUF의 Python 구현은 어떤 암호화 라이브러리든 사용할 수 있고(PyCA cryptography 지원은 향후 추가될 예정입니다), PBKDF2 반복 횟수의 기본값을 재정의할 수 있으며, KDF를 원하는 대로 조정할 수 있습니다.

키 관리: miniLock

사용하기 쉬운 키 관리 솔루션이 필요합니다. 한 가지 해결책은 개발자가 여러 컴퓨터에서 암호화 키 파일을 관리하지 않아도 되도록 비밀번호에서 개인 키를 파생하는 것입니다. miniLock은 이를 수행하는 방법의 한 예입니다. 개발자는 암호화 키를 보조 비밀번호로 간주할 수 있습니다. miniLock은 매우 작은 키만 필요한 Ed25519와 같은 서명 체계와도 잘 작동합니다.

타사 업로드 도구: Twine

Twine과 같은 타사 도구는 TUF 메타데이터를 포함하는 배포를 지원하려는 경우 개발자 프로젝트에 서명하고 PyPI에 업로드하도록 수정할 수 있습니다. Twine은 TLS를 사용하여 배포를 업로드하고 사용자 이름과 비밀번호에 대한 MITM 공격을 방지하는 PyPI 상호 작용용 유틸리티입니다.

빌드 백엔드

빌드 백엔드는 메타데이터에 서명하고 서명된 배포를 PyPI에 업로드하도록 수정할 수 있습니다.

자동 서명 솔루션

개발자에게 사용하기 쉬운 키 관리 솔루션을 권장합니다. 한 가지 방법은 miniLock과 유사하게 사용자 비밀번호에서 암호화 개인 키를 생성하는 것입니다. 개발자 서명을 선택 사항으로 유지할 수 있더라도, 각 배포에 포함될 수 있는 잠재적으로 서명되지 않은 의존성의 수가 매우 많으므로 이 방법은 충분하지 않을 수 있습니다. 이러한 의존성 중 하나라도 서명되지 않으면 프로젝트가 자체 배포에 서명하여 얻는 모든 이점이 무효화됩니다(즉, 공격자는 최종 사용자들을 공격하기 위해 서명되지 않은 의존성 중 하나만 손상시키면 됩니다). 개발자에게 배포에 수동으로 서명하고 키를 관리하도록 요구하면 키 서명 기능이 사용되지 않게 될 것으로 예상됩니다.

개발자에게 transparent한 기본 PyPI 중개 키 관리 및 패키지 서명 솔루션을 서명 도구에 권장하며, 키 에스크로(PyPI와 암호화된 개인 키를 공유하는 것)를 요구하지 않아야 합니다. 또한 서명 도구는 각 개발자의 여러 컴퓨터 간에 개인 키를 공유하지 않도록 해야 합니다. 이는 키 관리 솔루션이 각 프로젝트에 대해 여러 키를 지원해야 함을 의미합니다.

다음은 새 개발자가 배포를 PyPI에 업로드하기 위해 따를 수 있는 자동 서명 솔루션의 개요입니다.

  1. PyPI 프로젝트를 등록합니다.
  2. 보조 비밀번호를 입력합니다(PyPI 사용자 계정 비밀번호와는 별개입니다).
  3. 선택 사항: 비밀번호 프롬프트 후 두 번째 컴퓨터에서 개발자의 PyPI 사용자 계정에 새 ID를 추가합니다.
  4. 프로젝트를 업로드합니다.
  5. 선택 사항: 프로젝트와 연관된 다른 유지 관리자는 로그인하고 보조 비밀번호를 입력하여 프로젝트에 자신의 ID를 추가할 수 있습니다.

1단계는 개발자가 register a PyPI project하기 위해 따르는 일반적인 절차입니다.

2단계에서는 암호화된 키 파일(개인 키)을 생성하고, Ed25519 공개 키를 PyPI에 업로드하며, 배포를 위해 생성된 TUF 메타데이터에 서명합니다.

선택적으로 두 번째 시스템에서 새 신원을 추가하면, 비밀번호를 입력하는 것만으로 3단계에서 암호화된 개인 키 파일도 생성하고 Ed25519 공개 키를 PyPI에 업로드합니다. 개발자가 여러 시스템에서 릴리스를 서명할 수 있도록 별도의 신원을 생성할 수 있습니다. 기존의 검증된 신원(공개 키가 프로젝트 메타데이터에 포함되어 있거나 PyPI에 업로드된 신원)이 새 신원에 서명합니다. 기본적으로 프로젝트 메타데이터의 서명 임계값은 “1”이며, 다른 검증된 신원이 이 임계값을 충족하도록 새 릴리스를 생성할 수 있습니다.

4단계에서는 배포 파일과 TUF 메타데이터를 PyPI에 업로드합니다. “스냅샷 프로세스” 섹션에서는 개발자가 배포 파일을 PyPI에 업로드하기 위해 따르는 절차를 자세히 설명합니다.

5단계에서는 다른 유지 관리자가 2단계와 유사한 방식으로 암호화된 키 파일을 생성할 수 있습니다. 이러한 키는 PyPI에 업로드하고 TUF 메타데이터에 추가해야 합니다. 이 키는 프로젝트의 향후 릴리스를 업로드하는 데 사용할 수 있습니다.

기본적인 경우 암호화 파일과 서명의 생성은 개발자에게 투명합니다. 즉, 개발자는 패키지가 자동으로 서명된다는 사실을 알 필요가 없습니다. 그러나 서명 도구는 유연해야 합니다. 개발자가 직접 키를 생성하고 키 관리를 직접 처리하려 할 수 있기 때문입니다. 이 경우 개발자는 공개 키를 간단히 PyPI에 업로드할 수 있습니다.

repositorydeveloper TUF 도구는 현재 앞서 언급한 모든 권장 사항을 지원하지만, 자동 서명 솔루션은 예외이며 Distlib, Twine 및 기타 서드파티 서명 도구에 추가되어야 합니다. 자동 서명 솔루션은 사용 가능한 저장소 도구 함수를 호출하여 메타데이터에 서명하고 암호화 키 파일을 생성합니다.

스냅샷 프로세스

스냅샷 프로세스는 상당히 간단하며 자동화해야 합니다. 스냅샷 프로세스는 최신 root, targets 및 위임된 역할의 작업 집합을 메모리에 유지해야 합니다. 스냅샷 프로세스는 1분 정도마다 이 최신 작업 집합에 서명합니다. (프로젝트 업로드가 최신 위임된 메타데이터에 관한 정보를 동시성 안전 방식으로 스냅샷 프로세스에 지속적으로 전달한다는 점을 기억하십시오. 스냅샷 프로세스는 실제로 최신 작업 집합의 복사본에 서명하는 한편, 메모리의 최신 작업 집합은 프로젝트 트랜잭션 프로세스가 지속적으로 전달하는 정보로 업데이트됩니다.) 스냅샷 프로세스는 이전 단계에서 생성된 메타데이터(root, targets 및 위임된 역할)를 보증하는 새로운 timestamp 메타데이터를 생성하고 서명해야 합니다. 마지막으로 스냅샷 프로세스는 최신 스냅샷을 나타내는 새로운 timestampsnapshot 메타데이터를 클라이언트가 이용할 수 있도록 해야 합니다.

클레임된 또는 최근에 클레임된 프로젝트는 PyPI에 대한 트랜잭션에서 targets(간단한 색인과 배포 파일 모두)뿐만 아니라 TUF 메타데이터도 업로드해야 합니다. 프로젝트는 두 디렉터리, 즉 위임된 targets 메타데이터 파일을 포함하는 /metadata/와 프로젝트 간단한 색인 및 위임된 targets 메타데이터가 서명한 배포 파일 등의 targets를 포함하는 /targets/를 담은 ZIP 파일을 업로드하여 이를 수행할 수 있습니다.

프로젝트가 PyPI에 메타데이터 또는 target 파일을 업로드할 때마다 PyPI는 프로젝트 TUF 메타데이터에서 최소한 다음 속성을 확인해야 합니다.

  • 해당 프로젝트가 PyPI에 등록한 개발자 키 중 임계값에 해당하는 수의 키는 해당 프로젝트의 targets 루트를 나타내는 위임된 targets 메타데이터 파일(예: metadata/targets/ project.txt)에 서명해야 합니다.
  • 위임된 targets 메타데이터 파일의 서명은 유효해야 합니다.
  • 위임된 targets 메타데이터 파일은 만료되어서는 안 됩니다.
  • 위임된 targets 메타데이터는 targets와 일관되어야 합니다.
  • 위임자는 다른 위임자가 자신에게 위임하지 않은 targets를 위임해서는 안 됩니다.
  • 위임받은 자는 위임자가 자신에게 위임하지 않은 targets에 서명해서는 안 됩니다.

PyPI가 프로젝트 TUF 메타데이터를 확인하기로 선택한 경우, 이러한 요구 사항을 충족하지 않는 메타데이터 또는 target 파일 집합의 게시를 거부할 수 있습니다.

PyPI는 각 프로젝트가 자신에게 책임이 있는 TUF 메타데이터에만 쓸 수 있도록 보장하여 접근 제어를 반드시 시행해야 합니다. 이를 위해 프로젝트 업로드 프로세스가 올바른 메타데이터와 해당 메타데이터 내 올바른 위치에 쓰도록 반드시 보장해야 합니다. 예를 들어, 미클레임 프로젝트의 프로젝트 업로드 프로세스는 해당 프로젝트의 대상에 대한 올바른 위임된 미클레임 메타데이터의 올바른 대상 경로에 반드시 써야 합니다.

드문 경우에 PyPI는 프로젝트의 TUF 메타데이터 형식을 하위 호환성이 없는 방식으로 확장하고자 할 수 있습니다. 이 경우 개발자 키로 서명된 메타데이터의 서명이 무효화되므로, PyPI가 프로젝트를 대신하여 기존 TUF 메타데이터를 자동으로 다시 작성하여 새로운 하위 호환성이 없는 형식으로 업그레이드할 수 없다는 점에 유의해야 합니다. 대신 패키지 관리자는 TUF 메타데이터의 호환되지 않는 여러 버전을 인식하고 처리하도록 작성되어야 하며, 이를 통해 클레임된 프로젝트와 최근 클레임된 프로젝트에 최신이지만 하위 호환성이 없는 형식으로 메타데이터를 마이그레이션할 합리적인 시간이 제공되어야 합니다. 이 버전 변경을 처리하는 한 가지 메커니즘은 TAP 14에 설명되어 있습니다.

PyPI가 결국 새로운 일관된 스냅샷을 생성할 디스크 공간이 부족해지면, PyPI는 충분히 오래된 일관된 스냅샷을 삭제하기 위해 “mark-and-sweep” 알고리즘과 유사한 방법을 사용할 수 있습니다. 즉, 더 이상 사용되지 않는 timestampsnapshot 같은 오래된 메타데이터만 삭제됩니다. 구체적으로 최신 일관된 스냅샷을 보존하기 위해 PyPI는 최신 일관된 스냅샷의 객체를 루트(timestamp)부터 순회하며 방문한 모든 객체를 표시하고 표시되지 않은 모든 객체를 삭제합니다. 최근의 몇 개 일관된 스냅샷도 유사한 방식으로 보존할 수 있습니다. 일관된 스냅샷을 삭제하면 클라이언트는 삭제된 일관된 스냅샷의 대상에 대한 모든 요청에 대해 HTTP 404 응답만 보게 됩니다. 그러면 클라이언트는 이전과 마찬가지로 최신 일관된 스냅샷을 사용하여 요청을 다시 시도해야 합니다.

TUF 메타데이터를 지원하는 모든 패키지 관리자는 파일 요청에 파일의 암호화 해시를 파일 이름에 포함하여 timestamp 메타데이터를 제외한 모든 메타데이터 및 대상 파일을 다운로드하도록 반드시 수정되어야 합니다. 다음 하위 절에서 권장하는 파일 이름 규칙에 따라 filename.ext 파일에 대한 요청은 digest.filename 파일에 대한 동등한 요청으로 변환됩니다.

마지막으로 PyPI는 서버 장애 후 오류를 더 쉽게 복구할 수 있도록 프로젝트 트랜잭션 프로세스와 큐를 기록하는 transaction log를 사용해야 합니다.

일관된 스냅샷 생성

PyPI는 프로젝트에 따라 claimed, recently-claimed, 또는 unclaimed 메타데이터와 관련 위임된 메타데이터를 업데이트할 책임이 있습니다. 모든 프로젝트는 자신의 메타데이터 및 대상 집합을 단일 트랜잭션으로 반드시 업로드해야 합니다. 업로드된 파일 집합을 “프로젝트 트랜잭션”이라고 합니다. PyPI가 프로젝트 트랜잭션의 파일을 검증할 수 있는 방법은 이후 절에서 설명합니다. 이 절에서는 PyPI가 프로젝트 트랜잭션에 어떻게 응답하는지에 중점을 둡니다.

모든 메타데이터 및 대상 파일은 파일 이름에 해당 파일의 hex digestBLAKE2b-256 해시를 반드시 포함해야 하며, PyPI는 파일이 업로드된 후 파일 이름 앞에 이를 추가할 수 있습니다. 이 PEP에서는 PyPI가 다음과 같은 단순한 형식의 규칙을 채택할 것을 권장합니다: digest.filename. 여기서 filename은 해시가 복사되지 않은 원래 파일 이름이고, digest는 해시의 16진수 다이제스트입니다.

미클레임 프로젝트가 새 트랜잭션을 업로드하면 프로젝트 트랜잭션 프로세스는 모든 새 대상 파일과 관련 위임된 미클레임 메타데이터를 반드시 추가해야 합니다. 프로젝트 업로드 프로세스는 새로운 위임된 미클레임 메타데이터가 있음을 스냅샷 프로세스에 반드시 알려야 합니다.

recently-claimed 프로젝트가 새 트랜잭션을 업로드하면 프로젝트 업로드 프로세스는 프로젝트의 모든 새 대상 파일과 위임된 대상 메타데이터를 반드시 추가해야 합니다. 프로젝트가 새로운 프로젝트인 경우 프로젝트 업로드 프로세스는 프로젝트에 대한 공개 키와 함께 새로운 recently-claimed 메타데이터도 반드시 추가해야 하며, 공개 키는 반드시 트랜잭션의 일부여야 합니다. recently-claimed 프로젝트의 임계값은 업로드 프로세스가 “1”로 설정합니다. 마지막으로 프로젝트 업로드 프로세스는 새로운 recently-claimed 메타데이터와 프로젝트의 현재 위임된 대상 메타데이터 집합이 있음을 스냅샷 프로세스에 반드시 알려야 합니다.

클레임된 프로젝트의 업로드 프로세스는 PyPI 관리자가 프로젝트를 recently-claimed 역할에서 claimed 역할로 주기적으로 이동한다는 점에서 약간 다릅니다(2주마다에서 한 달에 한 번 사이에 발생할 수 있는 수동 프로세스입니다). (recently-claimed에서 claimed로 프로젝트를 이동하는 것은 PyPI 관리자가 오프라인 키를 사용하여 클레임된 프로젝트의 배포물에 서명해야 하기 때문에 수동으로 수행됩니다.) 이후 프로젝트 업로드 프로세스는 이 마이그레이션을 반영하기 위해 새로운 recently-claimedclaimed 메타데이터를 추가해야 합니다. recently-claimed 프로젝트의 경우와 마찬가지로, 프로젝트 업로드 프로세스는 클레임된 프로젝트의 모든 새로운 대상 파일과 위임된 targets 메타데이터를 항상 추가해야 합니다. 마지막으로 프로젝트 업로드 프로세스는 새로운 recently-claimed 또는 claimed 메타데이터와 프로젝트의 현재 위임된 targets 메타데이터 집합을 일관된 스냅샷 프로세스에 알려야 합니다.

PyPI 관리자가 프로젝트를 recently-claimed 역할에서 claimed 역할로 이동하는 경우를 제외하고, 프로젝트 업로드 프로세스는 자동화해야 합니다. 프로젝트 업로드 프로세스는 원자적으로도 적용해야 합니다. 즉, 모든 메타데이터와 대상 파일을 추가하거나, 어느 것도 추가하지 않아야 합니다. 프로젝트 트랜잭션 프로세스와 스냅샷 프로세스는 동시에 실행해야 합니다. 마지막으로 프로젝트 업로드 프로세스는 최신 claimed, recently-claimedunclaimed 메타데이터를 메모리에 유지하여 새로운 일관된 스냅샷에서 올바르게 업데이트되도록 해야 합니다.

다음 규칙을 준수한다면 큐는 나타난 순서대로 동시에 처리할 수 있습니다.

  1. 어떤 두 프로젝트 업로드 프로세스도 동일한 프로젝트에서 동시에 작업해서는 안 됩니다.
  2. 어떤 두 프로젝트 업로드 프로세스도 동일한 위임된 unclaimed 역할에 속하는 unclaimed 프로젝트에서 동시에 작업해서는 안 됩니다.
  3. 어떤 두 프로젝트 업로드 프로세스도 새 recently-claimed 프로젝트에서 동시에 작업해서는 안 됩니다.
  4. 어떤 두 프로젝트 업로드 프로세스도 새 claimed 프로젝트에서 동시에 작업해서는 안 됩니다.
  5. 한 프로젝트 업로드 프로세스가 새 recently-claimed 프로젝트에서 작업하는 동안 다른 프로젝트 업로드 프로세스가 새 claimed 프로젝트에서 작업해서는 안 되며, 그 반대의 경우도 마찬가지입니다.

메타데이터가 일관되지 않게 읽히거나 기록되지 않도록 이러한 규칙을 준수해야 합니다.

스냅샷 감사

악의적인 주체가 PyPI를 침해하면 온라인 키 중 어느 것이든 사용하여 임의의 파일에 서명할 수 있습니다. 오프라인 키를 사용하는 역할(즉, roottargets)은 여전히 보호됩니다. 저장소 침해에서 안전하게 복구하려면 파일이 신뢰할 수 있는 버전으로만 복원되도록 스냅샷을 감사해야 합니다.

저장소 침해가 탐지되면 세 가지 유형의 정보 무결성을 검증해야 합니다.

  1. 저장소의 온라인 키가 침해된 경우, targets 역할이 새 키에 위임된 새 메타데이터에 서명하도록 하여 해당 키를 폐기할 수 있습니다.
  2. 저장소의 역할 메타데이터가 변경되면 온라인 키로 서명된 메타데이터에 영향을 줍니다. 침해 이후 생성된 모든 역할 정보는 폐기해야 합니다. 그 결과 새 프로젝트의 개발자는 프로젝트를 다시 등록해야 합니다.
  3. 패키지 자체가 변조되었을 가능성이 있는 경우, 침해 전에 신뢰할 수 있는 메타데이터에 존재했던 패키지에 대해 저장된 해시 정보를 사용하여 검증할 수 있습니다. 또한 claimed 역할의 개발자가 서명한 새로운 배포물은 안전하게 유지할 수 있습니다. 그러나 recently-claimed 또는 unclaimed 역할의 개발자가 서명한 배포물은 모두 폐기해야 합니다.

침해가 발생한 경우 스냅샷을 안전하게 복원하려면 PyPI는 일정에 따라 PyPI 스냅샷을 복사할 자체 미러를 소수 유지해야 합니다. 이러한 목적을 위해 미러링 프로토콜을 즉시 사용할 수 있습니다. 미러는 PyPI 미러링만 담당하도록 보안을 설정하고 격리해야 합니다. 우발적 장애나 악의적인 장애를 탐지하기 위해 미러들을 서로 대조하여 검사할 수 있습니다.

또 다른 방법은 각 snapshot의 암호화 해시를 주기적으로 생성하여 트윗하는 것입니다. 예를 들어, 트윗을 받은 후 사용자가 실제 메타데이터를 제시하면 저장소 유지 관리자는 메타데이터의 암호화 해시를 검증할 수 있습니다. 또는 PyPI는 외부에서 제공된 메타데이터에 의존하는 대신 자체 snapshots버전을 주기적으로 보관할 수 있습니다. 이 경우 PyPI는 저장소의 모든 패키지에 대한 암호화 해시를 가져와 이 데이터를 오프라인 장치에 저장해야 합니다. 패키지 해시가 하나라도 변경되었다면 공격이 발생했음을 의미합니다.

서로 다른 버전의 메타데이터를 제공하거나 패키지 버전을 특정 버전에 고정하는 공격은 암묵적 키 폐기 및 메타데이터 불일치 감지와 같은 기법을 사용하여 TUF로 처리할 수 있습니다 [2].

키 침해 분석

이 PEP에서는 최대 보안 모델, 배포본의 지속적 제공을 지원하기 위해 추가해야 하는 TUF 역할, 각 역할의 메타데이터를 생성하고 서명하는 방법, 개발자가 서명한 배포본을 지원하는 방법을 다루었습니다. 나머지 섹션에서는 PyPI가 저장소 메타데이터를 감사해야 하는 방법과 PyPI 침해를 탐지하고 복구하기 위해 PyPI가 사용할 수 있는 방법을 설명합니다.

표 1은 일정 임계 수의 개인 암호화 키(PyPI 역할 중 하나에 속하는 키)가 침해되었을 때 가능한 공격 몇 가지를 요약합니다. 가장 왼쪽 열에는 침해된 역할(또는 역할 조합)이 나열되고, 오른쪽 열에는 침해된 역할로 인해 클라이언트가 악성 업데이트, 동결 공격 또는 메타데이터 불일치 공격에 취약해지는지 여부가 표시됩니다.

역할 침해 악성 업데이트 동결 공격 메타데이터 불일치 공격
timestamp NO snapshot과 targets 또는 위임된 역할 중 하나가 협력해야 합니다. YES 가장 이른 root, targets 또는 bin 메타데이터 만료 시간으로 제한됩니다. NO snapshot이 협력해야 합니다.
snapshot NO timestamp와 targets 또는 위임된 역할 중 하나가 협력해야 합니다. NO timestamp가 협력해야 합니다. NO timestamp가 협력해야 합니다.
timestamp AND snapshot NO targets 또는 위임된 역할 중 하나가 협력해야 합니다. YES 가장 이른 root, targets 또는 bin 메타데이터 만료 시간으로 제한됩니다. YES 가장 이른 root, targets 또는 bin 메타데이터 만료 시간으로 제한됩니다.
targets OR claimed OR recently-claimed OR unclaimed OR project NO timestamp와 snapshot이 협력해야 합니다. NOT APPLICABLE timestamp와 snapshot이 필요합니다. NOT APPLICABLE timestamp와 snapshot이 필요합니다.
(timestamp AND snapshot) AND project 예, root, targets 또는 bin 메타데이터 만료 시간 중 가장 이른 시간으로 제한됩니다. 예, root, targets 또는 bin 메타데이터 만료 시간 중 가장 이른 시간으로 제한됩니다.
(timestamp AND snapshot) AND (recently-claimed OR unclaimed) 예. 단, claimed가 위임하지 않은 프로젝트에 대해서만 해당합니다. 예, root, targets, claimed, recently-claimed, project 또는 unclaimed 메타데이터 만료 시간 중 가장 이른 시간으로 제한됩니다. 예, root, targets, claimed, recently-claimed, project 또는 unclaimed 메타데이터 만료 시간 중 가장 이른 시간으로 제한됩니다.
(timestamp AND snapshot) AND (targets OR claimed) 예, root, targets, claimed, recently-claimed, project 또는 unclaimed 메타데이터 만료 시간 중 가장 이른 시간으로 제한됩니다. 예, root, targets, claimed, recently-claimed, project 또는 unclaimed 메타데이터 만료 시간 중 가장 이른 시간으로 제한됩니다.
root

표 1: 역할 키의 특정 조합을 손상시켜 가능한 공격입니다. September 2013에 당시 pip의 최신 버전이 이러한 공격에 취약했으며 TUF가 이에 맞서 사용자를 보호할 수 있다는 사실이 밝혀졌습니다 [7]. 오프라인 키로 서명된 역할은 굵게 표시됩니다.

targets 또는 프로젝트 targets 메타데이터를 제외한 모든 위임된 역할을 손상시키더라도 공격자가 악성 업데이트를 제공할 수 있게 되지는 않는다는 점에 유의하십시오. 공격자는 timestampsnapshot 역할도 손상해야 합니다. 이 역할들은 모두 온라인 상태이므로 손상될 가능성이 더 높습니다. 이는 공격을 실행하려면 중간자 공격자 역할을 할 수 있어야 할 뿐 아니라 timestamp 키도 손상해야 한다는 의미입니다. 또는 root 키를 손상시킨 후 새로운 timestamp 키에 서명해야 합니다. 동결 공격 이외의 공격을 실행하려면 snapshot 키도 손상해야 합니다. 마지막으로 이러한 역할의 키가 온라인 상태이므로 PyPI 인프라가 손상되면 recently-claimed 프로젝트에 악성 업데이트를 도입할 수 있습니다.

키가 손상된 경우

키 손상이란 개발자 또는 PyPI의 역할에 속한 키가 임계 수만큼 손상되고 PyPI 인프라도 손상되어, 이를 사용해 PyPI에서 새로운 메타데이터에 서명한 상태를 의미합니다.

프로젝트의 개발자 키가 임계 수만큼 손상된 경우 프로젝트는 다음 단계를 반드시 수행해야 합니다.

  1. 프로젝트 메타데이터와 targets를 프로젝트가 손상된 것으로 알려지지 않았던 마지막으로 알려진 양호하고 일관된 스냅샷으로 반드시 복원해야 합니다. 개발자가 새로운 키로 모든 targets를 다시 패키징하고 재서명하여 이를 수행할 수 있습니다.
  2. 프로젝트의 메타데이터는 버전 번호를 증가시키고, 만료 시간을 적절히 연장하며, 서명을 갱신해야 합니다.

반면 PyPI는 다음 단계를 반드시 수행해야 합니다.

  1. 침해된 개발자 키를 recently-claimed 또는 claimed 역할에서 폐기하십시오. 이는 침해된 개발자 키를 새로 발행된 개발자 키로 교체하여 수행합니다.
  2. 새로운 타임스탬프가 기록된 일관된 스냅샷을 반드시 발행해야 합니다.

timestamp, snapshot, recently-claimed 또는 unclaimed 키가 임계 수만큼 침해된 경우, PyPI는 다음 단계를 반드시 수행해야 합니다.

  1. 루트 역할에서 timestamp, snapshottargets 역할 키를 폐기하십시오. 이는 침해된 timestamp, snapshottargets 키를 새로 발행된 키로 교체하여 수행합니다.
  2. targets 역할에서 recently-claimedunclaimed 키를 새로 발행된 키로 교체하여 폐기하십시오. 새 targets 역할 메타데이터에 서명한 후 새 키를 폐기하십시오(앞서 설명했듯이 이렇게 하면 targets 메타데이터의 보안이 향상되기 때문입니다).
  3. recently-claimed 역할의 모든 타깃 또는 위임을 삭제하고, 관련된 모든 위임된 targets 메타데이터를 삭제하십시오. 최근 등록된 프로젝트는 PyPI에 개발자 키를 다시 등록해야 합니다.
  4. recently-claimedunclaimed 역할의 모든 타깃을, timestamp, snapshot, recently-claimed 또는 unclaimed 키 중 어느 것도 침해된 것으로 알려지지 않았던 마지막으로 정상임이 확인된 일관된 스냅샷과 비교해야 합니다. 침해된 일관된 스냅샷에서 추가되거나 업데이트되거나 삭제된 타깃 중 마지막으로 정상임이 확인된 일관된 스냅샷과 일치하지 않는 타깃은 이전 버전으로 복원해야 합니다. 모든 unclaimed 타깃의 무결성을 확인한 후 unclaimed 메타데이터를 반드시 다시 생성해야 합니다.
  5. recently-claimedunclaimed 메타데이터의 버전 번호를 반드시 증가시키고, 만료 시간을 적절히 연장하며, 서명을 갱신해야 합니다.
  6. 새로운 타임스탬프가 기록된 일관된 스냅샷을 반드시 발행해야 합니다.

이렇게 하면 이들 역할 중 하나만 침해되었더라도 모든 역할을 선제적으로 보호할 수 있습니다.

targets 또는 claimed 키가 임계 수만큼 침해된 경우, timestampsnapshot 키 없이는 공격자가 할 수 있는 일이 거의 없습니다. 이 경우 PyPI는 침해된 targets 또는 claimed 키를 각각 roottargets 역할에서 새 키로 교체하여 단순히 폐기해야 합니다.

timestamp, snapshotclaimed 키가 임계 수만큼 침해된 경우, PyPI는 timestamp 또는 snapshot 키가 침해되었을 때 수행하는 단계에 더하여 다음 단계를 반드시 수행해야 합니다.

  1. targets 역할에서 claimed 역할 키를 폐기하고 새로 발행된 키로 교체하십시오.
  2. claimed 역할의 모든 프로젝트 타깃을, timestamp, snapshot 또는 claimed 키 중 어느 것도 침해된 것으로 알려지지 않았던 마지막으로 정상임이 확인된 일관된 스냅샷과 비교해야 합니다. 침해된 일관된 스냅샷에서 추가되거나 업데이트되거나 삭제된 타깃 중 마지막으로 정상임이 확인된 일관된 스냅샷과 일치하지 않는 타깃은 이전 버전으로 복원할 수 있습니다. 모든 claimed 프로젝트 타깃의 무결성을 확인한 후 claimed 메타데이터를 반드시 다시 생성해야 합니다.
  3. claimed 메타데이터의 버전 번호를 반드시 증가시키고, 만료 시간을 적절히 연장하며, 서명을 갱신해야 합니다.

이러한 단계를 수행하면 이들 역할 중 하나만 침해되었더라도 모든 역할을 선제적으로 보호할 수 있습니다.

root 키가 임계 수만큼 침해된 경우, PyPI는 targets 역할이 침해되었을 때 수행하는 단계를 반드시 수행해야 합니다. 모든 root 키도 반드시 교체해야 합니다.

PyPI가 보안 게시판(security bulletins)으로 침해 사항을 충분히 문서화하는 것도 권장됩니다. timestamp, snapshot, 또는 root 역할의 키가 더 이상 유효하지 않아 pip-with-TUF 사용자가 프로젝트를 설치하거나 업데이트할 수 없을 때, 이 보안 게시판이 가장 유용한 정보를 제공합니다. 그러면 사용자는 PyPI 웹사이트를 방문하여 왜 더 이상 설치하거나 업데이트할 수 없는지 설명해 주는 보안 게시판을 참고한 다음, 그에 따라 조치를 취할 수 있습니다. 침해로 인해 임계 개수의 root 키가 폐기되지 않은 경우, 기존 root 키 중 임계 개수가 새 root 메타데이터의 무결성 서명에 사용되므로, 새 root 메타데이터를 안전하게 업데이트할 수 있습니다. TUF 클라이언트는 이전에 알려진 root 키의 임계 개수로 새 root 메타데이터의 무결성을 검증할 수 있습니다. 이는 일반적인 경우가 될 것입니다. 임계 개수의 root 키가 침해로 인해 폐기된 최악의 경우, 최종 사용자는 out-of-band 메커니즘으로 새 root 메타데이터를 업데이트하는 방법을 선택할 수 있습니다.

부록 A: PyPI 빌드 팜과 종단 간 서명

PyPI 관리자는 중앙 빌드 팜을 지원할 계획입니다. PyPI 빌드 팜은 개발자가 업로드하는 각 배포판에 대해 PyPI 인프라 및 지원되는 플랫폼에서 Wheel을 자동 생성합니다. 패키지 관리자는 개발자가 서명한 소스 배포판보다는, (소스 배포판보다 훨씬 빠르게 설치할 수 있는) 이러한 PyPI Wheel을 다운로드하여 프로젝트를 설치할 가능성이 높습니다. 최대 보안 모델을 구현하기 전에 종단 간 서명을 갖춘 중앙 빌드 팜을 두는 것의 함의를 조사해야 합니다.

중앙 빌드 팜과 종단 간 서명의 한 가지 문제는, Wheel 배포판이 PyPI 인프라에서 생성되고 나면 개발자가 이를 서명할 가능성이 낮다는 점입니다. 그러나 Wheel 빌드가 결정적(deterministic) 프로세스라면, 개발자가 서명한 소스 배포판으로부터 Wheel을 생성하는 것은 여전히 유익할 수 있습니다. 결정적 빌드가 불가능한 경우, 개발자는 온라인 키로 Wheel에 서명하는 PyPI 역할에 이러한 Wheel에 대한 신뢰를 위임할 수 있습니다.

참고 문헌

감사의 말

이 자료는 국립과학재단(National Science Foundation)의 보조금 번호 CNS-1345049 및 CNS-0959138의 지원을 받은 연구를 기반으로 합니다. 이 자료에 표현된 모든 의견, 결과, 결론 또는 권고 사항은 저자(들)의 것이며, 반드시 국립과학재단의 견해를 반영하는 것은 아닙니다.

저희는 Alyssa Coghlan, Daniel Holth, Donald Stufft, Sumana Harihareswara, 그리고 distutils-sig 커뮤니티 전반에 감사드립니다. 이들은 TUF를 PyPI와 사용성 있고 효율적으로 통합하는 방법을 고민하는 데 도움을 주었습니다.

Roger Dingledine, Sebastian Hahn, Nick Mathewson, Martin Peck, Justin Samuel는 Tor 프로젝트의 전신인 Thandy로부터 TUF를 설계하는 데 도움을 주었습니다.

TUF를 개발하는 데 힘써준 Konstantin Andrianov, Geremy Condra, Zane Fisher, Justin Samuel, Tian Tian, Santiago Torres, John Ward, Yuyu Zheng에게 감사드립니다.