DEV Community

Suman Mandal
Suman Mandal

Posted on

From Design Discussions to Production: Building Report Metadata Protection in Kubescape

Note

This article focuses on the engineering journey behind designing and implementing Report Metadata Protection in Kubescape v4.0.11.

If you're looking for installation instructions, usage examples, or command reference for --hide, --encrypt, and kubescape decrypt, please refer to the official Kubescape documentation:

Official Documentation: https://kubescape.io/docs/scanning/#protecting-report-metadata


Can a Security Report Become a Security Risk?

That question stayed with me throughout this project.

Security scanners exist to help organizations improve their security posture. They identify vulnerabilities, misconfigurations, exposed secrets, and policy violations. But while working with Kubescape, I realized something interesting.

The reports themselves often contain sensitive information.

A typical scan report may include Kubernetes namespaces, workload names, repository metadata, Git information, source file paths, container image names, and other identifiers that reveal details about an organization's infrastructure.

These reports are frequently shared outside engineering teams—for compliance reviews, customer support, security audits, or even when opening issues in public repositories.

At that point, I started asking myself a simple question.

Can a security report itself become a security concern?

The answer was yes.

That question eventually became the starting point for Report Metadata Protection, a feature that shipped with Kubescape v4.0.11.

This article isn't about how to use the feature. Instead, it's about everything that happened before the feature reached users.



The Problem We Were Actually Trying to Solve

When people hear the phrase "security report," the assumption is that the report itself is safe to share.

After all, it's the output of a security scanner.

But while working on Kubescape, I realized something interesting.

Although the report doesn't expose secrets like passwords or API tokens, it often contains metadata that can reveal a surprising amount about an organization's infrastructure.

For example, a report may include:

  • Kubernetes namespaces
  • Workload and deployment names
  • Container image names
  • Repository information
  • Git metadata
  • Source file paths
  • Cluster resource names

Individually, none of these fields are necessarily sensitive.

Together, however, they paint a detailed picture of an organization's environment.

Many organizations share scan reports with:

  • Security consultants
  • Customers
  • Compliance auditors
  • Open-source maintainers
  • Internal teams outside engineering

In those situations, exposing infrastructure metadata may not be acceptable.

The obvious solution might seem to be removing all of that information.

Unfortunately, that creates another problem.

Most security findings reference workloads, namespaces, or resources.

If those identifiers disappear completely, the report quickly becomes difficult to understand.

That led us to a fundamental engineering challenge.

How can we protect sensitive metadata without making the report useless?

That single question influenced almost every design decision that followed.

Instead of asking "How do we hide names?", the real question became:

How do we preserve the usefulness of a security report while protecting the information organizations don't want to expose?

Everything else—the anonymization pipeline, encryption support, decryption workflow, and CLI design—was built to answer that question.


From One Idea to Two Different Workflows

Initially, I thought there would be a single solution.

As the design discussions evolved, it became clear that different users had different requirements.

Some users wanted reports they could safely share without exposing infrastructure names.

Others needed actual cryptographic protection because reports might travel outside trusted environments.

Trying to satisfy both requirements with a single implementation would have complicated the user experience.

Instead, the feature evolved into two complementary workflows.

The first focuses on hiding sensitive identifiers while preserving the structure of the report.

The second focuses on encrypting sensitive metadata so that it can later be recovered only by someone who possesses the correct master key.

Although both workflows aim to protect report metadata, they solve different problems.

Understanding that distinction became one of the most important design decisions during development.


Building the --hide Workflow

The first capability introduced was the --hide flag.

At first glance, replacing names might sound simple.

It isn't.

Simply removing values would make reports difficult to understand.

Imagine every workload name becoming an empty string.

Relationships between resources would disappear, making debugging much harder.

Instead, the implementation generates deterministic pseudonyms.

That means identical values always produce identical replacements.

For example, if the namespace production appears in twenty different places inside the report, every occurrence is replaced with the same pseudonym.

Although the original value is hidden, the relationships remain intact.

This allows users to understand the report without exposing sensitive infrastructure details.

This was an important balance between usability and privacy.

The goal wasn't encryption.

The goal was making reports safer to share while preserving their usefulness.


Why --hide Wasn't Enough

As discussions continued, another use case became clear.

Some organizations don't simply want identifiers hidden.

They need them to remain confidential while still allowing authorized users to recover the original values later.

That requirement cannot be solved through pseudonymization.

Once a value has been replaced, there is no secure way to recover the original information.

This is where encryption became necessary.

Rather than extending the --hide implementation beyond its intended purpose, Kubescape introduced a separate workflow dedicated to protecting report metadata through encryption.

The result was a much cleaner design.

Each workflow now had a clear responsibility.

  • --hide reduces accidental exposure.
  • --encrypt provides cryptographic confidentiality.

Trying to combine both into a single workflow would have made the feature harder to understand and maintain.

Separating them made both implementations simpler and more intuitive.


The Engineering Lesson That Stood Out

Looking back, I don't think the most valuable lesson from this project was learning how to implement anonymization.

It was learning that software design is about understanding trade-offs.

There is rarely a single "correct" solution.

Every design decision introduces compromises.

Removing metadata makes reports less useful.

Pseudonymization preserves usability but isn't intended to provide cryptographic protection.

Encryption protects confidentiality but introduces key management and recovery workflows.

Choosing between those approaches wasn't just an implementation decision.

It was a product design decision.

As contributors, it's easy to jump straight into writing code.

This project reminded me that the quality of the implementation often depends on the quality of the conversations that happen before implementation even begins.


What's Next?

This article focused on the journey from identifying a security problem to designing the overall solution.

In the next part, I'll dive into the implementation itself, including:

  • How the anonymization pipeline was designed
  • Why deterministic pseudonyms were chosen
  • Integrating the feature into Kubescape's scanning pipeline
  • CLI design decisions
  • Lessons learned while implementing the feature in Go

Eventually, I'll also write about the encryption architecture, including the Data Encryption Key (DEK), master key management, why the master key never travels with the report, and how kubescape decrypt restores protected metadata.


Final Thoughts

This feature taught me much more than how to build anonymization or encryption into a security tool.

It showed me what building production software in an open-source project really looks like.

Ideas become discussions.

Discussions become design decisions.

Design decisions become implementations.

Implementations become documentation.

And finally, after many rounds of review and collaboration, they become features that thousands of users can rely on.

That journey—from design discussions to production—is what made this project so rewarding.


About Me

Hi! I'm Suman Mandal (GitHub: @jijo-OO7), an open-source contributor passionate about Kubernetes, cloud-native technologies, and security engineering.

Through this blog series, I want to share not only the technical details behind the features I build, but also the engineering decisions, design trade-offs, review process, and lessons that aren't always visible in a merged pull request.

If you're beginning your own open-source journey, I hope my experiences can make yours a little easier.

You can find me here:

Thanks for reading, and I'll see you in the next part, where I'll dive into the implementation of the --hide workflow and the design decisions behind it.

Top comments (0)