Skip to content

publish entire blog content to feed #13813

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

ewdurbin
Copy link
Member

i'm -1 here as it renders pretty poorly

Full render of rss feed underneath
  
<title>The Python Package Index</title>
<description>The official blog of the Python Package Index</description>
<link>http://0.0.0.0:8000/</link>
<atom:link href="http://0.0.0.0:8000/feed_rss_created.xml" rel="self" type="application/rss+xml" />



<docs>https://github.com/pypi/warehouse</docs>
<language>en</language>


<pubDate>Wed, 31 May 2023 01:37:27 -0000</pubDate>
<lastBuildDate>Wed, 31 May 2023 01:37:27 -0000</lastBuildDate>
<ttl>1440</ttl>


<generator>MkDocs RSS plugin - v1.6.0</generator>



<image>
  <url>https://blog.pypi.org/assets/logo.png</url>
  <title>The Python Package Index</title>
  <link>http://0.0.0.0:8000/</link>
</image>




<item>
  <title>Reducing Stored IP Data in PyPI</title>
  
  
    
  <author>Mike Fiedler</author>
    
  
  
  
    
  <category>security</category>
    
  <category>transparency</category>
    
  
  <description>&lt;div class=&#34;blogging-tags-grid&#34;&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#security&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#security&lt;/code&gt;&lt;/a&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#transparency&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#transparency&lt;/code&gt;&lt;/a&gt;

&lt;/div&gt;

<style>
.md-typeset .blogging-tags-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
margin-top: 5px;
}

.md-typeset .blogging-tag {
    color: var(--md-typeset-color);
    background-color: var(--md-typeset-code-color);
}

.md-typeset .blogging-tag code {
    border-radius: 5px;
}

</style>
<p>Hi there! I'm Mike, the newest member of the PyPI admin team. Nice to meet you!</p>
<h2>TL;DR</h2>
<p>We've been working on reducing the amount of IP address data we store,
and we're making progress.</p>
<h2>What's this about?</h2>
<p>If you've read some of the other blogs here, you may have noticed that
we've been working on a number of security and privacy improvements.</p>
<p>A few months ago we started exploring what it would take
to remove the concept of IP addresses from our stack,
and retain the ability to safely manage the platform.</p>
<p>Some places of where IP data was historically used:</p>
<ul>
<li>web access logs</li>
<li>user events (login,. logout, password reset, et al)</li>
<li>project events (creation, new releases, new file uploads, yanks, et al)</li>
<li>organization/team membership events (<a href="../2023-04-23-introducing-pypi-organizations">new!</a>)</li>
<li>journal entries (private to PyPI admins)</li>
</ul>
<p>Security is a spectrum - where on one extreme, it's the wild west, no security.
On the other extreme, everything is locked down, impossible to use.
We constantly have to balance the needs and desires of our users
with the needs of running a sustainable, trusted platform.</p>
<p>A similar mindset can be applied to privacy - where we must strike the balance
between providing a manageable service, and protecting the privacy of our users.</p>
<p>The two main approaches we've pursued in the short term are:</p>
<ul>
<li>Evaluate whether we need to store IP data at all</li>
<li>Whenever possible, use alternatives to IP data</li>
</ul>
<p>I'll provide a couple of examples demonstrating the above.</p>
<h2>Do we need the IP data?</h2>
<p>As we evaluated the different places we stored IP data,
we learned that our Journal entries (similar to an append-only transaction log)
were never exposed beyond admin users, and even then, used for admin display only.</p>
<p>We never share that via API, or used it for operational purposed.
So we audited the code, removed calls to stop writing the column, and dropped it.</p>
<p>Woohoo!</p>
<p>Other places where we currently still need IP data include rate limiting,
and fallbacks until we have backfilled the IP data with hashes and geo data.
Our modern approach has evolved from using the IP data at display time to find
the relevant geo data, to storing the geo data directly in the database.</p>
<p>Another use case is for handling abuse - we need to be able to identify
the source of abuse, and take action to prevent it.
We're thinking about how to manage that without storing IP data,
but we're not there yet.</p>
<h2>Alternatives to IP data</h2>
<p>For the other places where we stored IP data,
we asked ourselves - could we use an alternative?</p>
<p>We can't store what we don't see, so we explored what we could do to
reduce the amount of IP data we see.</p>
<p>Pretty much every request to PyPI is served via our CDN partner, Fastly.
They provide a number of features, including the ability to
<a href="https://docs.fastly.com/en/guides/adding-or-modifying-headers-on-http-requests-and-responses&#34;&gt;add custom headers</a>.
We leverage this ability already for a number of things,
like informing the warehouse code of the inbound encoding of the request or language.</p>
<p>We explored whether we could use this to add a hash of the IP address,
and use that instead of the IP address itself.
Fastly can also provide some basic geographic info about the IP address,
which served our purpose of showing the user where they had connected from.</p>
<p>Using this approach, we have Fastly pass along an already-hashed IP address,
as well as the geographic data, to our backend, and store those for later use.</p>
<p>Another spot we identified was web access logs.
We don't need real IP addresses there,
as we rarely use them for anything other than low-level debugging,
so a stable, hashed value serves the purpose of correlating requests.</p>
<p>For the requests that Fastly doesn't serve, we're already hashing the IP address
ourselves prior to storage, so we could "see" the IP address briefly,
but we try to avoid storing it.
We don't get get the geo data for these requests,
we're thinking of creative and sustainable solutions already.</p>
<h2>Questions and Answers</h2>
<p>I tried to think up some questions you might have, and answer them here.
If you have more, please feel free to reach out to us!</p>
<p><strong>Q:</strong> Is a hashed IP address secure?</p>
<p><strong>A:</strong> It's more secure than a plain IP address, for sure.
We apply a <a href="https://en.wikipedia.org/wiki/Salt_(cryptography)&#34;&gt;salt&lt;/a> (known value)
to the IP address before hashing it.
It's not a perfect solution, but it's a step in the right direction.</p>
<p>The hash is non-reversible, but since the known address space is relatively small,
it's possible to brute force the hash to determine the original IP address.
By applying a salt, we require someone to possess <strong>both</strong> the salt
and the hashed IP addresses to brute force the value.
Our salt is not stored in the database while the hashed IP addresses are,
we protect against leaks revealing this information.</p>
<p><strong>Q:</strong> Is this a response to the subpoenas?</p>
<p><strong>A:</strong> No, we started exploring this <a href="#8158 in 2020</a>,
with a long term goal to increase end-user security,
while retaining the ability to effectively steer the platform.
We picked it up recently as we explored our CDN partner's options for geo IP data.</p>
<p><strong>Q:</strong> Are we done?</p>
<p><strong>A:</strong> Nope! Security is an ongoing journey,
and we're making strong strides to accomplish this goal.
We still have some work to do to replace IP data in our models,
after we've backfilled our models with the hashed IP data and relevant geo data,
and clean up some of the code.</p>
<p><strong>Q:</strong> What's next?</p>
<p><strong>A:</strong> I can't predict every future step we're likely to take,
but some things we're considering:</p>
<ul>
<li>Reevaluate the need for IP data in Event history <strong>forever</strong>,
remove it after a period of time</li>
<li>Explore whether we can use a CDN for all requests</li>
<li>Determine if there's a better mechanism than Journal Entries, and replace them</li>
</ul>
<p>We believe the steps we're taking are in the right direction,
and we're excited to share our progress with you.
Hopefully this enriches your understanding of the work we're doing,
in support of maintaining a secure, trusted platform.</p>
<p>Thanks for reading!</p>
<hr>
<p><em>Mike Fiedler is a PyPI administrator
and maintainer of the Python Package Index since 2022.</em></p>
http://0.0.0.0:8000/posts/2023-05-26-reducing-stored-ip-data/
Fri, 26 May 2023 15:00:00 +0000
The Python Package Index

  <guid isPermaLink="true">http://0.0.0.0:8000/posts/2023-05-26-reducing-stored-ip-data/</guid>
  
