Flexible scan result policy
Create policy your way
A note
the 40% case study
This case study represents around 40% of the process and work behind this project. If you want to see what a more complete one, check:
I have worked on many more projects throughout my design life and it is luxury to document everything during work with my workload. I could probably spend months turning all of them into detailed case studies.
But I am also a mum, a daughter, a wife, a friend, an artist, and a person who needs time for physical exercise, meditation. I choose not to spend all of that time documenting work I have already done.
But if a particular project makes you curious, ask me about it. I’m very happy to open the design files, show you the details, and talk through the decisions, mistakes, trade-offs, and things that never made it onto this website.
Problem statement
Security is hard, even for those trained in it. As "shift-left" practices push security responsibility towards developers, there's growing pressure to simplify how requirements are expressed and understood.
Human-readable language lowers the barrier to entry, but risks losing the depth and flexibility that security policies require.
The challenge is designing a system that doesn't force a trade-off between power and accessibility.
My responsibilities
User research & validation — Conduct problem validation research to identify and prioritise user needs.
Solution design — Design a structured, intuitive framework for policy configuration.
Solution validation — Validate design decisions through usability testing and feedback loops.
Implementation support — Deliver design handover and support engineering with implementation planning.
Analyzing JBTD
Understand users, empthy with users

Convert to details user needs
Policy Settings
Users need more granular criteria for scan result policies, including the ability to filter by:
Age of vulnerabilities
False positives
Fixable vulnerabilities (container and dependency scans only)
New and previously existing vulnerabilities
Detection status: detected, dismissed, or resolved
Users need support for complex, multi-condition logic using "and/or" operators to handle advanced policy scenarios.
Users need role-based approver assignment, so approvals are tied to roles rather than individuals.
Users need a simple, low-friction way to configure and send security notifications.
Users need a security-approval-first workflow, delivered alongside MR view improvements.
Merge request page (Out of scope)
Users need clear, contextual communication on the MR page when security approval is active — across all possible states and situations.
Users need an explicit signal when an MR is blocked specifically by security approval rules, clearly distinguishing this from a pipeline still in progress.
Users need clear guidance on what to do when an MR has a code conflict alongside a pending security approval.
Users need a security-approval-first workflow that surfaces the approval requirement before other actions.
Users need security approval to be automatically waived when all security scans are removed from an MR.
Iteration x - 50+ small iterations after the base is completed
Ex 1 - resizable interface and code view
Problem
Switching between rule mode (forms) and YAML mode (code) is broken and one-directional — rule mode edits sync to YAML, but not vice versa. Combined with vague "invalid property" errors and no way to pinpoint validation issues short of resetting fields one by one, users are forced to commit to a single mode and waste time troubleshooting instead of building policies.
Solution
A new split-view Advanced Policy Creation Editor showing UI and YAML side by side, with real-time two-way sync. Users can start in the UI and watch YAML build live, or edit YAML directly and see it reflected in the UI, with validation errors surfaced immediately as they work — letting them move fluidly between visual and code-based editing instead of choosing one upfront.
Ex 2 - resizable interface and code view
Problem
Security policies currently lack a way to lock unset variables, leaving a gap that undermines compliance and pipeline integrity. Users can't ensure that variables left intentionally unset (e.g. SAST_RULESET_GIT_REFERENCE) stay unset — a project or global variable can silently fill the gap at execution time, letting someone swap in a remote ruleset or otherwise tamper with analyzer behavior and bypass the policy. This also blocks Software Supply Chain Security use cases: achieving SLSA L3-style guarantees requires locking all undefined variables in custom build/signing jobs so tampered or injected variables (from instance/group/project level) can't alter the attestation process.
Solution
Give policies the ability to lock unset variables — either individually or as a global "lock all undefined variables" option with exceptions for specific variables that should still inherit project-level values. At job execution, the policy reads in the variable set and enforces the lock: if a variable was configured as empty/unset/locked, any newly introduced value (e.g. pulled from instance/group/project config) is ignored and the variable stays empty. Applied to enforced custom CI jobs like build and signing, this ensures those jobs — and the pipelines that depend on them — can't be tampered with via variable injection, providing a practical path toward SLSA L3-level integrity guarantees.









