# Python Security at PyCon US 2026: A Visual Guide to Talk Python Episode 557

**Guide**: https://talkpython.fm/guides/557/security-of-everything-at-pycon-2026
**Episode**: [Talk Python to Me #557: Security of everything at PyCon 2026](https://talkpython.fm/episodes/show/557/security-of-everything-at-pycon-2026)
**Featuring**: Seth Michael Larson (Security Developer-in-Residence at the Python Software Foundation), Juanita Gomez (PhD candidate in Computer Science at UC Santa Cruz), Mike Fiedler (PyPI Safety and Security Engineer)
**Published**: October 26, 2026

**TL;DR:** PyCon US 2026 gave security its own day-long track for the first time, and the room was full. The talks covered a phishing campaign against PyPI maintainers that got past TOTP two-factor, dependency cooldowns, GitHub Actions pitfalls, SBOMs, zero trust, and a proposal to bring Rust into CPython. The people doing the work don't think Python security is anywhere close to solved, and they want more people and money behind it.

"Security has always been the vegetables of software." That's how Michael Kennedy, host of Talk Python, opened this episode. Everyone agrees it matters, and somehow it never quite makes it onto the plate. That changed at PyCon US 2026 in Long Beach. Security got its own dedicated track for an entire day, one of only two dedicated tracks at the conference. The other one was AI.

The track, Trailblazing Python Security, was co-chaired by Seth Larson, the Python Software Foundation's Security Developer-in-Residence, and Juanita Gomez, a PhD researcher at UC Santa Cruz who works on open source security. Mike Fiedler, PyPI's Safety and Security Engineer, opened the day with the story of a phishing attack he handled himself. The three of them sat down with Michael to walk through the talks one at a time and take the temperature of Python security right now.

So how is Python security doing? Mike has an analogy for that. Securing PyPI is like rebuilding the plane while you're flying it. They had the plane, and now they're adding better sensors, better steering and better throttles "while we're still flying". And, he added, "that flight is accelerating".

This guide follows the arc of that day. It starts with who actually gets paid to do this work, then covers the phishing campaign and why the kind of two-factor you use matters, how one small package reached Hugging Face Transformers, dependency cooldowns, GitHub Actions, SBOMs, CVEs and malware, zero trust and Rust in CPython. It ends where the panel did, with what you can do about it.

## Who gets paid to secure Python, and why volunteers still matter

A surprisingly small number of paid people carry Python's security work. Mike Fiedler is PyPI's Safety and Security Engineer and is coming up on his third year at the Python Software Foundation. Before the job existed, he was a volunteer PyPI admin and contributor for years. Seth Larson is the PSF's Security Developer-in-Residence and, very recently, a CPython core developer. His area is everything that isn't the PyPI backend: the language and runtime, the security response team for Python and pip, packaging tools and standards, and how the wider security world, CVEs included, works with Python. Juanita Gomez puts the gap plainly. Every time she talks to Mike, she asks him "why are you the only getting paid for doing Python security?"

Paying someone has two sides, as Mike sees it. With volunteers, "you get what you pay for, which is nothing". That's not a knock on them. Volunteers do what they want to do, and they do their best. Hire someone and you can set expectations and work to meet them. The catch is that volunteers often step back once someone is paid to do the job. They get a much-needed break, and the pressure lands on the few full-time people, who never have enough capacity. Is it worth it anyway? Mike's conclusion is that when you pay for a focused security effort, you do get a good security outcome.

Seth deals with the same tension by being choosy. His area is so large that he looks for clearly high-impact projects and avoids what he calls snacking. He also avoids work a volunteer could do. If a task looks like something a volunteer might pick up, he may pause and leave space for someone to contribute. What he takes on is the work volunteers are less likely to want: setting up a CVE Numbering Authority for the PSF, or monitoring the Python Security Response Team's inbox for spam. Being on that team and coordinating vulnerability reports, with credit in the advisory, is a different story, and volunteers might well want it. The goal, in his words, is to build "the community volunteer muscle".

His reach goes past CPython, too. Seth has talked many times with David from Flask about setting up a security response program or a threat model, and with plenty of other maintainers. Because the PSF is a nonprofit, it publishes everything it does and where it has seen success, so other projects can copy what worked into their own processes.

> "One of the nice things about this role being at a nonprofit is that you can be super, super open. You don't have to keep the secrets to yourself about what you've done and how you've seen success."
>
> Seth Larson

**Resources**

- [PyPI hires its first Safety and Security Engineer](https://blog.pypi.org/posts/2023-08-04-pypi-hires-safety-engineer/)
- [PSF announcement of the PyPI Safety and Security Engineer role](https://pyfound.blogspot.com/2023/08/announcing-our-new-pypi-safety-security.html)

## PyCon US 2026's first Python security track

![Security Is No Longer the Vegetables. The Past: Security as a faint dot on a radar, a secondary concern. PyCon US 2026: Artificial Intelligence and Trailblazing Python Security as parallel beams. First dedicated track, a full day right next to AI. Capacity: standing room only, packed to the back wall.](https://blobs.talkpython.fm/guides/557/02.webp?cache_id=f679177c)

PyCon US has always had security talks. What it hadn't had before 2026 was a security track. Trailblazing Python Security ran for a full day on Saturday, in one fixed room, so people didn't have to keep moving between talks. It was one of only two dedicated tracks at the conference, the other being AI.

A track says more than a few security talks scattered through the schedule. Juanita Gomez sees security as something that runs alongside everything else in Python. If you maintain a package, it should be somewhere on your mind while you develop. Yet there's a big gap in how much time maintainers spend on it, and in their expertise. Giving it a full track, she says, "elevates the importance of security within Python", which isn't always the case. A lot of the material wasn't even Python specific. You should care about credentials and phishing whether you write Python, C or anything else.

For Juanita this was personal. She has helped organize SciPy for a couple of years and has tried to bring security into the conversation there with birds-of-a-feather sessions, but a whole security track seemed a little impossible. At PyCon, the organizers were limited to about eight slots, and she says she learned a lot just reading the proposals. For Seth Larson, it was his first time organizing at this level. The day itself was very on the fly.

And people came. Several talks were standing room only, with nowhere left to stand. Seth's view as an organizer of a first-time event is that when the room is too small, "It means you're doing something right."

Juanita does see a gap: she would have liked an intro to security. Her research with UC Santa Cruz's open source program office works on security practices for university projects, and some of them aren't ready for the more advanced material. Basics like flipping some switches in your GitHub repository settings didn't get much time. Michael Kennedy liked the idea of a Security 101 talk to open the track, with things like rate limiting and logging so you can tell when something does happen.

So is there a second one coming? "We're hoping for it, for sure," says Juanita. Seth saw no sign they shouldn't do it again, and a more interactive, panel-style session came up as an idea for next year. A bigger room would help, too.

> "I think security is something that's parallel to everything in Python. I think that if you're a maintainer for a package, I think having security somewhere on your mind should be a thing."
>
> Juanita Gomez

**Resources**

- [The PyCon US 2026 security track](https://us.pycon.org/2026/tracks/security/)
- [Trailblazing Python Security, the track announcement](https://pycon.blogspot.com/2025/11/trailblazing-python-security-pycon-us-2026.html)
- [Everything security at PyCon US 2026 (PSF recap)](https://pyfound.blogspot.com/2026/06/everything-security-at-pycon-us-2026.html)

## How the PyPI phishing campaign worked

![Anatomy of a Phishing Campaign. Step 1, Reconnaissance: scrape public maintainer emails from GitHub profiles and package metadata. Step 2, Mimicry: copy PyPI's open source email templates for a legitimate-looking request. Step 3, The Trap: of over 1 million accounts, 4 maintainers click and log in.](https://blobs.talkpython.fm/guides/557/03.webp?cache_id=9b49ffed)

Mike Fiedler opened the security track with a story he lived through as PyPI's Safety and Security Engineer. People hear "phishing attack" and tune out, but this one was different.

A lot of phishing campaigns build a byte-for-byte or pixel-perfect copy of a site and steer traffic to it. These attackers didn't bother. They put a proxy in front of the real PyPI, so every page a maintainer saw was genuine. Then they emailed maintainers using addresses that are public anyway, the ones people put on their GitHub profiles and in their package metadata.

That's a sharper kind of targeting. Michael Kennedy pointed out that the email on a maintainer's GitHub profile is probably the one they registered at PyPI, and the packages worth stealing link straight to those GitHub repos. Mike agrees it narrows things a little. Most phishing is spray and pray: email 2 million people, and if two bite, that's a success.

Why did anyone click? PyPI is open source, so anyone can read its code and see what its email templates look like. And PyPI really does ask maintainers to take action now and then. It emailed people a couple of years ago to turn on 2FA, and it sometimes tells people there's a problem with their metadata. The attackers asked maintainers to do an action, and the maintainers did it. The mail didn't come through PyPI's infrastructure, so anti-spam tools might have caught it, but they didn't. The link went to pypj.org instead of pypi.org. Mike challenges anyone to spot the difference between a lowercase i and j in Arial while hovering over a link on their phone. That's why he has "no qualms for the humans that fell for this". They did what they were supposed to do.

PyPI has over a million user accounts. Only four people fell for it and logged in, and that was enough. The [next sections](#why-totp-two-factor-didnt-stop-the-pypi-phishing-proxy) cover how the attackers turned a login into lasting access, and [where the one stolen package went](#num2words-how-one-phished-package-reached-hugging-face-transformers).

Juanita Gomez counts this among her favorite talks of the track because it was so relatable. Many people in the room publish packages on PyPI themselves, and Mike ended with a call to action: what to do so this doesn't happen to you.

> "We have to defend 100% of the time. They only have to be right once or twice."
>
> Mike Fiedler

**Resources**

- [PyPI's incident report on the phishing attack](https://blog.pypi.org/posts/2025-07-31-incident-report-phishing-attack/)
- [Anatomy of a Phishing Campaign (PyCon US 2026 talk)](https://us.pycon.org/2026/schedule/presentation/74/)

## Why TOTP two-factor didn't stop the PyPI phishing proxy

![The Transparent Proxy Attack. The user enters a username, password and TOTP code at the look-alike domain pypj.org, which forwards them to the real PyPI. PyPI issues a session cookie valid for hours, and the proxy intercepts it and mints an API token with no expiration. Core insight: 2FA is not a monolith.](https://blobs.talkpython.fm/guides/557/04.webp?cache_id=e05b28b9)

PyPI has been pushing two-factor authentication for a long time. So how did a phishing site still get in? Mike Fiedler's answer is that "you can still get phished with certain forms of two-factor authentication". The weak form is the time-based one-time password, or TOTP: the six-digit code from a QR code you scanned into Google Authenticator or a similar app. They're all the same thing.

Here's how it plays out. The maintainer types their username, password and TOTP code into the fake site. The proxy passes them straight to the real PyPI while the code is still valid. Michael Kennedy noted that TOTP still earns its keep elsewhere. If your password leaks, or someone tries to brute force it, the password alone isn't enough to get in anymore. But against a live proxy it doesn't add much.

The login was only the start. Once you've entered your password and TOTP code, PyPI gives your browser a session cookie, so you don't have to log in again on every page. That cookie is good for, as Mike put it, eight hours or something like that. The attacker doesn't need your TOTP code anymore. They have the cookie, and they can be you.

Then they made the access permanent. With the session in hand, the attackers created a PyPI API token. API tokens today don't expire. At that point the username, password, TOTP code and session no longer matter.

After the attack, PyPI started checking sessions that were obtained with TOTP. If one shows up from a different IP address, PyPI asks you to prove who you are again. People who log in with WebAuthn aren't affected. The ones who might get caught are people bouncing between VPNs, or riding a train and changing IP addresses as they pass cell towers. Mike doesn't think that happens very often, but it can.

The fix that works much better is a different kind of second factor, which is where the [next section](#passkeys-webauthn-and-trusted-publishing-for-pypi) picks up.

> "And now I don't need your username, your password, your TOTP, the session token. I don't need any of that. I have an API token."
>
> Mike Fiedler

**Resources**

- [RFC 6238, the TOTP specification](https://datatracker.ietf.org/doc/html/rfc6238)

## Passkeys, WebAuthn and trusted publishing for PyPI

![The Authentication Reality Check. TOTP (authenticator apps): fails against transparent proxies; session cookies last for hours. WebAuthn and passkeys (e.g., YubiKey): bound to the real domain, pypi.org. Trusted Publishing (OIDC): short-lived, scoped tokens via CI; delete old API tokens immediately.](https://blobs.talkpython.fm/guides/557/05.webp?cache_id=d89c6675)

If TOTP codes can be relayed, what can't be? Mike Fiedler's answer is WebAuthn, the technology underneath passkeys, or a hardware key like a YubiKey. It's a different sort of two-factor, and it's more phishing resistant. In the PyPI attack, that's exactly what separated the people who were hit from the people who weren't.

The reason is that a WebAuthn credential is tied to the website it was created for. Your browser won't use a credential made for pypi.org on pypj.org, so a look-alike domain gets nothing to forward. There's no six-digit code to type into the wrong page.

That doesn't make TOTP useless. It still stops someone holding a leaked password, as Michael Kennedy pointed out. It just isn't phishing resistant, and a maintainer whose packages sit under other people's dependency trees is a juicy phishing target.

The other half of the story is how packages get published. The attackers' lasting access came from an API token that never expires. So when Michael asked each guest for the one thing listeners should do this week, Mike's answer went straight at that: look at trusted publishing, convert at least one of your projects to use it, "And don't forget to delete the old token."

Trusted publishing lets a CI system such as GitHub Actions publish to PyPI without a stored API token. The CI provider proves its identity to PyPI with OpenID Connect, and PyPI hands back a short-lived token scoped to that one project. There's no long-lived secret sitting in your repository settings. The old token is the catch. As long as it exists, it can still publish, so moving to trusted publishing only pays off once that token is gone.

> "So anybody who had the phishing resistant part was not subject to this attack."
>
> Mike Fiedler

**Resources**

- [Web Authentication (WebAuthn) Level 3](https://www.w3.org/TR/webauthn-3/)
- [passkeys.dev](https://passkeys.dev/)
- [YubiKey hardware security keys](https://www.yubico.com/)
- [PyPI trusted publishing documentation](https://docs.pypi.org/trusted-publishers/)

## num2words: how one phished package reached Hugging Face Transformers

![The Trojan Horse Dependency Graph. Transformers (Hugging Face), with 30 to 40 million downloads per day, sits above a dependency tree with num2words, the single package captured in the phishing attack, at the bottom. It was not version-pinned. The lesson: attackers target the weakest, least-watched link.](https://blobs.talkpython.fm/guides/557/06.webp?cache_id=da7ddf0a)

Four maintainers fell for the phishing site, so what did the attackers do with those accounts? PyPI audited the attackers' signatures and behavior and turned up only one package that was harvested and republished. "Just one that we know of," as Mike Fiedler put it, and that doesn't mean others weren't set up as a backup.

The choice of package is the interesting part. The attackers ignored whatever the other three maintainers had and went after one that was "a dependency of a dependency of a dependency". That was num2words, a sub-dependency of Hugging Face's Transformers library. If you do anything at all in AI, Transformers is kind of key. Mike's estimate is that it gets 30 or 40 million downloads a day.

And num2words wasn't pinned in Transformers. So by publishing a new version of num2words, the attackers made sure any Transformers user was going to get it. Nobody had to install num2words on purpose. The dependency graph did the distributing.

This is the supply chain problem in a nutshell. You might review a package before you take it on as a dependency, but Michael Kennedy asked how far down its dependency chain anyone really follows. There's no comfortable answer. Mike's view is that we all depend on somebody else somewhere. None of us wrote our own compiler, the Python language, our editor or our operating system. If you have, he commends you. It's a lot of effort that's unnecessary in today's world, though you're likely more secure for it.

For a package buried that deep, pinning is one answer, though Mike calls sub-dependency pinning and version bounds a whole other set of conversations. For most people, the easier lever is a [dependency cooldown](#dependency-cooldowns-waiting-a-few-days-before-you-install).

> "You're only as strong as the weakest link in your chain. And we all depend on something and somebody else and somewhere."
>
> Mike Fiedler

**Resources**

- [num2words on PyPI](https://pypi.org/project/num2words/)
- [Hugging Face Transformers on GitHub](https://github.com/huggingface/transformers)

## Why the CVE system struggles with malicious packages

![The CVE Paradox: Flaw vs. Threat. Vulnerable software: Microsoft Word opening a booby-trapped PDF, legitimate software with an accidental bug. Malicious software: the software is the bad actor, and tracking all malware as vulnerabilities means millions of records. Conclusion: vulnerability tracking was built for flaws.](https://blobs.talkpython.fm/guides/557/07.webp?cache_id=d6d9477d)

A CVE is a public, numbered record of a vulnerability: a flaw in software that's supposed to be doing something legitimate. Seth Larson knows the system well. He helped set up the PSF as a CVE Numbering Authority, and the CVE system is something he has "spent way too much time kind of digging around in". The last talk the panel discussed, Breaking Bad (Packages) by Shelby Cunningham and Madison Ficorilli, was right up his alley. Its subtitle asks why traditional vulnerability tracking fails supply chain attacks.

The tension is between vulnerabilities and malware. Malware on PyPI isn't buggy software. It's software built to do harm, working exactly as its author intended. Sometimes the community issues CVEs for malware, and sometimes it doesn't. If it did every time, Seth says, there'd be millions of them. That raises questions he doesn't have settled answers to. What are the trade-offs? Does it overwhelm the system? Is it even useful?

Michael Kennedy drew the line with an example. Malware isn't a problem in valid software. It's just a bad piece of software. But if you open a PDF in Microsoft Word and it turns your machine into part of a botnet, that's a CVE, "Because Microsoft Word isn't intended to be malware."

The talk walked through watering hole attacks that published malware to several open source ecosystems, PyPI included. It looked at how vulnerability records like CVE and OSV responded, and how people got the word out.

So is CVE the right tool for malicious packages? Seth's honest answer is not quite. It feels so close to being the right system, and that's what makes it so challenging. He isn't sure whether that means building a new system or something else, only that "We need to do some more thinking in this area."

> "It feels so close to being the right system to use, but not quite. And maybe that means that we need to build a new system."
>
> Seth Larson

**Resources**

- [Breaking Bad (Packages) (PyCon US 2026 talk)](https://us.pycon.org/2026/schedule/presentation/79/)
- [The CVE program](https://www.cve.org/)
- [OSV, the Open Source Vulnerabilities database](https://osv.dev/)
- [The PSF as a CVE Numbering Authority](https://www.python.org/cve-numbering-authority/)
- [The PSF advisory database](https://github.com/psf/advisory-database)

## Four places to defend a Python package

![The Defense-in-Depth Telemetry Map. Four checkpoints on a pipeline: the repository (zizmor scans GitHub Actions workflows for injection risks), the build (SBOMit attests to build events via in-toto), the registry (trusted publishing replaces long-lived API tokens) and the client (cooldowns).](https://blobs.talkpython.fm/guides/557/08.webp?cache_id=9a0863ba)

Nobody on the panel laid it out this way, but the tools in this guide line up along the path a package takes from a maintainer's repository to your machine. Each one guards a different step:

- **The repository.** zizmor checks a project's GitHub Actions workflows for risky patterns. See [GitHub Actions and zizmor](#github-actions-security-pull_request_target-and-zizmor).
- **The build.** SBOMit records what actually happens during a build and turns it into a verifiable software bill of materials. See [SBOMit](#zero-trust-in-python-a-credential-per-transaction-and-builds-you-can-verify).
- **The registry.** Trusted publishing lets CI publish to PyPI without a long-lived API token. See [trusted publishing](#passkeys-webauthn-and-trusted-publishing-for-pypi).
- **Your machine.** A dependency cooldown keeps brand-new releases off it until the community's scanners have had a look. See [dependency cooldowns](#dependency-cooldowns-waiting-a-few-days-before-you-install).

The phishing campaign shows why more than one step matters. TOTP was the layer the attackers got past, and the lasting damage came through another: an API token that never expires.

## Dependency cooldowns: waiting a few days before you install

![The Cooldown Shield. A funnel timeline. At publish, malware is uploaded to PyPI. Plus 30 minutes: volunteer reporters' tooling flags it. Plus 1 hour: automated quarantine, pending human review. Plus 3 days: the package manager's exclude-newer cooldown hits a hard barrier.](https://blobs.talkpython.fm/guides/557/09.webp?cache_id=db733b42)

A dependency cooldown means refusing to install a package version until it has been public for a while. Michael Kennedy noticed the idea early in uv. pip is getting it too, along with package managers outside Python.

Mike Fiedler thinks cooldowns are a good idea for the average consumer. If you use unbounded versions, you get whatever the latest release on the registry is, and attackers look for exactly that. num2words wasn't pinned in Transformers. A cooldown is the easy way to say you don't want the newest thing: "I want to wait three days or seven days". In that window, it's very likely some security scanner has chewed through a new release, and if it's malicious, there's a very high likelihood it's already gone.

Why are bad releases usually gone that quickly? PyPI has no commercial scanning relationship. There are people in the community who like scanning things, plus some businesses, who report suspicious packages. The best of them have such a low false-positive rate that PyPI lets their reports put a package into automated quarantine. It can't be downloaded until a human like Mike clears it or removes it. One volunteer, Kamil in Austria, often reports within 30 minutes of publish, with zero false positives. Michael pointed to cooldowns.dev, whose stats include the LiteLLM case. His recollection is that within a week around 90% of the malicious versions were down, most within a day.

Seth Larson sees cooldowns as a fit for people without a security team: students, and anyone for whom Python is their first language. Set a cooldown once and you benefit from all that scanning and takedown work. Juanita Gomez adds that many people who use Python packages have no idea what PyPI is. When she started, she ran commands she read on Reddit.

In uv, the setting is exclude-newer, and it accepts a relative duration:

```bash
uv pip compile requirements.in --exclude-newer "7 days" -o requirements.txt
```

It's not all unicorns and rainbows, however. Michael pins everything with uv pip compile, added a one-week exclude-newer, and put pip-audit in his Docker builds so they fail on a known CVE. Then a CVE would land, the fix would ship a day later, and the cooldown would refuse the fix for being too new. Seth says that's exactly why he'd have a hard time pushing cooldowns as a default right now. They confuse people, and commands that always worked suddenly say a version doesn't exist. His ideal is a secure default for anyone not showing operational maturity, such as using a mirror or asking for a lock or an exact version, that also knows when a security fix lands inside the window. That would be easier if more review happened on the index side. Right now, an upload to PyPI is available immediately and scanned after the fact, because there's too much volume to do otherwise.

> "Set like a really aggressive like seven days or something like that on your cooldown one time and then you're pretty okay."
>
> Seth Larson

**Resources**

- [cooldowns.dev](https://cooldowns.dev/)
- [uv resolution docs, including exclude-newer](https://docs.astral.sh/uv/concepts/resolution/)
- [LiteLLM on GitHub](https://github.com/BerriAI/litellm)
- [pip-audit](https://github.com/pypa/pip-audit)

## GitHub Actions security: pull_request_target and zizmor

![Structural Integrity: The Sharp Knife of Actions. The threat vector: the pull_request_target trigger, which runs on forks with elevated privileges and opens the door to cache poisoning. The metaphor: a very sharp knife; pick it up the wrong way and you cut your hand. The fix: run zizmor continuously.](https://blobs.talkpython.fm/guides/557/10.webp?cache_id=76006f6a)

Andrew Nesbitt is, in Mike Fiedler's words, "the best kind of nerd". He loves researching things and collecting data, and he's the author behind ecosyste.ms. For his talk, he ran zizmor across a large number of PyPI-linked GitHub repositories. zizmor is a static analyzer for GitHub Actions workflows (Andrew didn't write it). What it turns up is unsettling. Plenty of findings are easy to fix. Some are the scarier kind, where a workflow has left the project open to an injection that leads to an exploit, and Andrew walked through a couple of those.

Michael Kennedy described one of the stranger cases: cache poisoning. Someone with no rights to a project opens a pull request, which triggers a GitHub Actions build. Because that build runs in the context of the target repository, the pull request can point at a malicious package that then gets cached into the project's real build.

Mike heard the keyword right away. GitHub Actions has a lot of triggers, such as push and pull_request. There's also one called pull_request_target. It runs on forks, and it runs with elevated privileges. Mike calls it dangerous. zizmor flags it as something you're probably using wrong, because it's a very sharp knife, and it's easy to pick it up the wrong way and cut your hand.

So what should a maintainer do? Mike keeps it short. Run zizmor on your repository, or better, add it as a GitHub Action so it runs all the time. Follow its recommendations, and move on with your life. It belongs on the checklist for anyone getting started with security. When Michael asked each guest for the one thing listeners should do this week, Juanita Gomez's pick was zizmor.

> "This should be on that checklist of did you run zizmor on your repository? Better yet, did you add it as a GitHub action to run always on your repository?"
>
> Mike Fiedler

**Resources**

- [GitHub Actions Security in Python Packages (PyCon US 2026 talk)](https://us.pycon.org/2026/schedule/presentation/117/)
- [zizmor](https://zizmor.sh/)
- [zizmor on GitHub](https://github.com/zizmorcore/zizmor)
- [GitHub Actions documentation](https://docs.github.com/en/actions)

## Runtime SBOMs: is the vulnerable code even running?

![Visibility: Runtime Reachability. A circuit maze with a green execution path. The insight: traditional tools tell you what you installed; runtime SBOMs generated from Python memory tell you what is reachable. The threat: a known CVE flagged by standard scanners. The execution path: the active program running in memory bypasses the CVE.](https://blobs.talkpython.fm/guides/557/11.webp?cache_id=4f5490f1)

An SBOM, a software bill of materials, is a list of everything that went into a piece of software. Seth Larson likes that the format isn't tied to any one ecosystem, which suits Python well. Plenty of Python packages aren't just Python. They carry C, Fortran, Rust and JavaScript too.

Most SBOMs describe what you declared as inputs. Hala Ali and Andrew Case's talk, Post-Incident Runtime SBOM Generation from Python Memory, asked a different question: what is actually there? Michael Kennedy described the idea as looking at what's loaded into memory. Why is this library loaded too? Did something an attacker put on the machine get loaded in?

Seth was in awe watching it. The talk went deep into Python memory management, how modules are loaded and how functions are called. That depth makes runtime analysis possible. You can look at a running program and see whether the code affected by a CVE is even being used, without reading the source to check.

That would help with a real headache. Michael's guess is that less than 1% of people ever run pip-audit on their code. And even those who do, or who get a Dependabot alert, still have to decide whether a CVE matters. He remembered one in a package he used: a Windows-only issue with untrusted PDF input. His deployment target is Linux on Docker, his dev machine is a Mac, and he doesn't think he takes untrusted input there at all. He didn't really care, but the alert still fails his build.

Tools may be able to make that call for you someday. Mike Fiedler says the open source vulnerability database is working to publish richer details about which code paths a vulnerability affects. Then an audit could check automatically whether you use those paths, and fail your build or not. But there's a catch. Python's dynamism makes that question harder to answer, not easier. You don't even need an import statement to load a library. You can use importlib, or all sorts of other things.

> "So the challenge is how do we surface enough information to make a confident decision without misleading you down the wrong path."
>
> Mike Fiedler

**Resources**

- [Post-Incident Runtime SBOM Generation from Python Memory (PyCon US 2026 talk)](https://us.pycon.org/2026/schedule/presentation/104/)
- [OSV, the Open Source Vulnerabilities database](https://osv.dev/)
- [pip-audit](https://github.com/pypa/pip-audit)
- [Dependabot documentation](https://docs.github.com/en/code-security/dependabot)

## Rust in CPython: why zlib comes first

![Rebuilding the Engine: Rust in CPython. A jet engine with a glowing zlib module at its core. Rewriting parts of CPython in Rust for memory safety, starting with zlib, which handles untrusted data. CPython maintainers are C developers; open source moves by consensus. Next: the EuroPython language summit.](https://blobs.talkpython.fm/guides/557/12.webp?cache_id=fa41f008)

What if more of CPython were written in Rust? That's the idea behind Emma Smith's talk. The proposal right now is modest: rewrite a single standard library module in Rust. The long-term goal is maybe more, potentially even parts of the language itself. Seth Larson says the just-in-time compiler came up as a candidate for a larger project, or as a place to cut your teeth that might never be merged but would prove whether the tooling works.

Seth thinks zlib is a really good first choice. It's a compression library that's pretty well understood, and it processes a lot of untrusted data. That's where the memory safety argument for Rust applies. "Not necessarily that Zlib has had a ton of issues in that area," he adds, but it's a good first module.

The harder problem is people. As Michael Kennedy put it, the C in CPython is there for a reason: the people who work on it are C developers. They don't necessarily want to rewrite things in Rust, and they don't necessarily have the expertise. Juanita Gomez loved that Emma addressed this head-on. The talk covered the technical side of a migration and why it's needed, but also how to organize people and get them to agree. That's how open source works. One of Juanita's highlights was Guido van Rossum in the audience, asking Emma questions about her talk.

Isn't this just the old rewrite-it-in-Rust joke? Seth's view is that people do treat it almost like one. RustPython already exists, so why would this be hard? But it is extremely difficult, socially and technically. The idea has been discussed for a while, and this talk was the first time Emma and the team took it to the wider community. It's on the agenda for the language summit at EuroPython. Seth expects it to be a long road ahead.

> "You don't just make a decision and take a different path on something that you're doing. There's a whole lot of people that are involved in making decisions for a specific community."
>
> Juanita Gomez

**Resources**

- [Rust for CPython (PyCon US 2026 talk)](https://us.pycon.org/2026/schedule/presentation/1/)
- [CPython on GitHub](https://github.com/python/cpython)
- [The Rust programming language](https://www.rust-lang.org/)
- [EuroPython](https://europython.eu/)

## Zero trust in Python: a credential per transaction, and builds you can verify

![The Zero-Trust Ecosystem. Three linked rings. Community telemetry: cooldowns and volunteer scanners. Identity per transaction: FedRAMP-inspired zero trust with no standing credentials, a fresh scoped identity valid for only 200 milliseconds. Cryptographic attestation: build steps verified via in-toto and SBOMit.](https://blobs.talkpython.fm/guides/557/13.webp?cache_id=f622dfe2)

The phishing story turned on a credential that lasted forever. Zero trust goes the other way. Tristan McKinnon's talk, Zero Trust in 200ms: Identity per Transaction, came out of FedRAMP, the US government's Federal Risk and Authorization Management Program. The idea, as Michael Kennedy summarized it, is that every single time your code needs an API key, it gets a new one. Want to talk to AWS? Here's a key you can use for two seconds or so. Use it now.

Seth Larson really loved this talk, because it showed a side of Python development most people never see. If you work in a regulated industry that has to implement FedRAMP, it's a ton of extra work, and it rarely gets talked about online. That work mostly happens in industry, not in open source communities. The talk showed how to build it with tools people already use, starting with the AWS SDK, and then extrapolated it to other backends.

Another talk went after trust in builds. In Asleep at the Wheel: SBOMs for Python Builds, Sanchit Sahay and Abhishek Reddypalle presented SBOMit. Juanita Gomez was proud of it. Both are students, one a master's student and one a PhD student, and they made their research usable by making the project part of the OpenSSF ecosystem. The talk made people aware that today's SBOM tools aren't accurate enough to rely on for security, and the speakers were brave enough to run a live demo, which worked. Seth says this was the talk that showed him what SBOMit actually is. It records everything that happens during a build, every network call and command invocation, exports it as an SBOM, and adds a verifiable record using in-toto, the "it" in SBOMit. He can see it in a future PyPI build farm, or in a recommended builder Docker image that produces an accurate bill of materials for each package.

> "This is just stuff that you don't necessarily see at PyCon or at open source conferences, people talking about federal policy requirements and how to implement secure controls like this."
>
> Seth Larson

**Resources**

- [Zero Trust in 200ms (PyCon US 2026 talk)](https://us.pycon.org/2026/schedule/presentation/140/)
- [FedRAMP](https://www.fedramp.gov/)
- [boto3, the AWS SDK for Python](https://github.com/boto/boto3)
- [Asleep at the Wheel: SBOMs for Python builds (PyCon US 2026 talk)](https://us.pycon.org/2026/schedule/presentation/116/)
- [in-toto](https://in-toto.io/)

## Security isn't free: how to support the Python projects you depend on

![Funding Is the Ultimate Dependency. A seesaw: the global Python ecosystem outweighs a handful of paid full-time engineers and unpaid volunteers. A quote from Seth Larson: Security is not free. Banner: support the upstreams you depend on; donate engineering time or financially support the PSF.](https://blobs.talkpython.fm/guides/557/14.webp?cache_id=cbff432b)

The episode opened with a promise that none of the panel thinks security is anywhere close to solved. That's why the room was full. So what can one listener do about it this week? Michael Kennedy asked each guest for a single recommendation. Juanita Gomez picked [zizmor](#github-actions-security-pull_request_target-and-zizmor). Mike Fiedler picked [trusted publishing](#passkeys-webauthn-and-trusted-publishing-for-pypi), and deleting the old token.

Seth Larson's answer went wider. If you depend on Python or third-party packages, look upstream. See how much work is being done, how much more there is to do, and support the open source ecosystems you rely on so they can do security.

That support comes in two forms. One is engineering time: working on a security team, or making security-focused contributions to the projects you care about. The other is money, such as donating to the Python Software Foundation, the nonprofit that is the home for both Mike's and Seth's jobs.

"Security is not free," as Seth put it. It costs a lot of time to build the changes that everyone ends up benefiting from. And it mostly happens because someone inside a company or organization works with their management to convince them to support the open source they depend on.

If you want to go deeper yourself, Talk Python Training has a few courses that line up with this conversation. [Python Web Security: OWASP Top 10 with Agentic AI](https://training.talkpython.fm/courses/agentic-ai-python-security?utm_source=talkpythondeepdive) works through the OWASP Top 10 with vulnerable and fixed examples, plus tools like pip-audit. [Managing Python Dependencies](https://training.talkpython.fm/courses/managing-python-dependencies-with-pip-and-virtual-environments?utm_source=talkpythondeepdive) covers pip, virtual environments and the dependency habits behind pinning and cooldowns. And if pip install and PyPI are new to you, [Python for Absolute Beginners](https://training.talkpython.fm/courses/python-for-absolute-beginners?utm_source=talkpythondeepdive) starts at the very beginning.

> "And it really would not happen without internal advocates at companies and organizations working with their management and all of that to convince them to support open source that they depend on."
>
> Seth Larson

**Resources**

- [Donate to the Python Software Foundation](https://www.python.org/psf/donations/)
- [python.org](https://www.python.org/)

---

Listen to the full episode: https://talkpython.fm/episodes/show/557/security-of-everything-at-pycon-2026
Episode show notes as Markdown: https://talkpython.fm/episodes/show/557/security-of-everything-at-pycon-2026.md