</item>

<item>
  <title>Securing PyPI accounts via Two-Factor Authentication</title>
  
  
    
  <author>Donald Stufft</author>
    
  
  
  
    
  <category>2fa</category>
    
  <category>security</category>
    
  
  <description>&lt;div class=&#34;blogging-tags-grid&#34;&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#security&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#security&lt;/code&gt;&lt;/a&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#2fa&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#2fa&lt;/code&gt;&lt;/a&gt;

&lt;/div&gt;

<style>
.md-typeset .blogging-tags-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
margin-top: 5px;
}

.md-typeset .blogging-tag {
    color: var(--md-typeset-color);
    background-color: var(--md-typeset-code-color);
}

.md-typeset .blogging-tag code {
    border-radius: 5px;
}

</style>
<p>One of the key security promises that PyPI makes is that when you're downloading
something, that only the people associated with that project are going to be able
to upload, delete, or otherwise modify a project. That when you look at that
project and see that it is owned by someone that you trust, that you can be
assured that nobody else is making changes to that package on PyPI.</p>
<p>This promise is predicated on the security of each and every individual account
on PyPI used to create and maintain a Python project. In the past we've taken
steps to safeguard these accounts by
<a href="https://caremad.io/posts/2018/08/pypi-compromised-passwords/&#34;&gt;blocking compromised passwords</a>, strong 2FA support using
<a href="#5567> and
<a href="#5795>,
<a href="https://pypi.org/help/#apitoken&#34;&gt;support for API tokens with offline attenuation</a>,
<a href="https://pypi.org/security-key-giveaway/&#34;&gt;enrolling the most downloaded projects into mandatory 2FA</a>,
and <a href="https://blog.pypi.org/posts/2023-04-20-introducing-trusted-publishers/&#34;&gt;enabling short lived tokens for upload</a>.</p>
<p>Today, as part of that long term effort to secure the Python ecosystem, we are
announcing that <em>every</em> account that maintains any project or organization
on PyPI will be required to enable 2FA on their account by the end of 2023.</p>
<p>Between now and the end of the year, PyPI will begin gating access to certain
site functionality based on 2FA usage. In addition, we may begin selecting
certain users or projects for early enforcement.</p>
<h2>What can I do to prepare?</h2>
<p>The most important things you can do to prepare are to enable 2FA for your
account as soon as possible, either with a
<a href="https://pypi.org/help/#utfkey&#34;&gt;security device</a> (preferred) or an
<a href="https://pypi.org/help/#totp&#34;&gt;authentication app</a> and to switch to using either
<a href="https://docs.pypi.org/trusted-publishers/&#34;&gt;Trusted Publishers</a> (preferred) or
<a href="https://pypi.org/help/#apitoken&#34;&gt;API tokens</a> to upload to PyPI.</p>
<h2>Why Use 2FA?</h2>
<p>Account takeover attacks typically stem from someone using an insecure password:
perhaps it was easy to guess, or it was reused and appeared in a breach. With
that insecure password, an attacker is able to gain control over a maintainers
account and begin to take actions as if they were that user.</p>
<p>This is particularly problematic on a site like PyPI, where the actions that a
person can take include releasing software that might be used by people world
wide, allowing an attacker to install and execute software on unsuspecting
user's computers. <a href="https://python-security.readthedocs.io/pypi-vuln/index-2022-05-24-ctx-domain-takeover.html&#34;&gt;Account takeover attacks have been previously used to
compromise PyPI users in this
way</a>.</p>
<p>Two-factor authentication immediately neutralizes the risk associated with a
compromised password. If an attacker has someone's password, that is no longer
enough to give them access to that account.</p>
<h2>Why every project or organization maintainer?</h2>
<p>There's two ways to think about this question:</p>
<ul>
<li>Why every project and organization maintainer instead of just some subset of
them (based on popularity, purpose, whether that user uses their account,
etc)?</li>
<li>Why only maintainers and not every single user?</li>
</ul>
<p>Not every account on PyPI has the same value to an attacker. An account with
access to the most downloaded project on PyPI can be used to attack far more
people than an account with access to the least downloaded project.</p>
<p>However, it only takes one compromised project in someone's dependency set to
compromise their computer. The attacker doesn't care if they get you from a
widely used or a niche project, just that they got you. Even worse, once
compromised, an attacker can extend that attack to attack <em>other</em> systems,
including other projects on PyPI that the now compromised person maintains.</p>
<p>Given that it only takes one compromised project, no matter how many downloads
it gets [^1], to compromise someone we want to ensure that every project is
being protected by 2FA.</p>
<p>On the flipside, an account without access to any project cannot be used to
attack anyone 1 so it is a very low value target.</p>
<p>We recognize that enabling 2FA for an account imposes a non zero cost both for
the owner of that account <em>and</em> for PyPI 2, so forcing that on accounts that
cannot affect anyone but themselves is not an effective use of limited
resources. In addition, from a practical view, the standard 2FA flow that most
people are used to and that PyPI implements also involves adding a 2FA token
to an existing account rather than forcing it to be part of the registration
flow.</p>
<p>Our expectation is that for users who currently are not a project maintainer or
organization member, the ultimate experience will be whenever they attempt to
take some action that would require them to add 2FA (creating a new project,
accepting an invite, making an organization, etc) they will be prompted to add
2FA to their account before they can proceed.</p>
<h2>Why now?</h2>
<p>The direction of many projects in or serving the Open Source community in the
last 5-10 years has been an increasing focus on supply chain security,
preventing attacks that are being delivered through the "supply chain", namely
the services and tooling used to create and consume software.</p>
<p>In July of 2022, we announced
<a href="https://pypi.org/security-key-giveaway/&#34;&gt;a security key giveway</a> in conjunction
with a plan to begin mandating 2FA for the top 1% of projects on PyPI by download
count.</p>
<p>The initial announcement of that mandate to the top 1%
of projects and the related giveaway was met with mixed reactions, ranging from
people applauding the effort to people deciding to distribute their code on
places other than PyPI. We planned to limit this to the projects in the top 1%
of downloads because those are likely he highest value targets for an attacker,
and because we were concerned about the impact of such a mandate on both the
maintainers of projects on PyPI, and on the support burden of the PyPI team
itself.</p>
<p>At that time last year, we did not have any plans or expectations on widening
our net of users that would fall under that mandate, other than would occur
naturally as projects rose in popularity to be part the top 1%.</p>
<p>However, in the year since then a few things have changed.</p>
<ul>
<li>We've gotten a lot more confident in our 2FA implementation and in what the
impact to enabling it is for both people publishing to PyPI, and to the PyPI
team itself.</li>
<li>We've shipped features like
<a href="https://docs.pypi.org/trusted-publishers/&#34;&gt;Trusted Publishing</a> that help
remove some of the overheard of 2FA has on publishing (by far the most common
action users do).</li>
<li>GitHub has furthered it's
<a href="https://github.blog/2022-05-04-software-security-starts-with-the-developer-securing-developer-accounts-with-2fa/&#34;&gt;plans to mandate 2FA for all contributors</a>
on their platform, making more people already (or soon will be) prepared to cope
with the requirements of having 2FA.</li>
<li>The PSF has received funding to hire a
<a href="https://blog.pypi.org/posts/2023-05-09-announcing-pypi-safety-and-security-engr-role/&#34;&gt;PyPI Safety and Security Engineer</a>.
While the role is not meant to purely handle support requests, having
dedicated focus on the overall security posture, as well as the
implementation specifics will improve PyPI as a whole for both
users and project maintainers, and will help alleviate some of the
pressures on PyPI's volunteers.</li>
<li>The workload to support end users relies heavily on a very small group of
volunteers. When an user account report is seen by our trusted admins, we have
to take time to properly investigate. These are often reported as an emergency,
red-alert-level urgency. By mandating 2FA for project maintainers, the
likelihood of account takeovers drop significantly, reserving the emergency
status for truly extraordinary circumstances. Account recovery becomes part of
normal routine support efforts instead of admin-level urgency.</li>
</ul>
<p>All of these together help lead us to the conclusion that we can widen our
mandate to <em>all</em> project maintainers on PyPI, while minimizing the impact on
both project maintainers and PyPI administrators, and to do so in a way that
improves the sustainability of PyPI and the wider Python ecosystem.</p>
<h2>Isn't supply chain security a corporate concern?</h2>
<p>There are some people who believe that efforts to improve supply chain security
benefits only corporate or business users, and that individual developers should
not be asked to take on a uncompensated burden for their benefit.</p>
<p>We believe this is shortsighted.</p>
<p>A compromise in the supply chain can be used to attack individual developers the
same as it able to attack corporate and business users. In fact, we believe
that individual developers, are in a <em>more</em> vulnerable position than corporate
and business users. While businesses are generally able to hire staff and devote
resources to vetting their dependencies, individual developers generally are
not, and must expend their own limited free time to do so 3.</p>
<p>To make matters worse for the individual, in the case of a compromise a business
is more likely going to have experts available to them to detect and remediate
the compromise, while the individual has to do this on their own. At the extreme
ends, businesses often have insurance to compensate them for any losses incurred
while the individual almost always does not.</p>
<p>We recognize that supply chain security effects <em>everyone</em>, no matter how big
or how small they are, and we are dedicated to protecting <em>all</em> our users.</p>
<hr>
<p><em>Donald Stufft is a PyPI administrator and maintainer of the Python Package Index since 2013.</em></p>
<p>[^1]: <em>Technically</em> a project with 0 downloads is effectively the same as a
non-existent project, but it's easier to draw the line between
non-existent and existent than it is to draw the line between 0 and 1
downloads. This is particularly true on PyPI, where a large network of
mirrors and scanners mean that <em>no</em> projects truly get downloaded exactly
0 times.

