Every screen
What it actually looks like
36 pages, captured from a demonstration instance loaded with twenty repositories worth of scan output. Nothing here is a mockup: every screen is the product's own, and the counts, the rankings and the reasoning on each finding are what it produced from what it was given.
Everything on screen is invented. The organizations and repositories are made up, no commit author is in the data at all, and every credential is shown through the product's own masking: four leading and three trailing characters, which is what the report files carry.
Click any screenshot to open it full size. Once it is open, use the arrow keys to move through the set, click the picture again to see it at its true pixel size, and press Escape to close it.
Setting up · 8 screens
Local accounts with a second factor, or single sign on against any OpenID Connect provider. The first administrator password is printed once by the installer and has to be changed on first use.
GitHub, GitLab, Bitbucket, Azure Repos, AWS CodeCommit, Google Cloud Source Repositories, Assembla, Beanstalk, Subversion and Perforce. Each connection carries its own credential, scope, branch list and sensitivity labels.
A branch box with no idea what exists is a memory test, and a name typed with the wrong case matches nothing, scans no code and reports success. So the box offers the branches past scans of this account actually walked, with the number of repositories each one appears in, and a click puts one in.
Routed by severity, on findings that are new rather than on the standing backlog. Mail goes by SMTP, with or without a password, or through Microsoft Graph for tenants with basic authentication switched off.
Every run, what it covered, how long it took and what it found. A repository stopped at its time limit is counted as partial rather than as scanned or failed, because it is neither. An account nobody has put anything in yet is empty rather than failed, so the red row means something the night it appears.
JSON, CSV, SARIF, both VEX dialects, both combined bills of material and the per repository set as one zip. The findings and the VEX documents are rewritten whenever a decision changes what is reportable. The SBOMs are the only files here that cannot be, because a bill of materials only ever comes from a scan, and the page says so.
Repositories at once, scans at once, and what semgrep and TruffleHog may each use inside one repository. They multiply, which is the thing worth understanding before raising any of them. Beside them, how many days of history a run walks and whether idle time is used to finish the rest.
Engines, thresholds, schedules, retention and the scanner's own tuning. Secrets are encrypted in the database and a settings change is audited by name, never by value.
Every day · 5 screens
What is open, what arrived since the last scan, and what is worth doing first. The counts are of findings nobody has set aside, so the number falls when work is done rather than when a filter is changed.
One list across every connection, every organization and every repository. A verified credential outranks a critical nobody can reach, because one of them is a key somebody can use this afternoon. The line under the heading says how many are left out for sitting in packages the code does not reach, and offers one click to put them back.
Every column filters, and the filter is in the address, so a view can be sent to somebody else and it will be the same view when they open it.
Two hundred and seventy eight of three hundred and sixty one dependency findings on this corpus came back as not reached, each with the sentence that justifies it rather than a bare verdict.
Not a package with a hole in it: a package published to steal something. These are never softened by reachability, because a malicious package runs when it is installed.
One finding · 2 screens
The masked value, the fingerprint, which branches it is live in, whether the provider says it still works, what the repository holds, who can push to it, and the buttons for every decision available.
The recommended grade sits beside the engine's own, with the reasoning that produced it. Nothing changes until somebody accepts it, and that lands in the audit log with their name on it.
Deciding · 5 screens
Twenty rules ship, and every one can be switched off. An administrator can add rules by value or by path, and the box at the bottom shows what a candidate would match before anything is saved.
A rule can match a path, a rule name, or the fingerprint of a credential value, so the same key committed somewhere else is covered by the same decision. Expired rules are counted rather than quietly forgotten.
One finding, one decision, one reviewer, one date. An accepted risk is emitted into the VEX document as affected, never as not affected, because a customer reading it deserves the truth.
A rule or a CWE regraded across the estate, or one finding regraded on its own. The engine's original grade stays visible beside the new one.
A grade is usually a statement about a combination. A credential that only ever existed in git history and is still open is one rule with one reason, and the page says how many findings each rule covers before anybody saves it and after.
Context · 6 screens
The application it belongs to, both owners, the environment and what data it carries. The whole table exports to a spreadsheet and comes back, because most organizations already keep these answers somewhere else.
Access counted per organization and per repository, with outside collaborators separated from members, because those two numbers mean very different things.
A row opens to show the description, what the repository holds, and where each answer came from: set here, or inherited from the account. Only an administrator can write these.
The other half of blast radius, built from the bill of materials rather than from the findings, so a package with no advisory against it still has a row. That is the only kind of table that can answer "is this version anywhere" on the morning a release is announced as compromised, two days before there is an advisory to match on.
Every version, every repository and every branch, with the license and whatever advisories exist against that exact version. A release branch routinely pins a version the default branch has already moved past, which is why the branch is a column rather than a detail. The search exports as CSV, JSON or a CycloneDX document.
What was scanned, when, how big it is, and what came back. Archived and forked repositories are marked, because they usually deserve a different answer.
Accountability · 5 screens
Every decision anybody made, filtered as you type. Sign ins, exceptions, severity changes, settings, impersonation, scans started and stopped.
The whole detail of one event, with a link to whatever it names. Enough to answer "who set this aside, and what did they say" without opening the database.
A person reads a branch and signs it. A completed scan signs off the branches it found nothing to read on, in its own words and marked as its own, so nobody reads a machine finding nothing as somebody having looked.
A certification hides nothing. The branch below is signed off and the low graded findings on it are reported exactly as they would be otherwise, because a badge that could hide a finding would be one person's confidence turned into everybody else's blind spot.
Three roles: a reader who can only read, a developer scoped to their own repositories who can ask for an exception, and an administrator who can approve one. An administrator can view the product as another user to reproduce what they are seeing, and that session cannot write anything at all.
Trends and drill down · 5 screens
The chart, the risk matrix and the grid all answer to the same filter, so narrowing one narrows the picture rather than opening a different one. The line is worked out from what every finding says about when it was first seen, so a chart exists on the first day rather than ninety days after the product is installed.
Every column sorts and the table pages, both across the whole set rather than across the rows on screen. Each row offers the two ways on: down a level, or out to the findings themselves. The count underneath says how much is behind the page you are looking at.
A repository opens into its branches, which is where a release branch that is months behind the default one stops being a detail and becomes the answer. The chart and the risk matrix above have narrowed with it.
Worst first by grade is the right default and the wrong answer to "who has the most of this one". Clicking a heading asks that instead, clicking it again turns it around, and the arrow says which way it is reading.
Paging happens after sorting rather than before it, so page two is the next twenty five of the order you asked for and not the next twenty five of some other one.
About these images
A headless browser, against a running instance
Each one was captured at twice the pixel density from a signed in session on an instance that had just finished a scan, then scaled down. What you see is what the software renders.
Real findings, with the names changed
The repositories scanned are real and public, so the counts, the severities and the rankings are genuine. Every organization, person and repository name was replaced with an invented one before capture, and every credential is shown through the product's own masking, which is all it stores.
Nothing drawn on top
No annotations, no arrows and no tidied up empty states. Where a page says nothing has been configured yet, that is what it looks like.
Run it yourself in about ten minutes
One command on any machine with Docker. It is free, MIT licensed, and it never sends your code anywhere.