ScrutoraCode, cloud & consent

Read the source. Follow the data.

Every path a value takes, from the line that touches it to the store, log or sub-processor it reaches. Not a grep for field names.

…/useradministration/service/ForgotPasswordServiceImpl.javaa public banking platform
45 @Override
46 @Transactional
47 public void requestPasswordReset(final String email) {
48 final AppUser user = this.appUserRepository.findActiveUserByEmail(email);
49 if (user == null) {
50 log.debug("Password reset requested for non-existent or inactive email: {}", email);
51 return;
52 }
16 lines (53–68), no personal data touched
69 this.emailService.sendForgotPasswordEmail(organisationName, contactName, email, user.getUsername(), temporaryPassword);
requestPasswordReset(String email)1 field · 3 sinks
PIIemail3 sinks · 2 unprotected
Live traceone field · 3 sinks
STORAGEfrom line 48
Primary datastore
…/useradministration/domain/AppUserRepository.javaparameterised
LOGGINGfrom line 50
Application log
…/service/ForgotPasswordServiceImpl.java:50unmasked
SHARINGfrom line 69
Email provider
…/infrastructure/core/service/PlatformEmailService.javaleaves your estate

One field, three destinations. The leak sits two lines after the lookup nobody would question. Clone the repo and read it.

Ordinary code from a well-run open-source project. That is the point: this is not a bad codebase, it is a normal one.

01 · What it reads

Everything you ship, not just the application code.

SOURCE

12 languages, parsed to a syntax tree. Values are followed across functions and files. The analysis knows a variable, not a word.

INFRASTRUCTURE

11 IaC formats (Terraform, Kubernetes, Dockerfiles, pipelines), read as configuration rather than as text.

DEPENDENCIES

The full tree, with advisories resolved against the packages that actually sit on a regulated-data path.

SECRETS

Credentials, keys and tokens committed to the repository, including the ones inside build files and CI config.

270+ rules, one pass, one graph.

02 · A findingNO GENERIC ADVICE

Every finding explains itself.

Why it matters, the exact path the data took, and the change to make, all on one screen, so nobody has to go and interpret a rule id.

Scrutora finding detail: PII-001, why it matters, the data-flow trace from line 45 to line 50, a concrete fix, and the clauses it maps to.
The trace is the part that matters: line 45 takes the parameter, line 48 uses it, line 50 logs it unmasked. The fix names the call to change.
03 · The queue

Grouped by what they break, not by file.

A list of 69 findings is a backlog. The same 69 grouped by the obligation they touch is a plan, and the severity mix tells you whether to start today or this quarter.

Findings grouped by framework, with severity and status filters.
Findings from a scan of the demo project, grouped automatically by the regulation they touch.
04 · ClassificationNO RE-SCAN NEEDED

You decide once what counts as personal data.

Every scanner guesses at what is personal data, and every scanner gets some of it wrong. The difference is what happens next: one decision here updates the data flow, the RoPA, the blast radius and the findings at once, rather than being re-litigated on every screen, every scan.

Confirmed or rejected, the decision is yours and it sticks. The scanner proposes; it does not overrule you.

The data dictionary: confirmed, rejected and undecided fields, with erasure coverage.
33 confirmed, 10 rejected, 1 undecided, plus the erasure check that falls out of it.
06 · Try itPUBLIC REPOSITORIES

Point it at a repository.

A public repository, read once and not kept. You get the data map: every personal-data field, where it lands, and who receives it. Or run the container on your own runner, and the source never reaches us.