<style>
.md-typeset .blogging-tags-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
margin-top: 5px;
}

.md-typeset .blogging-tag {
    color: var(--md-typeset-color);
    background-color: var(--md-typeset-code-color);
}

.md-typeset .blogging-tag code {
    border-radius: 5px;
}

</style>
<p>In March and April 2023, the Python Software Foundation (PSF)
received three (3) subpoenas for PyPI user data.
All three subpoenas were issued by the United States Department of Justice.
The PSF was not provided with context on the legal circumstances surrounding these subpoenas.
In total, user data related to five (5) PyPI usernames were requested.</p>
<p>The data request was:</p>
<ol>
<li>"Names (including subscriber names, user names, and screen names);"</li>
<li>"Addresses (including mailing, residential addresses, business addresses, and email addresses);"</li>
<li>"Connection records;"</li>
<li>"Records of session times and durations, and the temporarily assigned network address (such as Internet Protocol addresses) associated with those sessions;"</li>
<li>"Length of service (including start date) and type of services utilized;"</li>
<li>"Telephone or instrument numbers (including the registration Internet Protocol address);"</li>
<li>"Means and source of payment of any such services (including any credit card or bank account number) and billing records;"</li>
<li>"Records of all Python Package Index (PyPI) packages uploaded by..." given usernames</li>
<li>"IP download logs of any Python Package Index (PyPI) packages uploaded by..." given usernames</li>
</ol>
<p>The privacy of PyPI users is of utmost concern to PSF and the PyPI Administrators,
and we are committed to protecting user data from disclosure whenever possible.
In this case, however, PSF determined with the advice of counsel that
our only course of action was to provide the requested data.
I, as Director of Infrastructure of the Python Software Foundation,
fulfilled the requests in consultation with PSF's counsel.</p>
<p>We have waited for the string of subpoenas to subside, though we were committed
from the beginning to write and publish this post as a matter of transparency,
and as allowed by the lack of a non-disclosure order associated with the
subpoenas received in March and April 2023.</p>
<h2>Next Steps</h2>
<p>PyPI and the PSF are committed to the freedom, security, and privacy of our users.</p>
<p>This process has offered time to revisit our current data and privacy standards,
which are minimal, to ensure they take into account the varied interests of
the Python community.
Though we collect very little personal data from PyPI users,
any unnecessarily held data are still subject to these kinds of requests
in addition to the baseline risk of data compromise via malice or operator error.</p>
<p>As a result we are currently developing new data retention and disclosure policies.
These policies will relate to
our procedures for future government data requests,
how and for what duration we store personally identifiable information such as
user access records,
and policies that make these explicit for our users and community.</p>
<p>Please continue to watch this blog for related announcements as policies
are finalized, published, and implemented.</p>
<hr>
<h2>Details</h2>
<p>In order to provide as much transparency as possible,
the following will detail the shape of and extent of
the data that was contained in the responses to these subpoenas.</p>
<p>We will not be releasing the usernames involved publicly
or to the users themselves.</p>
<h3>1) Names (including subscriber names, user names, and screen names);</h3>
<p>These were confirmed via our database records</p>
<p><code>sql
select id, username, name from users where username = '{USERNAME}';</code></p>
<p>Returning:
<code>id | UUID for USERNAME
username | PyPI username
name | Display name for user</code></p>
<p>And are also publicly available at <code>https://pypi.org/user/{USERNAME}/&lt;/code&gt;.&lt;/p>
<p>PyPI allows users to delete their accounts.</p>
<p>PyPI does not allow for the <code>username</code> field to be changed without admin intervention,
and no such intervention has occurred for the users in question.
If they had, we would have provided records of those changes.</p>
<p>PyPI does allow for user to update their display names
and keeps no record of the history of these changes.</p>
<h3>2) Addresses (including mailing, residential addresses, business addresses, and email addresses);</h3>
<p>PyPI only stores email addresses for individual users. No physical addresses are stored.
Organization accounts who have signed up for billing (not yet live)
will be required to provide a billing address that validates to their payment method.</p>
<p>These were sourced from our database records and is private to PyPI.</p>
<p><code>sql
select email, user_id from user_emails where user_id ='{UUID for USERNAME}';</code></p>
<p>Returning:
<code>email | An email address
user_id | UUID for USERNAME</code></p>
<p>PyPI allows for users to add and remove email addresses without admin intervention.
Records of these changes are kept, and no such changes were observed in our records for
the usernames in question.
If they had, we would have provided records of those changes.</p>
<h3>3. Connection records</h3>
<h4>3a. Project events</h4>
<p>PyPI retains records of all changes to projects on the index,
and has since <code>2002-11-01 17:11:36 UTC</code>.</p>
<p>These were confirmed via our database records</p>
<p><code>sql
select * from journals where submitted_by='{USERNAME}' order by submitted_date;</code></p>
<p>Returning:
<code>id | An auto incrementing integer representing the "Serial"
name | Name of a PyPI Project
version | Version of a PyPI Release if relevant
action | Description of the action taken against the Project/Release
submitted_date | ISO-8601 datetime in UTC
submitted_by | PyPI Username
submitted_from | IP Address</code></p>
<p>and with the exception of the <code>submitted_by</code> (PyPI username)
and <code>submitted_from</code> (IP Address) columns
are publicly available via our <a href="https://warehouse.pypa.io/api-reference/xml-rpc.html#changelog-since-with-ids-false&#34;&gt;XMLRPC API</a>.</p>
<h4>3b. User events</h4>
<p>PyPI retains records of critical user events including
account creation, emails sent, email address changes, logins, and login failures.
See <a href="https://github.com/pypi/warehouse/blob/9738ebb2ffcee91a935a6a11b224575aaf02a878/warehouse/events/tags.py#L61-L106&#34;&gt;this list</a>
for the comprehensive set of events recorded.</p>
<p>These were sourced from our database records</p>
<p><code>sql
select * from user_events where source_id = '{UUID for USERNAME}' order by time desc;</code></p>
<p>Returning:
<code>id | UUID of the event
source_id | UUID for USERNAME
tag | EventTag
time | ISO-8601 datetime in UTC
ip_address_string | IP Address
additional | JSONB metadata about the event
ip_address_id | UUID of associated IPAddress object</code></p>
<p>and are private to PyPI.</p>
<h3>4. Records of session times and durations, and the temporarily assigned network address (such as Internet Protocol addresses) associated with those sessions;</h3>
<p>PyPI does not record session durations.</p>
<p>Session creation (Login) times were provided as a synopsis of the data in 3b.</p>
<p>Sessions are not created for uploads, but the associated login events
for project uploads were provided as a synopsis of the data in 3a.</p>
<h3>5. Length of service (including start date) and type of services utilized;</h3>
<p>PyPI retains records of the date that a user account was created,
as well as the last time it was successfully logged in by any method
(web UI or command line tool for upload).</p>
<p><code>sql
select date_joined, last_login from users where username = {USERNAME}</code></p>
<p>Returning:
<code>date_joined | ISO-8601 datetime in UTC
last_login | ISO-8601 datetime in UTC</code></p>
<p>These were sourced from our database records and are private to PyPI.</p>
<p>Types of service utilized are "standard" to PyPI and include the ability to
create projects, releases, and distribution files for downloads.</p>
<h3>6. Telephone or instrument numbers (including the registration Internet Protocol address);</h3>
<p>A synopsis of all IP Addresses for each username from previous records were shared.</p>
<p>These were sourced from our database records and are private to PyPI.</p>
<h3>7. Means and source of payment of any such services (including any credit card or bank account number) and billing records;</h3>
<p>PyPI has no cost to use for individual users
and no such payment records or billing records exist.</p>
<h3>8. Records of all Python Package Index (PyPI) packages uploaded by the given usernames</h3>
<p>A list of all past and any current projects associated with each username was provided.</p>
<p>These were sourced from our database records and for past projects, are private to PyPI.</p>
<h3>9. IP download logs of any Python Package Index (PyPI) packages uploaded by the given usernames</h3>
<p>PyPI does not retain download logs for packages which include IP addresses.
Download logs are processed by a pipeline which includes GeoIP information reported by our CDN only.</p>
<p>These records were sourced from the <a href="https://warehouse.pypa.io/api-reference/bigquery-datasets.html&#34;&gt;Google BigQuery Public dataset</a> with the following queries:</p>
<p><code>sql
SELECT * FROM bigquery-public-data.pypi.file_downloads
WHERE project IN ({LIST OF PROJECT NAMES FROM 8})
AND timestamp &gt; '{START OF PERIOD IN QUESTION}';</code></p>
<hr>
<p><em>Ee Durbin is the Director of Infrastructure at
the Python Software Foundation.
They have been contributing to keeping PyPI online, available, and
secure since 2013.</em></p>
http://0.0.0.0:8000/posts/2023-05-24-pypi-was-subpoenaed/
Wed, 24 May 2023 13:12:00 +0000
The Python Package Index

  <guid isPermaLink="true">http://0.0.0.0:8000/posts/2023-05-24-pypi-was-subpoenaed/</guid>
  
