GitHub / 2020–22

Turning several acquired security tools into one product, so developers can ship secure code.

Problem
Developers wanted to ship secure code. Projects in popular languages rely on a lot of dependencies, any of which a bad actor could use to distribute malware, and the code itself has its own vulnerabilities. GitHub had acquired the tools to find both, from different companies, each with its own way of reporting a problem.
My part
Moved from Microsoft after the acquisition, as GitHub grew its team by bringing people across. Principal Designer in the Security group, hands-on, with code scanning as the main surface, plus requests and support to the Primer design system team.
The idea
One Security product, not three tools. Whatever found the problem, the developer meets it in the same shape, in the pull request, on the line that caused it.
What shipped
Code scanning, generally available from September 2020 and free for public repositories, as part of one Security offering with secret scanning and dependency review.

The setting

Microsoft acquired GitHub while I was at Microsoft, and GitHub quickly grew its team by moving people across. I was one of them. Between 2020 and 2022 I worked in the Security group, which at that point was really a few technology acquisitions, CodeQL for analysing code among them, that had to become one cohesive group and one set of features.

The need was simple to state and hard to meet: developers wanted to ship secure code. Projects written in popular languages like JavaScript rely on a lot of dependencies, and a bad actor could easily distribute malware through one of them. The code itself has its own vulnerabilities. GitHub now owned the tools to find both, but they had come from different companies, each with its own way of reporting a problem.

What I did

At GitHub I was a Principal Designer. The screens on this page are mine. As product designers we also helped the Design System team develop Primer, the shared component library, with requests and support.

The idea

One Security product, not three tools. Whatever found the problem, code analysis, a leaked secret or a vulnerable dependency, the developer should meet it in the same shape, and meet it where they already are: in the pull request, on the line that caused it.

The choices

One alert, whatever found it

Chose
A single alert shape, with the same state, severity, location and history, shared by code scanning, secret scanning and dependency alerts.
Over
Each acquired tool keeping the reporting interface it came withA security dashboard alongside the repository rather than inside it

A developer doesn't care which engine found the problem; they care whether it is real, how bad it is and where it is. A shared shape meant learning one thing: the alert page at the top of this case, with its state, severity, location, affected branches and the record of how it was tracked and fixed, is that shape. The cost was that each tool's native output had to fit the frame: CodeQL's data-flow paths went behind a “Show paths” control, and the details specific to one kind of alert had to earn their place on the page rather than arrive by default.

The finding goes in the pull request

Chose
An annotation on the changed line, with severity, one sentence on what is wrong and a link to the full alert.
Over
The whole alert inline, paths and advisories includedA summary in the checks only, with the alerts kept to the Security tab

The person who wrote the line is the one who can fix it, and the moment they can fix it cheaply is review. But a pull request is already a crowded page, so the inline version had to be short: enough to decide, not enough to fix, with everything else one click away.

A pull request on GitHub where the GitHub Security bot has annotated two lines with code scanning alerts, one Medium and one Critical, each with View details and Dismiss actions; below, the checks list shows code scanning as a required check and ‘Merging is blocked’
The same alert as it appears in the pull request: severity, a sentence, and the choice to look further or dismiss. Below it, the check that can stop the merge.

Blocking the merge is the repository's call

Chose
Code scanning as a status check that a repository can mark as required, so a finding can block the merge.
Over
Always blocking, so nothing vulnerable can be mergedNever blocking: inform and let people decide

Interrupting is a strong move, and the wrong default for a platform with every kind of project on it. Making it a check meant a repository could choose how hard the rule was, using a mechanism it already knew. The cost is that on the repositories that opt in, a false positive becomes a blocker until someone deals with it, which is exactly why the next decision mattered.

Dismissing needs a reason

Chose
Alerts can be dismissed, with a stated reason such as a false positive or something used only in tests, and stay in the history.
Over
No dismissal, so every finding has to be fixed or lived withA silent close

If developers can't say “not this one”, they stop looking at all of them. If they can say it without a reason, the count going down stops meaning anything. A reason keeps the dismissal honest and leaves a record of why, for the next person who hits the same line.

Shipping it

Code scanning became generally available in September 2020, free for public repositories and part of Advanced Security for private ones, alongside secret scanning and dependency review under one Security tab.

Beyond Security

I also designed for GitHub Actions and Code Search. The search work was as much writing as drawing: specifying how qualifier suggestions should narrow as a developer types.

GitHub’s search box open on a repository page, listing result types (Repositories, Code, Commits, Issues, Discussions, Packages…), with a blue note over the page reading: selecting ‘search’ will show all the possible result types available; we could consider pre-selecting Code or Repositories depending on the page the user is
Code search: the result-type menu, with the reasoning written over the frame as it was shared with the team.

Looking back

I was designing for millions of developers I couldn't see, on a platform where every choice was highly scrutinised and commented on on Twitter. The CEO was on there too, listening, and sometimes committing to things in public. That is a different discipline from working with a handful of customers: you find out what people think in public, and quickly, and the roadmap could take shape there as much as inside.

What I would keep is the alert as the unit, not the tool. Deciding early that a developer meets one kind of thing, wherever it came from, is what let three products become one; everything else on this page followed from that.

What I would do differently is design the dismiss path first. Dismissal with a reason came as a consequence of blocking, but it is what makes blocking survivable, and it should have been on the table before it.