You paste a Kubernetes manifest into an online YAML linter to debug a deployment error. The linter responds with a helpful parse tree, and silently logs the AWS access key embedded in your ConfigMap, the database credentials in your Helm values, and the JWT secret in your deployment spec. Every value you pasted is now sitting in a third-party log store you have no access to. Nobody announced the breach. You only find out months later when someone notices anomalous API activity originating from an IP range you do not recognize, or when a prospective employer running due diligence on YourCompany/terraform-infra finds a live production key public on GitHub.
CapyToolkit approaches infrastructure-as-code security the same way it approaches every privacy problem: keep the data on the machine. The Cloud Config Sanitizer scans Kubernetes, Terraform, and YAML manifests for hardcoded secrets, suspicious key patterns, and Kubernetes pod security misconfigurations entirely in your browser. No bytes leave the tab. You get a redacted manifest safe for Git, an environment template for local development, and a severity-coded findings list that tells you exactly what was caught and where. Paste a manifest, review the findings, download the clean version, and move on. Every analysis happens through deterministic regex rules and a JavaScript YAML parser. No AI model, no server round-trip, no persistent log of what you pasted.
The tool does not teach you secrets management architecture. What it does is close a specific gap: the moment between “I need to debug this manifest” and “I am about to paste it into some website I do not control.” That is the gap where most accidental leaks happen. A developer chasing a pod crash at midnight is not thinking about data classification. They want a working manifest. The sanitizer catches what the developer’s tired brain misses.
The problem extends beyond obviously sensitive values. A ConfigMap exposing a database hostname and port reveals internal network topology. A Terraform provider block naming a specific AWS account ID narrows an attacker’s search space. Even a resource name like prod-eks-control-plane-sg in a VPC security group definition tells an adversary exactly which environment they are targeting. Individually each piece might seem harmless. Together they form a reconnaissance map that makes any actual credential leak far more damaging.
Why Config Files Leak Secrets
The most common leak path is not a sophisticated nation-state attack. Whether a developer pastes a manifest into ChatGPT to debug a syntax error, drops a Helm values file into a community Slack channel asking for help with a chart upgrade, or simply pushes a Terraform variable file containing default = "postgres://admin:[email protected]:5432/app" without auditing the diff, the result is identical: credentials travel to a system outside the team’s control, an AI provider’s training pipeline, a search-indexed code host, or a chat log with no retention policy and no audit trail.
Hardcoded database connection strings in ConfigMaps remain one of the most persistent patterns in open-source Kubernetes repos. Developers treat ConfigMaps as a catch-all configuration layer, stuffing in everything from feature flags to full URIs with embedded passwords. The Kubernetes API makes ConfigMaps trivially readable, and a team member or workload with ConfigMap access can fetch every key.1 If the cluster does not have encryption at rest enabled for etcd, those values sit in plaintext on disk.2 Helm values files carry their own risk: a values.yaml that works perfectly in a CI pipeline often contains production credentials injected during development. When the repo goes public or the team forgets those credentials after a migration, automated scanners find them within hours.
Terraform compounds the problem further. Teams treat .tf files as safe because “it is just infrastructure code,” but default variable values, provider blocks with inline credentials, and hardcoded region endpoints all land in version control. Once GitHub Secret Scanning flags a repo, GitHub can scan the entire Git history on all branches for hardcoded credentials such as API keys, passwords, tokens, and other known secret types.3
The OWASP Secrets Management Cheat Sheet puts it plainly: hardcoded credentials in configuration files remain one of the top infrastructure security risks, and the violation is almost always accidental. The cheat sheet recommends a centralized secrets vault with automated rotation, but acknowledges that many teams operate without one because the setup cost feels disproportionate to the risk.4 That changes the first time a leaked key appears in a breach report. That is the calculation the sanitizer disrupts: it reduces the cost of prevention to zero while the team works toward a proper vault.
This is the same principle behind CapyToolkit’s social media privacy workflow, which scrubs EXIF metadata and runs browser leak audits before content crosses a trust boundary. For config files, that boundary is the edge of your browser tab. Once crossed, there is no reliable way to revoke what an external service has already logged.
Using CapyToolkit’s Cloud Config Sanitizer
Integrating this check into a pre-commit routine takes only seconds without interrupting standard engineering workflows:
- Dropping a
.yaml,.yml,.json, or.tffile onto the input area (or pasting raw manifest text directly) into the Cloud Config Sanitizer. - Evaluating the real-time findings panel, where each result displays severity level, exact key path (like
spec.containers[0].env[2].value), and detection category. - Copying or downloading the sanitized YAML with
__REDACTED_placeholders replacing every detected value. - Downloading the companion
.envtemplate listing every stripped key. Filling in real values locally and keeping it out of version control.
The output panel highlights each finding with a severity tag and the precise location in the document tree. Critical findings jump to the top. You can expand any result to see the detection rationale: whether a value matched a known pattern, exceeded the entropy threshold, or sat under a suspicious parent key. Multi-document YAML files split by --- are parsed independently, so a single file containing a Deployment, a ConfigMap, and a Secret produces three separate finding groups, each tagged with the Kubernetes kind when the parser can identify it.
The sanitized output replaces every detected value with a unique placeholder: __REDACTED_AWS_ACCESS_KEY__, __REDACTED_DATABASE_URI_1__, __REDACTED_GITHUB_TOKEN__, and so on. Each placeholder is numbered per detection instance, so you can map them back to the original keys. A companion .env template lists every stripped key in a simple KEY=value format. Ready to source with a single command or to load through Docker Compose, Helm --set-file, or any CI environment that reads dotenv files natively. Commit the sanitized YAML to Git. Add .env to .gitignore. Your deploy pipeline injects real values at runtime.
The architecture natively evaluates three core formats: standard YAML, JSON (including Terraform’s HCL-in-JSON representation), and multi-document YAML streams. Everything runs through JavaScript’s YAML parser and a set of deterministic regex rules. No AI model involved, no external API calls. Open DevTools before you paste and watch the Network tab: it stays completely empty during analysis.
The rule engine operates entirely on string matching and statistical analysis, which means two things. First, results are fully reproducible: the same manifest produces the same findings every time, on every machine, with no dependency on a remote model’s changing weights. Second, the patterns are auditable. If you want to know exactly which regex caught a given value, you can read the source directly. This stands in contrast to cloud-based linters that rely on opaque machine-learning classifiers where the detection rationale is server-side and unverifiable.
What the Rule Engine Detects
Secret patterns (critical severity)
Detection runs in three passes. Every string value is checked against twelve known secret patterns during the first pass: AWS Access Keys starting with AKIA or ASIA (temporary session tokens from assume-role operations), GitHub tokens prefixed ghp_, GitLab PATs starting glpat-, Slack tokens matching xox[bprs]-, PEM private keys, JWTs (the same token format you can decode and inspect for expiry claims locally), database connection strings for PostgreSQL, MySQL, MongoDB, and Redis, SendGrid API keys, Stripe live and test keys, Google API keys prefixed AIza, NPM tokens, and Twilio SIDs beginning with AC. Any match is flagged critical. All values inside a Kubernetes Secret’s .data map are always flagged critical regardless of content. This is an important design choice: .data fields contain Base64-encoded strings rather than raw text, which means standard regex engines scanning for plaintext patterns like AKIA or ghp_ will miss rotated or encoded tokens entirely.5 Block-level redaction of the entire .data map sidesteps this problem completely, the tool does not need to decode and parse what is inside a Secret to know it should not be committed.
High-entropy strings (high severity)
Shifting focus to unformatted tokens, Shannon entropy is computed on every string of 16 characters or more in the second pass.6 Anything scoring at or above 4.5 gets flagged as a high-entropy string. This catches base64-encoded tokens, random API keys without standard prefixes, and custom service credentials the regex patterns do not cover. The threshold is deliberately conservative. A random UUID such as 550e8400-e29b-41d4-a716-446655440000 scores around 3.4, so the filter avoids flagging most legitimate identifiers. A 32-character random token like a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 scores above 4.5 and gets caught.
Suspicious key names (medium severity)
To catch risks hiding behind harmless-looking variable names, the third pass inspects parent key names directly. Values sitting under keys like password, secret, api_key, token, or credential are flagged at medium severity regardless of what the value actually contains. This catches placeholder values, development defaults, and comments that convey sensitive context even when the value itself is not a real secret. A ConfigMap entry reading password: changeme does not match any known pattern and scores low on entropy, but the key name alone tells you it belongs in a secrets manager.
Kubernetes security smells (info severity)
Beyond string values, the engine walks Kubernetes pod spec trees and flags security-context misconfigurations: containers running with privileged: true, hostNetwork: true, hostPID: true, containers that set readOnlyRootFilesystem to false or omit it entirely, and pods where runAsNonRoot is missing or explicitly false. These are tagged info severity. They are not secrets, but they represent meaningful security weaknesses. A container running with privileged: true weakens the isolation boundary that NIST treats as a core container-security concern.7 These flags should only appear in manifests where they are genuinely required, not copy-pasted from a Stack Overflow answer. To help map your configurations against these scanning tiers, the engine organizes detections into four actionable layers:
| Severity | Description | Example |
|---|---|---|
| Critical | Known secret patterns + all values in Secret .data/.stringData | AKIA... becomes __REDACTED_AWS_ACCESS_KEY_1__ |
| High | Shannon entropy 4.5 or higher on strings of 16+ chars | Base64-encoded token without a known prefix |
| Medium | Value under a suspicious parent key name | password: "changeme" in a ConfigMap |
| Info | Kubernetes pod securityContext misconfigurations | privileged: true on a container |
Where Secrets Hide in Kubernetes Manifests
ConfigMaps with database credentials
The single most prevalent leak: a ConfigMap with a key like DATABASE_URL holding a full connection string including username, password, host, and database name. ConfigMaps are explicitly designed for non-sensitive configuration, yet developers routinely treat them as a convenient key-value store for everything because they are simple to create and universally supported by every Kubernetes workload. The real danger comes when these manifests escape the cluster: pasted into support tickets, committed to public repos, or archived in CI logs. Even with RBAC restricting access inside the cluster, anyone with Git access can read the plain text. Teams often apply permissive repository access policies to infrastructure repos because “it is just YAML,” not realizing that the YAML contains everything an attacker needs to connect directly to a production database.
Making matters worse, Kubernetes stores API resource data in etcd as plaintext unless you enable at-rest encryption, and EncryptionConfiguration is resource-specific: including secrets does not automatically encrypt configmaps. Any compromise of the etcd data directory exposes every key-value pair in every unencrypted ConfigMap across every namespace. This makes client-side sanitization of ConfigMap manifests even more critical.
Terraform variable defaults
A .tf file that declares variable "db_password" { default = "x9Kj2mPq" } is readable by anyone with repo access. Compounding this risk, local Terraform state files pose an even greater threat by storing every single infrastructure attribute in unencrypted JSON.8 The variable declaration alone is usually enough for automated credential scanners that sweep public GitHub. These defaults slip in during local development: the developer enters a temporary password to test the terraform apply, forgets to remove the default, and pushes. The same pattern appears in provider blocks, where hardcoded region strings, access keys, and endpoint URLs often cluster in a single file.
Terraform adds an additional dimension to the leak: the state file. Unlike Kubernetes manifests, which describe desired state, Terraform state captures the actual deployed resource attributes, including values the developer never intended to store in plaintext. Cloud provider access keys, database connection strings computed during resource creation, and randomly generated passwords for managed services all land in state. Many teams store this in version control when they first set up Terraform, then never move it to a proper backend. Even teams that switch to remote state backends like S3 with encryption may have weeks or months of state file history sitting in Git, each revision containing the full set of deployed secrets.
Helm values committed alongside the chart
A values.yaml in a Helm chart directory often carries production database passwords, third-party API keys, and internal service endpoints. Helm’s design expects values to be overridden at deploy time via --set or --values, but local testing habits hard-code them.9 When the chart directory gets committed, the secrets go with it. The compounding problem is that all three patterns frequently coexist in a single repository: a Terraform module with a plaintext password variable, a Helm chart with inline production credentials, and a ConfigMap manifest copy-pasted during debugging. This multi-vector exposure means a single git filter-branch pass might catch the obvious files while the ConfigMap key buried in a deployment spec goes unnoticed.
The Kubernetes Pod Security Standards define a baseline policy that explicitly disallows privilege escalation paths like hostNetwork: true and privileged: true, yet these settings still appear regularly in public repos and internal codebases.10 Security context misconfigurations do not leak credentials directly, but they widen the blast radius. If any secret in the manifest is eventually compromised, a pod running with host network access and privileged mode gives the attacker a much easier path to node-level operations.
Handling the Sanitized Output
Once the scan finishes, managing the generated outputs correctly keeps deployments secure without disrupting the CI/CD pipeline.
What to commit
The sanitized YAML with __REDACTED_ placeholders is your version-controlled manifest. It preserves the structure, key names, and non-sensitive values so diffs stay readable and CI pipelines can still template against them. Team members reviewing pull requests see the manifest layout without needing access to production secrets, which limits credential exposure even within the team. A reviewer can verify that the correct ConfigMap keys exist, that environment variables reference the right secret names, and that the pod spec is structured properly. No reviewer ever sees an actual password or API key. The .env template is your local development companion: fill in the real values, keep it out of Git, and point your local tooling at it.
CI/CD integration
At deploy time, your pipeline reads the .env file or pulls from a secrets manager like HashiCorp Vault, AWS Secrets Manager, or the cloud provider’s native equivalent. Each __REDACTED_ placeholder gets replaced with the real value before the manifest reaches the cluster. GitOps tooling like ArgoCD or Flux can manage this substitution through Kustomize overlays or Helm value files that reference external secrets. The key principle: the plaintext credentials should exist only in the secrets manager and in the running cluster’s memory. Version control stores only the placeholders.
If you verify artifact integrity after deployment, checking file hashes locally against published checksums confirms the deployed configuration matches what was intended. No third party sees your manifests.
Limitations of pattern-based detection
The sanitizer is a redaction tool, not a security certification. Base64-encoded values inside Kubernetes Secret .data blocks are not decoded and re-analyzed against the secret patterns because the raw base64 string does not look like a known credential format. Instead, the entire Secret .data and .stringData map is always flagged and redacted, which is the safe default but means pattern-level inspection of those specific values is skipped. Legitimate high-entropy strings such as random config IDs and internal UUIDs may appear as false positives, though the scoring threshold keeps this uncommon. Always review the findings output before committing and treat the sanitized manifest as a strong first pass rather than a guarantee.
The broader point is this: local-first sanitization and infrastructure secrets management solve fundamentally different problems. Tools like Vault, Sealed Secrets, or the External Secrets Operator eliminate credentials from manifests at the architectural level. But they require planning, operational buy-in, and migration time that most teams do not have on day one. A browser tab that catches hardcoded keys before git commit bridges the gap between “we have a leak” and “we have the proper infrastructure in place”, no deployment, no server dependency, no data ever leaving the machine. For teams architecting toward that longer-term goal, the Kubernetes security context documentation is the definitive reference for hardening container privileges without relying on blanket privileged: true flags.10
Hardest Secrets to Catch and How This Handles Them
Even with a structured output strategy in place, certain non-standard configuration patterns introduce edge cases that require closer inspection. Custom API keys and internal service-to-service credentials are the toughest category for any pattern-based scanner. They lack the standardized prefixes that make AWS keys and GitHub tokens easy to detect. The entropy filter catches most of these. A 32-character random service token will almost always exceed the 4.5 Shannon threshold regardless of its format. But a shorter 10 or 12-character alphanumeric key used internally might score just under the threshold and slip through unless its parent key name triggers the medium-severity name match.
Environment variable indirection presents a different blind spot. A container spec that sets valueFrom.configMapKeyRef to reference a ConfigMap carrying secrets will not trip any string-based detection because the manifest only holds a name reference, not the actual secret value. The tool flags what is literally present in the YAML text. It cannot follow references across resources, resolve Helm templates, or reach into the cluster’s running state. Similarly, secrets injected at runtime through init containers or sidecar injection patterns are invisible to static analysis. Service mesh setups like Istio with Vault integration use this approach heavily.
While pattern-based redaction elegantly solves the immediate risk of leaking keys to version control, it serves as a pragmatic stopgap rather than a total replacement for architectural secrets management. Until robust platforms like Vault or the External Secrets Operator are fully deployed across your pipelines, keeping this local validation check at the absolute edge of your development environment ensures your Git history remains entirely clear of production exposure. Run it before every commit. It costs nothing and catches what tired brains miss.
- 1.
Kubernetes, “Good practices for Kubernetes Secrets,” kubernetes.io, June 2025. https://kubernetes.io/docs/concepts/security/secrets-good-practices/
- 2.
Kubernetes, “Encrypting Confidential Data at Rest,” kubernetes.io, accessed June 2026. https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
- 3.
GitHub, “Secret scanning,” docs.github.com, accessed June 2026. https://docs.github.com/en/code-security/concepts/secret-security/secret-scanning
- 4.
OWASP Foundation, “Secrets Management Cheat Sheet,” github.com, accessed June 2026. https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Secrets_Management_Cheat_Sheet.md
- 5.
S. Josefsson, “The Base16, Base32, and Base64 Data Encodings,” RFC 4648, IETF, October 2006. https://www.rfc-editor.org/rfc/rfc4648
- 6.
“Entropy (information theory),” Wikipedia, accessed June 2026. https://en.wikipedia.org/wiki/Entropy_(information_theory)
- 7.
Murugiah Souppaya, John Morello, and Karen Scarfone, “Application Container Security Guide,” SP 800-190, NIST, September 2017. https://csrc.nist.gov/pubs/sp/800/190/final
- 8.
HashiCorp, “State,” developer.hashicorp.com, accessed June 2026. https://developer.hashicorp.com/terraform/language/state
- 9.
Helm, “Values Files,” github.com, accessed June 2026. https://github.com/helm/helm-www/blob/main/docs/chart_template_guide/values_files.mdx
- 10.
OWASP Foundation, “Kubernetes Security Cheat Sheet,” owasp.org, accessed June 2026. https://cheatsheetseries.owasp.org/cheatsheets/Kubernetes_Security_Cheat_Sheet