My first real open source contributions made me happy
This week I helped in two repositories that are not mine: dograh-hq/dograh and laramint/laravel-brain.
It made me genuinely happy.
Not because the patches were huge. They were not. Not because I suddenly became an open source expert. I did not. It felt good because I crossed a line I had been watching from the outside for years: I read someone else's project, understood a real problem, opened PRs, got feedback, adjusted the work, and saw one contribution become part of a release.
That is small in the scale of open source. But for me, it was a big personal step.
The surprising part: the most useful work was mostly about removing noise.
Dograh: helping an open voice AI project harden setup
Dograh is an open-source, self-hostable voice AI platform. That made the contribution exciting for me: it sits close to the kind of AI tooling I care about, but it is not my project and not my comfort zone.
The merged change was PR #458: generate a Redis password during setup and wire it through Docker Compose.
The project already had setup scripts that generated secrets like OSS_JWT_SECRET and POSTGRES_PASSWORD. Redis still had a fixed fallback value in the compose files. The right change was not to add a separate deployment path or redesign Docker. Maintainer feedback pointed in a simpler direction: extend the existing setup flow.
So the PR did that:
- generate
REDIS_PASSWORDin the remote setup script - generate it on first local Docker start if missing
- pass it into Redis
--requirepass, healthchecks, andREDIS_URL - preserve old installs with
${REDIS_PASSWORD:-redissecret}
That last part mattered. New installs get a random secret. Existing installs do not break. The change landed in Dograh's 1.38.0 release and was listed as my first contribution in the release PR.
Seeing my username in that release note felt great. Small security hardening, real project, real merge.
Laravel Brain: helping a PHP tool become easier to trust
The other repo was Laravel Brain, a PHP/Laravel tool that scans a Laravel app and renders the request lifecycle as a graph.
I tested it against a real Laravel app and hit a different problem: the security panel was reporting too many false positives. The app had real security boundaries, but the analyzer could not always see them.
PR #50 reduced three kinds of noise:
-
->all()calls on collections were being treated like unvalidated HTTP request input - signed routes, custom HMAC middleware, and trusted webhook routes were being treated as public writes
- Breeze/Fortify login throttling inside controllers or form requests was being missed because it was not always expressed as
throttle:middleware
The important boundary was not "hide warnings". It was "only warn when the analyzer can justify the claim".
The PR added config hooks for app-specific auth middleware and trusted route patterns, recognized signed URLs as authentication, and added tests both ways: cases that should stop warning and cases that must still warn.
That PR merged.
Then PR #51 went one layer deeper. It handles custom Laravel auth middleware aliases more correctly:
- reads
$middleware->alias([...]), not only$middleware->alias('key', Class::class) - recognizes middleware classes that extend Laravel's
Authenticate - stops treating unknown middleware as proof that a mutating route is public
That PR is still open as I write this, but the lesson is already useful: for static analysis, unknown does not mean public. Unknown means the tool should be careful about the claim it makes.
What I learned
My first useful open source contribution was not a big feature. It was smaller and more grounded:
- follow maintainer feedback instead of defending my first idea
- prove a bug from a real app without exposing private context
- keep the patch narrow enough to review
- add regression tests for both false positives and real positives
- preserve old installs while improving new ones
- write the PR body as part of the work, not as decoration
The PR description became almost as important as the code. In an unfamiliar repo, maintainers need to know the problem, the root cause, the compatibility story, and exactly how the patch was tested. If that explanation is weak, even good code becomes expensive to review.
The other lesson: tools that analyze security need humility. A noisy warning is not neutral. If a dashboard says everything is high risk, people stop trusting the dashboard. Reducing false positives is not cosmetic work; it protects attention for real findings.
I still have a lot to learn about contributing to other people's projects. But this first round made me happy and gave me a useful rule:
Start where the project already wants to go. Make one real path better. Leave tests behind. Do not make maintainers guess why the change exists.
Top comments (0)