Astral, the company behind Ruff and uv, just published a detailed breakdown of how they secure their open-source projects. Written by Staff Security Engineer William Woodruff, the post arrives amid a wave of supply chain attacks hitting projects like Trivy and LiteLLM. The goal is simple: share what works so other maintainers can adopt it.

The foundation of their approach is treating GitHub Actions as a security boundary. GitHub Actions has poor defaults, Woodruff writes, and compromises like those in Ultralytics, tj-actions, and Nx all started with well-known weaknesses. Astral's fix is blunt. They ban dangerous triggers like pull_request_target and workflow_run across their entire organization. Woodruff calls these triggers "almost impossible to use securely" and says most projects that think they need them are better off with less privileged alternatives. When a use case genuinely requires elevated permissions, Astral moves that logic out of GitHub Actions entirely and into a dedicated GitHub App or webhook.

They also require every action to be pinned to a full commit SHA instead of a mutable tag. Getting there took real coordination. Astral worked with downstream dependencies to hash-pin the entire action graph. They use zizmor, a static analysis tool Woodruff created, to catch unpinned actions and impostor commits. But hash-pinning alone isn't sufficient. An immutable action can still make mutable decisions, like downloading the latest binary from a release. Neither GitHub nor third-party tools catch these "immutability gaps" well, so Astral relies on manual review. When gaps turn up, they work with upstream maintainers to fix them.

Beyond CI/CD, Astral layers on organizational controls: limited admin access, mandatory strong 2FA for all org members, branch protection requiring pull requests for every change to main, and tag protection that locks release tags until a deployment gets manual approval from at least one other team member. Secrets live in deployment environments, not at the organization or repository level, limiting blast radius if a test or linting job gets compromised. It's a lot of overhead. But for tools that millions of developers depend on daily, that overhead is the point.