Nixpkgs core team update 2026-05-11 – automation/AI policy feedback and new members wanted

I will use this to say some stuff about GHSA-67f2-674w-6g63 :smiley:

For anyone wondering which committer caused all of this, it was me!

I take full responsiblity for this token leak, but I thought I could give some
insight into how this happened and, more importantly, what I learned from this.

How was the token leaked?

This happened back when I was running K3s on my home server. At my workplace we
use Kubernetes and deploy our workloads using FluxCD for
a GitOps-based approach. I loved
this so much back then that I wanted this at home as well. It didn’t age well
due to the amount of work needed to maintain the deployment manifests (imagine
having to maintain every NixOS module for your homelab services), but that’s
a story for another day.

Due to the declarative nature of GitOps configurations, you will quickly run
into a similar issue when trying to configure secrets for modules on NixOS. In
Kubernetes-Land there are of course many options to choose from. I chose
Sealed Secrets back then, as
it seemed fairly easy to encrypt secrets without having to maintain the
certificate.

This is where things went downhill. See, the easiest way to use Sealed Secrets
is to create a regular Kubernetes Secret manifest and then “seal” it using the
kubeseal utility. The tool will take your Secret and generate a SealedSecret
manifest with encrypted contents, that will then be decrypted on the cluster.
This seems like a solid way of doing this, as it’s actually quite similar to
how we do it in NixOS-Land with agenix and
sops-nix. But there is one catch:
kubeseal never modifies or removes the original Secret manifest. That means
that, unless you have a .gitignore
entry

that would make Git ignore these files, there is a risk of accidentally
commiting this file to your publicly viewable Git repo.

Well, as you can imagine from this long exposition, I accidentally committed
the source Secret manifest to the repo due to a simple mistake. Instead of
calling it secret.yaml.orig, I called it secret.orig.yaml which wasn’t
covered by my .gitignore file. So it just took one distracted code change to
accidentally commit this file, which seems to have happened on
2023/07/04
.

These are base64-encoded secrets and tokens and therefore effectively
plain-text.

Note that all the secrets mentioned here had been rotated back when this
vulnerability was reported.

What can I do to prevent this?

Nothing really. Mistakes happen, and we are all merely human. Though humans
aren’t the only ones leaking tokens nowadays!

I learned from this that the best I can do is reduce the impact. First, it’s
always a good idea to set an expiration date for a token. Rotating tokens
should be a very simple operation in any system, and if it isn’t, then that
should be worked on. In my case, I have limited all my GitHub secrets to
a maximum lifetime of 365 days, and much less for ones that are very easy to
rotate and/or rarely used. This not only reduces the impact of an old and
unnoticed leaked secret but also gets rid of unused secrets over time.

Additionally, the primary issue here was the permissive scope. The leaked token
was a classic one issued with the public_repo scope. Before this token was
reported, I was not aware that public_repo included write access to all repos
my account can write to. As the token was only used for increased API rate
limits, I have replaced it with a fine-grained token that only has read access.

TL;DR

I leaked a token years ago due to human error. Now all my tokens have an expiry
date of at most a year and much more limited scopes. Don’t use GitHub classic
tokens unless you really have to.

26 Likes