</item>

<item>
  <title>Removing PGP from PyPI</title>
  
  
    
  <author>Donald Stufft</author>
    
  
  
  
    
  <category>security</category>
    
  
  <description>&lt;div class=&#34;blogging-tags-grid&#34;&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#security&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#security&lt;/code&gt;&lt;/a&gt;

&lt;/div&gt;

<style>
.md-typeset .blogging-tags-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
margin-top: 5px;
}

.md-typeset .blogging-tag {
    color: var(--md-typeset-color);
    background-color: var(--md-typeset-code-color);
}

.md-typeset .blogging-tag code {
    border-radius: 5px;
}

</style>
<p>If you are someone who is currently uploading signatures, your package uploads will
continue to succeed, but any PGP signatures will be silently ignored. If you are
someone who is currently downloading PGP signatures, existing signatures
<em>SHOULD</em> continue to be available [^1], but no new signatures will be made available.
The related API fields such as <code>has_sig</code> have all been hardcoded to always be
<code>False</code>.</p>
<p>Historically, PyPI has supported uploading PGP signatures alongside the release
artifacts in an attempt to provide some level of package signing. However, the
approach used had long standing,
<a href="https://caremad.io/posts/2013/07/packaging-signing-not-holy-grail/&#34;&gt;documented issues</a>
which had previously lead us to deemphasize the support
for PGP signatures over time by removing them from the PyPI web user interface.</p>
<p>PyPI has continued to support uploading these signatures in the hope that there
might be some systems out there that found them useful. Recently though,
<a href="https://blog.yossarian.net/2023/05/21/PGP-signatures-on-PyPI-worse-than-useless&#34;&gt;an examination of the signatures on PyPI</a>
has revealed to us that the current support for PGP signatures is not proving useful.</p>
<p>In the last 3 years, about 50k signatures had been uploaded to PyPI by 1069
unique keys. Of those 1069 unique keys, about 30% of them were not discoverable
on major public keyservers, making it difficult or impossible to meaningfully
verify those signatures. Of the remaining 71%, nearly half of them were unable
to be meaningfully verified at the time of the audit (2023-05-19) 1.</p>
<p>In other words, out of all of the unique keys that had uploaded signatures to
PyPI, only 36% of them were capable of being meaningfully verified 2 at the
time of audit. Even if <em>all</em> of those signatures uploaded in that 3 year period
of time were made by one of those 36% of keys that are able to be meaningfully
verified, that would still represent only 0.3% of all of those files.</p>
<p>Given all of this, the continued support of uploading PGP signatures to PyPI is
no longer defensible. While it doesn't represent a <em>massive</em> operational burden
to continue to support it, it does require any new features that touch the
storage of files to be made aware of and capable of handling these PGP
signatures, which is a non zero cost on the maintainers and contributors of
PyPI.</p>
<hr>
<p><em>Donald Stufft is a PyPI administrator and maintainer of the Python Package Index since 2013.</em></p>
<p>[^1]: For now, but they may be removed in the future.

