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
- Three acquired tools become one Security product. Whatever finds a problem, the developer sees it in the same form, 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.
What developers wanted was simple: 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 in the Security group. GitHub ran on a strong PED structure, product, engineering and design, with three core people assigned to each feature. The Security design team was five designers. Designers could move a little, because priorities in the tech world change rapidly, which is how I also worked on features outside Security. 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.
How I worked
The work happened in Figma, frame by frame, and the frames carry the thinking: the alert page still has the states I tried and switched off, and the code search frames have my reasoning written on the canvas, for engineers to read next to the design. Between the frames and the product sat design critiques, with design leaders and the rest of the Security design team, and usability tests, often. Sometimes I also helped the research team with upfront research. Feedback on what shipped came in public, on Twitter, and quickly.
The idea
The three tools had to become one Security product. Whatever found the problem (code analysis, a leaked secret or a vulnerable dependency), the developer should see it in the same form, and see it where they already work: in the pull request, on the line that caused it.
The choices
None of these were settled on paper. The alternatives below were prototyped and tested, internally and with some users, before the choice was made.
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. In exchange, each tool's own output had to fit it: CodeQL's data-flow paths went behind a “Show paths” control, and details specific to one kind of alert only made it onto the page if they were worth the space. The Figma file still holds the states I tried and switched off along the way, ‘Fixed’, ‘Tracked in #12345’, experimental, before the set that shipped.
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 what to do, with the rest one click away.

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 catch is that on the repositories that opt in, a false positive blocks the merge until someone deals with it. Hence the next decision.
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. GitHub's own numbers at launch: during the beta it had scanned over 12,000 repositories 1.4 million times and found more than 20,000 security issues, and in the thirty days before GA developers had fixed 72% of the security errors reported in their pull requests before merging. That last figure is the one the pull request annotation was designed for.
Outside 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, with the reasoning on the canvas beside the frames.

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.
I'd keep the decision to make the alert the unit, whatever tool raised it. Settling early that a developer meets one kind of thing, wherever it came from, is what let three products become one.
If I did it again I would design the dismiss path first. Dismissal with a reason came as a consequence of blocking, but blocking is only bearable because of it, so it should have been on the table before.