On Being Blocked From Contributing to lodash
My Github account was blocked from contributing security improvements to the lodash project. This was my first open source work in a while, and unfortunately, it appears it was a waste of time. That said, I did learn a few lessons about contributing to open source projects that others might benefit from.
Background
I've been going down a rabbit hole to figure out how to improve supply chain security in the JavaScript ecosystem. A common problem is the inability to trust the true origin of code within a package and how that package was built and published. Phishing attacks on npm registry users exploit this weakness - threat actors with stolen credentials will directly publish malicious package versions to the npm registry, bypassing CI/CD entirely. A consumer of the package will be none the wiser. npm install
will happily install the malicious package version if configured to do so.
One way to detect this type of attack is through package provenance. Publishing packages with provenance is the process of creating a signed statement of attestation during the building of a package so that the build process can later be verified. The statement of attestation contains metadata about the build, provided in part by a trusted CI/CD platform, like Github Actions runners. While not a security panacea, dependent projects can check the statement of attestation to detect whether a package was published by a trusted CI/CD process or directly uploaded to the artifact registry, bypassing CI/CD.
The npm client itself has made the process of generating and publishing a statement of attestation trivial - all you need is a Github Actions workflow that runs the publish
command with these flags.
npm publish --provenance --access public
For packages that already use Github as a code forge, adopting a workflow to publish packages with these additional flags is, in most cases, a low-effort task. Despite this, the adoption of package provenance appears abysmally low. Of the ten most popular packages on the npm registry, only two are published with provenance. Even the typescript
package is not published with provenance.
Trying to Help
I've always felt like an outsider in the world of open source - mostly a consumer, not a contributor. It occurred to me that since I value having npm packages published with provenance, I could be the one to push those PRs. This could be my way of giving something back.
Among the top ten packages on npmjs.com without provenance, lodash was the one that caught my eye. I have used lodash many times, both professionally and personally. What stood out specifically about it is that there has not been a new release in over 5 years, but it's still being downloaded tens of millions of times per week. When I went to the Github repo, I saw the main branch had not received a new commit in 9 months. When I checked for a workflow to publish the package, I found nothing. I saw what I thought was a good opportunity. I was certain I could figure out the build process, create a new Github Actions workflow to automatically build lodash, and add provenance to boot. I figured if my initial PR was rejected, I could at least start a conversation about supply chain security and reproducible builds for this very popular project.
Within a few hours, I had a workflow that was mostly working. I reverse-engineered the packaging workflow by digging through git history, reading docs and the wiki. I even managed to publish a forked version of lodash to npmjs with provenance after some trial and error.
Unfortunately for me, that trial and error included opening a PR against the lodash repo before I was ready. I quickly closed the PR because I realized that the build artifacts in my version were not quite a 1-to-1 match with what was in the latest build of lodash.
I spent a few more hours in vain trying to figure out how to replicate the build. Eventually, I called it a day and decided to open an issue in the morning to ask the last maintainer who published a build how they managed to generate it.
Blocked
I quickly typed up a Github issue the next morning and pressed "Create". Nothing happened. I looked around and saw an error I had never seen before on Github: "Error - Failed to create the issue."
I figured Github was having an outage, so I took a break and did something else. When I tried again though, I saw the same error repeatedly, even after changing the title and content of the issue several times in the off chance I was triggering some kind of blocklist. I decided to try and reproduce the issue in my own repository. No error - I was able to create a Github issue successfully.
At this point, I suspected something was up specifically with lodash but I wasn't sure what. I went back to my closed PR on a hunch and noticed some new activity. The PR, despite being already closed, was locked and limited to collaborators. At this point, I was fairly certain I had been blocked. What finally gave it away was when I tried to use the watch action on the lodash Github repo, I got a truly bizarre and nonsensical error - I couldn't watch more than 10,000 repos on Github. I don't even watch 100 repos, and I could watch any other repo I wanted, outside of the lodash organization.
In an attempt to reach out to clear up any misunderstandings, I opened a Github issue on my forked repo, tagged the lodash org and primary maintainer, and explained the situation. I gave context as to why I had opened the PR, and what I wanted to achieve. Two weeks later, no response. As a last-ditch effort, I sent an email directly to the same primary maintainer, using an email I found in git commit history, but I have also received no response there either. At this point, I believe I've been permanently blocked.
Lessons Learned
While the effort I ultimately put into this project appears not to have furthered my goals, at least this was a learning experience. My contributions being rejected reinforces a belief I already held before going into this project - open source maintainers don't owe me anything. That said, I'm still confused as to why I was blocked for opening a single PR. I wanted to spark a conversation on how to publish a new version of lodash and ultimately make the build process transparent and trustworthy. I'm genuinely curious if my PR was viewed incorrectly as malicious, or if the maintainer who blocked me simply has no interest in what I was trying to do and is signaling that to the lodash community.
When I have time, I will continue to try and add provenance to open source NPM packages where I believe there is value, but I will start slowly and open an issue first to discuss the change. If there's interest, I'll create a pull request. If I'm ignored, I'll move on. My mistake with lodash was jumping in headfirst without gauging the interest of the maintainers or getting a better sense of what was happening in the project. I found out after the fact that the primary maintainer of lodash declared "issue bankruptcy" back in 2023, closing a slew of open Github issues and starting from scratch, and that a major rewrite of the codebase seems to have stalled out with no progress in 11 months. While the CONTRIBUTING.md in the repo indicates "Contributions are always welcome", I mistakenly believed that demonstrating enthusiasm through a pull request was the best way to contribute to open source. I should have known better. As a professional software engineer, I've learned this lesson before: more effort upfront doesn't guarantee results. A five-minute conversation to gauge interest can save hours of work on an unwanted PR.