The Last Piece of Atlassian

rubyrailstoolingbuilding-in-public

Another security advisory for Bitbucket Server landed this week. No patch coming. That makes it our problem now.

We replaced Jira with Meera two years ago when Atlassian killed self-hosted Jira. That left Bitbucket Server as the last Atlassian product in our stack. We knew it was on borrowed time. Atlassian announced end-of-life for Server products back in 2020, but as long as it was working, the urgency wasn’t there.

It’s there now. Security advisories have been piling up on Bitbucket Server, and there are no more patches coming. Every unpatched CVE makes it more of a liability than an asset. We felt this last year when a deprecated API crashed Wave CI on startup. That was an inconvenience. An unpatched remote code execution vulnerability is a different conversation.

So we started looking at other options.

GitHub

GitHub is where our open-source projects live, and it’s great for that. But putting corporate code there didn’t sit right. GitHub has been in the news for data breaches, incidents where repositories were inadvertently publicly accessible, and, the big one, training AI models on hosted codebases. Besides our internal tools, and our infrastructure code, we have client work. And for sure we didn’t want that in someone else’s training set.

There’s also the practical question of integration. We have Wave CI for builds, Flux for artifacts, Meera for project management. These tools talk to each other. Fitting GitHub into that ecosystem means working within whatever GitHub’s API supports, which may or may not match what we need.

GitLab

GitLab self-hosted was the more serious contender. It’s mature, it’s feature-rich, it runs on your own infrastructure. But GitLab is a monolith: it bundles CI, issue tracking, project management, artifact storage, wiki, and more. We already have all of those. We’d be paying for (and running the infrastructure for) a huge application just to use the git hosting piece.

And the features we actually wanted, like advanced push rules, merge controls, and policy enforcement, are behind the enterprise license. The free tier gives you git hosting and basic merge requests. The controls that make self-hosted git worthwhile for a security-conscious team? Those cost money. For features we’d use alongside a bunch of features we’d never touch.

What we actually need

When I stripped away the noise and listed what we wanted, it was specific:

That’s a well-defined scope. It’s not “build GitHub.” It’s “build the git hosting that fits our stack.”

Codex

Today I pushed the initial commit. The name comes from the idea of a codex, a structured collection of knowledge. Which is what a collection of source repositories is, when you think about it.

The architecture is Rails with Rugged (libgit2 bindings) for git operations. The HTTP backend delegates to the system’s native git-http-backend CGI program, so there’s no need to reimplement the git wire protocol. Rails handles authentication and authorization, then pipes the request through to the git backend. Push and pull work.

The RBAC system is YAML-driven with hierarchical permissions. Resources (projects, repositories, pull requests) form a tree, and granting access at one level cascades down. project:MYPROJ:write automatically implies repository:MYPROJ/*:push and repository:MYPROJ/*:pull. Service accounts get the same permission model as users, because CI pushing artifacts needs the same authorization guarantees as a developer pushing code.

This is the last piece of Atlassian leaving our stack. Jira became Meera. Bamboo became Wave. Bitbucket becomes Codex. The difference this time is that we’re not building in a panic with a license cliff nine days away. We have the time to take this slow and we have the experience from the building all the other dev tools on our side. Let the games begin …