<style>
.md-typeset .blogging-tags-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
margin-top: 5px;
}

.md-typeset .blogging-tag {
    color: var(--md-typeset-color);
    background-color: var(--md-typeset-code-color);
}

.md-typeset .blogging-tag code {
    border-radius: 5px;
}

</style>
<p>We are pleased to announce
Amazon Web Services (AWS)
as the inaugural Security Sponsor for PyPI,
investing $144,000 over one year
to fund key enhancements to PyPI infrastructure and operations,
including the creation of a new “PyPI Safety &amp; Security Engineer” role. </p>
<p>This role builds on our existing long term partnership with AWS
as one of the top sponsors of the Python Software Foundation for the last five years,
which has included in-kind donations of cloud computing infrastructure
and services to support PyPI.
The role will complement our previously announced role for a
<a href="https://pyfound.blogspot.com/2023/01/the-psf-is-hiring-security-developer-in.html&#34;&gt;PSF Security Developer in Residence</a>
and will work closely with the person hired for that role (to be announced soon).</p>
<p>This funding also builds on
<a href="https://dustingram.com/articles/2021/04/14/powering-the-python-package-index-in-2021/#project-funding&#34;&gt;previously successful project-focused funding efforts</a>,
such as the 2018 full-stack rewrite of PyPI,
the introduction of internationalization and localization for PyPI,
as well as 2FA and WebAuthn support.</p>
<p>We expect this partnership to tangibly improve the experience for all PyPI users,
from consumers downloading packages,
to package maintainers,
to large corporate teams.
Some of the outcomes we are working toward over the next year include
increased support for package maintainers including multi-maintainer projects,
improvements to reporting infrastructure for malicious projects,
as well as a reduced response time for malware reports and account recovery requests.</p>
<p><a href="https://jobs.pyfound.org/apply/CKEONredws/PyPI-Safety-Security-Engineer&#34;&gt;The job posting can be found here</a>,
and applications for the role are open until June 1st.
Similar to existing developer-in-residence roles,
the contract for this role will be for a one year period,
and the PSF will be actively engaging with our sponsors and supporters
to renew funding for the role in subsequent years.</p>
<hr>
<p><em>Ee Durbin is the Director of Infrastructure at
the Python Software Foundation.
They have been contributing to keeping PyPI online, available, and
secure since 2013.</em></p>
http://0.0.0.0:8000/posts/2023-05-09-announcing-pypi-safety-and-security-engr-role/
Tue, 09 May 2023 00:00:00 +0000
The Python Package Index

  <guid isPermaLink="true">http://0.0.0.0:8000/posts/2023-05-09-announcing-pypi-safety-and-security-engr-role/</guid>
  
</item>

<item>
  <title>Introducing PyPI Organizations</title>
  
  
    
  <author>Ee Durbin</author>
    
  
  
  
    
  <category>organizations</category>
    
  <category>sustainability</category>
    
  
  <description>&lt;div class=&#34;blogging-tags-grid&#34;&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#organizations&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#organizations&lt;/code&gt;&lt;/a&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#sustainability&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#sustainability&lt;/code&gt;&lt;/a&gt;

&lt;/div&gt;

<style>
.md-typeset .blogging-tags-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
margin-top: 5px;
}

.md-typeset .blogging-tag {
    color: var(--md-typeset-color);
    background-color: var(--md-typeset-code-color);
}

.md-typeset .blogging-tag code {
    border-radius: 5px;
}

</style>
<p>Today, we are rolling out the first step in our plan to build financial
support and long-term sustainability of the Python Packaging Index (PyPI),
while simultaneously giving our users one of our most requested features:
organization accounts.</p>
<h3>Introducing Organizations</h3>
<p>Organizations on PyPI are self-managed teams, with their own exclusive branded
web addresses. Our goal is to make PyPI easier to use for large community
projects, organizations, or companies who manage multiple sub-teams and multiple
packages. We’re making organizations available to community projects for free,
forever, and to corporate projects for a small fee. Additional priority support
agreements will be available to all paid subscribers, and all revenue will go
right back into PyPI to continue building better support and infrastructure
for all our users.</p>
<h3>Increasing sustainability and support</h3>
<p>In the last year PyPI served 235.7 billion downloads for the 448,941 projects hosted
there. This means that since the previous period, PyPI saw a 57% annual growth in download counts
and bandwidth alike. Having more people using and contributing to Python every
year is an fantastic problem to have, but it is one we must increase
organizational capacity to accommodate.</p>
<p>Increased revenue for PyPI allows it to become a
staffed platform that can respond to support requests and attend to issues
in a timeframe that is significantly faster than what our excellent (but thinly
spread) largely volunteer team could reasonably handle.</p>
<h3>Organizations are opt-in</h3>
<p>We want to be very clear—these new features are completely optional. If
features for larger projects don't sound like something that would be useful to
you as a PyPI maintainer, then there is no obligation to create an organization
and absolutely nothing about your PyPI experience will change for you.</p>
<h3>A basis for future features</h3>
<p>We look forward to discussing what other features PyPI users would like to see
tackled next. We know there are lots of ideas out there around safety,
security and usability and we’re looking forward to hearing about anything that
you think would benefit the community. And in the spirit of open source, <a href="https://github.com/pypi/warehouse/issues&#34;&gt;we
welcome your feedback</a> on what's on
offer so far.</p>
<h3>Get started today</h3>
<p>Both community projects (non-profits, NGO’s, hobbyists, etc) and corporate
teams can <a href="https://pypi.org/manage/organizations/&#34;&gt;sign up to request their organization name starting
today</a>. Submissions will begin
seeing review and approval in the coming weeks, and corporate teams will be
able to finalize their signup with billing details in May.</p>
<h3>Acknowledgements</h3>
<p>Organization feature development was approved by the
<a href="https://wiki.python.org/psf/PackagingWG&#34;&gt;Packaging Working Group</a>
and funded through the
<a href="https://www.python.org/psf-landing/&#34;&gt;Python Software Foundation</a>'s
sponsorship program -- thanks to our <a href="https://pypi.org/sponsors/&#34;&gt;sponsors&lt;/a>
for making this work possible.</p>
<p>We especially want to thank
<a href="https://www.bloomberg.com/company/values/tech-at-bloomberg/?ea-publisher=psf&#34;&gt;Bloomberg&lt;/a>
for funding our Packaging Project Manager, Shamika Mohanan.</p>
<p>We are also grateful for the many generous PyPI users who shared their
perspectives with Shamika, which laid the foundation for these new features.</p>
<p>And thanks as well to our beta
testers, including the following ✨new✨ PyPI organizations:</p>
<ul>
<li>Python Cryptographic Authority (<a href="https://pypi.org/org/pyca/&#34;&gt;https://pypi.org/org/pyca/&lt;/a&gt;)&lt;/li>
<li>The Pallets Project (<a href="https://pypi.org/org/pallets/&#34;&gt;https://pypi.org/org/pallets/&lt;/a&gt;)&lt;/li>
<li>certifi (<a href="https://pypi.org/org/certifi&#34;&gt;https://pypi.org/org/certifi&lt;/a&gt;)&lt;/li>
</ul>
<hr>
<p><em>Ee Durbin is the Director of Infrastructure at
the Python Software Foundation.
They have been contributing to keeping PyPI online, available, and
secure since 2013.</em></p>
http://0.0.0.0:8000/posts/2023-04-23-introducing-pypi-organizations/
Sun, 23 Apr 2023 00:00:00 +0000
The Python Package Index

  <guid isPermaLink="true">http://0.0.0.0:8000/posts/2023-04-23-introducing-pypi-organizations/</guid>
  
</item>

<item>
  <title>Introducing &#39;Trusted Publishers&#39;</title>
  
  
    
  <author>Dustin Ingram</author>
    
  
  
  
    
  <category>oidc</category>
    
  <category>publishing</category>
    
  <category>security</category>
    
  
  <description>&lt;div class=&#34;blogging-tags-grid&#34;&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#publishing&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#publishing&lt;/code&gt;&lt;/a&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#security&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#security&lt;/code&gt;&lt;/a&gt;

    &lt;a href=&#34;http://0.0.0.0:8000/tags#oidc&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#oidc&lt;/code&gt;&lt;/a&gt;

&lt;/div&gt;

<style>
.md-typeset .blogging-tags-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
margin-top: 5px;
}

.md-typeset .blogging-tag {
    color: var(--md-typeset-color);
    background-color: var(--md-typeset-code-color);
}

.md-typeset .blogging-tag code {
    border-radius: 5px;
}

</style>
<p>Starting today, PyPI package maintainers can adopt a new, more secure
publishing method that does not require long-lived passwords or API tokens to
be shared with external systems.</p>
<h3>About trusted publishing</h3>
<p>"Trusted publishing" is our term for using the <a href="https://openid.net/connect/&#34;&gt;OpenID Connect (OIDC)</a> standard
to exchange short-lived identity tokens between a trusted third-party service
and PyPI. This method can be used in automated environments and eliminates the
need to use username/password combinations or manually generated API tokens to
authenticate with PyPI when publishing.</p>
<p>Instead, PyPI maintainers can configure PyPI to trust an identity provided by a
given OpenID Connect Identity Provider (IdP). This allows allows PyPI to verify
and delegate trust to that identity, which is then authorized to request
short-lived, tightly-scoped API tokens from PyPI. These API tokens never need
to be stored or shared, rotate automatically by expiring quickly, and provide a
verifiable link between a published package and its source.</p>
<h3>Using trusted publishing with GitHub Actions</h3>
<p>PyPI currently supports trusted publishing with GitHub Actions, using <a href="https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect&#34;&gt;their
support for OpenID Connect</a>.</p>
<p>After configuring PyPI to trust a given GitHub repository and workflow, users
of the PyPA's <a href="https://github.com/marketplace/actions/pypi-publish&#34;&gt;&#39;pypi-publish&#39; GitHub Action</a> can adopt trusted publishing by
removing the <code>username</code> and <code>password</code> fields from their workflow
configuration, and adding permissions to generate an identity token:</p>
<p>```diff
jobs:
pypi-publish:
name: upload release to PyPI
runs-on: ubuntu-latest

  • permissions:
  •  # IMPORTANT: this permission is mandatory for trusted publishing
    
  •  id-token: write
    
    steps:
    # retrieve your distributions here</p>
    <pre><code> - name: Publish package distributions to PyPI
    uses: pypa/gh-action-pypi-publish@release/v1
    </code></pre>
    <ul>
    <li>with:</li>
    <li>username: <strong>token</strong></li>
    <li>password: ${{ secrets.PYPI_TOKEN }}
&lt;/ul&gt;
&lt;p&gt;Using the PyPA&#39;s GitHub action is strongly recommended, but not required. More
details on how to manually exchange tokens are available &lt;a href=&#34;https://docs.pypi.org/trusted-publishers/using-a-publisher/#the-manual-way&#34;&gt;in our
documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Additional security hardening is available&lt;/h3&gt;
&lt;p&gt;PyPI package maintainers can further increase the security of their release
workflows by configuring trusted publishers to only release from a specific
&lt;a href=&#34;https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment&#34;&gt;GitHub Actions environment&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Configuring an environment is optional, but strongly recommended: with a GitHub
environment, you can apply additional restrictions to your trusted GitHub
Actions workflow, such as requiring manual approval on each run by a trusted
subset of repository maintainers.&lt;/p&gt;
&lt;h3&gt;Unblocking future security improvements&lt;/h3&gt;
&lt;p&gt;In addition to making publishing more secure now, the availability of trusted
publishers unblocks additional future security improvements for PyPI.&lt;/p&gt;
&lt;p&gt;Configuring and using a trusted publisher provides a &#39;strong link&#39; between a
project and its source repository, which can allow PyPI to verify related
metadata, like the URL of a source repository for a project[^1]. Additionally,
publishing with a trusted publisher allows PyPI to correlate more information
about where a given file was published from in a verifiable way.&lt;/p&gt;
&lt;p&gt;Finally, although trusted publishers is currently limited to GitHub Actions,
much of the underlying work that went into making this feature possible is
generalizable and not specific to a single publisher. We&#39;re interested in
supporting the ability to publish from additional services that provide OpenID
Connect identities.&lt;/p&gt;
&lt;h3&gt;Get started today&lt;/h3&gt;
&lt;p&gt;To get started with using trusted publishers on PyPI, see our documentation
here: &lt;a href=&#34;https://docs.pypi.org/trusted-publishers/&#34;&gt;https://docs.pypi.org/trusted-publishers/&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Acknowledgements&lt;/h3&gt;
&lt;p&gt;Funding for this work was provided by the Google Open Source Security Team, and
much of the development work was performed by &lt;a href=&#34;https://www.trailofbits.com/&#34;&gt;Trail of Bits&lt;/a&gt;, with special
thanks to contributor &lt;a href=&#34;https://github.com/woodruffw&#34;&gt;William Woodruff&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Many thanks as well to &lt;a href=&#34;https://github.com/webknjaz&#34;&gt;Sviatoslav Sydorenko&lt;/a&gt;, maintainer of the PyPA&#39;s
&lt;a href=&#34;https://github.com/marketplace/actions/pypi-publish&#34;&gt;&#39;pypi-publish&#39; GitHub Action&lt;/a&gt; for his quick and timely work to add support for
trusted publishers in the action.&lt;/p&gt;
&lt;p&gt;Finally, we want to thank all our beta testers, including GitHub staff, for
working with us to ensure this feature is intuitive and useful, and for
providing valuable feedback to improve this feature along the way.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Dustin Ingram is a maintainer of the Python Package Index and a director of
the Python Software Foundation.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;[^1]: Currently, information such as this are provided by the uploader and are not verified as accurate by PyPI.&lt;/p&gt;</description>
      <link>http://0.0.0.0:8000/posts/2023-04-20-introducing-trusted-publishers/</link>
      <pubDate>Thu, 20 Apr 2023 00:00:00 +0000</pubDate>
      <source url="http://0.0.0.0:8000/feed_rss_created.xml">The Python Package Index</source>
      
      <guid isPermaLink="true">http://0.0.0.0:8000/posts/2023-04-20-introducing-trusted-publishers/</guid>
      
    </item>
    
    <item>
      <title>Welcome to the PyPI Blog</title>
      
      
        
      <author>Ee Durbin</author>
        
      
      
      
        
      <category>blogs-about-blogs</category>
        
      <category>meta</category>
        
      <category>welcome</category>
        
      
      <description>&lt;div class=&#34;blogging-tags-grid&#34;&gt;

        &lt;a href=&#34;http://0.0.0.0:8000/tags#meta&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#meta&lt;/code&gt;&lt;/a&gt;

        &lt;a href=&#34;http://0.0.0.0:8000/tags#welcome&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#welcome&lt;/code&gt;&lt;/a&gt;

        &lt;a href=&#34;http://0.0.0.0:8000/tags#blogs-about-blogs&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#blogs-about-blogs&lt;/code&gt;&lt;/a&gt;

    &lt;/div&gt;

&lt;style&gt;
    .md-typeset .blogging-tags-grid {
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        gap: 8px;
        margin-top: 5px;
    }

    .md-typeset .blogging-tag {
        color: var(--md-typeset-color);
        background-color: var(--md-typeset-code-color);
    }

    .md-typeset .blogging-tag code {
        border-radius: 5px;
    }
&lt;/style&gt;
&lt;p&gt;Today, we&#39;re excited to launch &lt;a href=&#34;https://blog.pypi.org&#34;&gt;blog.pypi.org&lt;/a&gt;,
the official blog of the Python Package Index.&lt;/p&gt;
&lt;p&gt;One of the most common refrains I hear from Python community members,
irrespective of if they have been around for days or years,
is &lt;em&gt;&#34;I didn&#39;t realize that PyPI...&#34;&lt;/em&gt;. Followed by something along the lines of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Could &lt;strong&gt;do&lt;/strong&gt; that&lt;/li&gt;
&lt;li&gt;Is operated with &lt;strong&gt;so&lt;/strong&gt; few resources[^1]&lt;/li&gt;
&lt;li&gt;Only had &lt;strong&gt;3&lt;/strong&gt; administrators[^2]&lt;/li&gt;
&lt;li&gt;Needs &lt;strong&gt;more&lt;/strong&gt; help&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That is certainly in part due to the fact that the people[^3] who
make PyPI &#34;happen&#34; are &lt;em&gt;humble&lt;/em&gt;, and do so with the limited time they
have to commit to the project among their other responsibilities.
But its also because writing is hard. Harder still when there is
not a convenient tool at hand.
We&#39;re hoping that a modern and extensible stack[^4] for this blog
will make writing about and sharing our work more frictionless.&lt;/p&gt;
&lt;p&gt;The PyPI team will use this space to communicate with PyPI users,
provide announcements about new features and updates,
interesting technology, as well as share information and
context around PyPI and related efforts of the
&lt;a href=&#34;https://www.python.org/psf-landing/&#34;&gt;Python Software Foundation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Stay tuned for more, we&#39;re very glad you&#39;re here! 💜&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Ee Durbin is the Director of Infrastructure at
the Python Software Foundation.
They have been contributing to keeping PyPI online, available, and
secure since 2013.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;[^1]: We&#39;re thrifty and picky about what we run, but
&lt;a href=&#34;https://www.fastly.com/fast-forward&#34;&gt;Fastly&lt;/a&gt; is the single most
important factor allowing us to get by with comparatively few
resources for our backends.
[^2]: That was until we welcomed Mike Fiedler as an admin in 2023.
[^3]: The PyPI Administrator team is
&lt;a href=&#34;https://github.com/dstufft&#34;&gt;Donald Stufft&lt;/a&gt;,
&lt;a href=&#34;https://github.com/di&#34;&gt;Dustin Ingram&lt;/a&gt;,
&lt;a href=&#34;https://github.com/miketheman&#34;&gt;Mike Fiedler&lt;/a&gt;,
and &lt;a href=&#34;https://github.com/ewdurbin&#34;&gt;Ee Durbin&lt;/a&gt;.
The PyPI Moderator team is
&lt;a href=&#34;https://github.com/yeraydiazdiaz&#34;&gt;Yeray Díaz&lt;/a&gt;,
&lt;a href=&#34;https://github.com/cmaureir&#34;&gt;Cristián Maureira-Fredes&lt;/a&gt;,
&lt;a href=&#34;https://github.com/ewjoachim&#34;&gt;Joachim Jablon&lt;/a&gt;,
&lt;a href=&#34;https://github.com/jamadden&#34;&gt;Jason Madden&lt;/a&gt;,
&lt;a href=&#34;https://github.com/pradyunsg&#34;&gt;Pradyun Gedam&lt;/a&gt;,
and &lt;a href=&#34;https://github.com/theacodes&#34;&gt;Stargirl Flowers&lt;/a&gt;.
[^4]: Shout-out: This blog is hosted on
&lt;a href=&#34;https://readthedocs.org/&#34;&gt;Read the Docs&lt;/a&gt;,
using the &lt;a href=&#34;https://pypi.org/project/mkdocs/&#34;&gt;MkDocs&lt;/a&gt;
static site generator,
and the &lt;a href=&#34;https://pypi.org/project/mkdocs-material/&#34;&gt;Material for MkDocs&lt;/a&gt; theme.
Many thanks to the maintainers of those projects for your
contributions,
we&#39;re very excited to have our blog contents live side-by-side
with our other documentation and code in
&lt;a href=&#34;https://github.com/pypi/warehouse&#34;&gt;pypi/warehouse&lt;/a&gt;!&lt;/p&gt;</description>
      <link>http://0.0.0.0:8000/posts/2023-03-21-welcome-to-the-pypi-blog/</link>
      <pubDate>Tue, 21 Mar 2023 00:00:00 +0000</pubDate>
      <source url="http://0.0.0.0:8000/feed_rss_created.xml">The Python Package Index</source>
      
      <guid isPermaLink="true">http://0.0.0.0:8000/posts/2023-03-21-welcome-to-the-pypi-blog/</guid>
      
    </item>
    
  </channel>
</rss>
</pre>
</details>

Footnotes

  1. Except maybe the account owner themselves, by denying them access to their
    account. 2

  2. For end users it forces them to purchase some kind of hardware token <em>OR</em>
    to use some sort of TOTP application. In both cases it forces them to keep
    track of something else besides their password and changes the login flow
    from what they are used to. For PyPI it increases the chance that someone
    may get locked out of their account, requiring intervention by administrators. 2

  3. Not for nothing, but PyPI is also an Open Source project, run largely by
    volunteers, and cleaning up after a compromise on PyPI is something that
    affects those volunteers significantly.</p>

    http://0.0.0.0:8000/posts/2023-05-25-securing-pypi-with-2fa/ Thu, 25 May 2023 00:00:00 +0000 The Python Package Index

    http://0.0.0.0:8000/posts/2023-05-25-securing-pypi-with-2fa/

    <title>PyPI was subpoenaed</title>

    Ee Durbin

    compliance

    transparency

    <div class="blogging-tags-grid">

    &lt;a href=&#34;http://0.0.0.0:8000/tags#transparency&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#transparency&lt;/code&gt;&lt;/a&gt;
    
    &lt;a href=&#34;http://0.0.0.0:8000/tags#compliance&#34; class=&#34;blogging-tag&#34;&gt;&lt;code&gt;#compliance&lt;/code&gt;&lt;/a&gt;
    

    </div>

i'm -1 here as it renders pretty poorly
@ewdurbin ewdurbin requested a review from a team as a code owner May 31, 2023 01:41
@ewdurbin
Copy link
Member Author

ewdurbin commented May 31, 2023

ref: #13812

@ewdurbin
Copy link
Member Author

Every previewer I could find at hand, renders the result pretty terribly.

I think this needs more investigation and someone to commit to figuring out how to render sanely in readers.

@ewdurbin ewdurbin closed this May 31, 2023
@miketheman miketheman added the blog Related to the Blog label Jun 1, 2023
@ewdurbin ewdurbin deleted the feeds_feed_the_feeds_feeding_feeding branch June 3, 2023 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blog Related to the Blog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants