Skip to main content
NEW: RSAC 2026 NHI Field Report. How Non-Human Identity became cybersecurity's central axis
Back to Blog

NHI Kill Chain: Drifted Key — How a Database Password Ended Up in Jira, GitHub, and a Docker Image

A PostgreSQL master password drifted across seven platform types — from Secrets Manager to GitHub, Jenkins, Docker Hub, Jira, Confluence, and Slack. Each security tool saw its own silo. None saw the full picture.

Ben Kim
Written by
14 min read2,975 words
Share:
NHI Kill Chain: Drifted Key — How a Database Password Ended Up in Jira, GitHub, and a Docker Image

A Database Password's Journey Across Seven Platforms

Early 2025. A 400-person e-commerce company. Series B closed the previous quarter, growing fast. Separate teams for infrastructure, backend, frontend, QA, and SRE, each running their own tool stacks. Different platforms per team, different security tools per platform, different organizational owners per tool.

The company's production PostgreSQL master password is stored in AWS Secrets Manager. Access control is configured, audit logging is enabled, rotation policy is applied. The security team reviewed and approved this setup. Textbook secret management. Everything is under control.

The problem started after that.

Backend developer P was setting up a local development environment and hardcoded the PostgreSQL password into docker-compose.yml. Calling the Secrets Manager SDK for every local startup was too cumbersome. "It's just for local use." P intended to add the file to .gitignore, but another developer filed an issue complaining that local environment setup was too complex. P committed the docker-compose file to the GitHub repository so other developers could spin up their local environments quickly.

DevOps engineer C, who managed the Jenkins pipeline, injected this password as an environment variable while building a database migration automation. For debugging failed builds, C enabled an option that printed environment variables to the build log. The password appeared in plaintext in the build output.

During the Docker image build process, the password was injected via an ENV directive. When the image was pushed to Docker Hub, the password was embedded in the image layer. Even if the layer was later overwritten, the previous layer history retained the value. Docker image security scanners find CVE vulnerabilities, but a plaintext password baked into an environment variable is typically not in their detection scope.

One day, a database migration failed. Developer J pasted the full connection string into a Jira ticket for debugging context: postgresql://admin:P@ssw0rd_Pr0d!@prod-db.internal:5432/ecommerce. Fifteen people across the infrastructure, backend, and QA teams had access to the ticket.

A new developer onboarding guide was created in Confluence. The "Local DB Setup" section included the password. The author's intention was good -- help new hires start developing quickly.

Finally, a new developer asked a senior colleague on Slack: "I can't connect to the DB." The senior sent the password via DM. Problem solved in ten seconds.

One production database password now exists across seven platforms: AWS Secrets Manager, GitHub, Jenkins, Docker Hub, Jira, Confluence, and Slack. Each copy was made for a rational reason. Not a single act was malicious. But the result is catastrophic.

The GitHub security scanner sees the repo. "One secret detected in the repository." It does not know that this same secret also lives in the Jenkins build log, the Docker Hub image, the Jira ticket, the Confluence page, and a Slack DM. The Slack DLP tool sees messages only. The Docker security scanner sees images only. Jira and Confluence have no secret scanning at all in most organizations.

Each tool reports "no issues" or "one finding" within its domain. But the complete picture -- that the same password exists across seven platform types -- is visible to no tool, no person, and no process.

Why This Key Is Dangerous

A Drifted Key is a credential that has moved beyond its authorized platform type boundary into heterogeneous platforms. The name captures the essential behavior: drift is unintentional. Nobody plans credential drift. It happens naturally within the flow of everyday work.

Credential drift occurs for three structural reasons.

First, developers need to solve problems quickly. "Setting up the Secrets Manager SDK call takes 30 minutes. Pasting the password directly takes 3 seconds." The gap between 30 minutes and 3 seconds creates drift. Each individual copy is a rational decision. The problem is that seven rational decisions in sequence completely dismantle security controls.

Second, secret management policies are not unified across platforms. GitHub has secret scanning. Slack has DLP. Docker has image scanners. But no system knows that the same password exists across all three. Each platform operates independently, with independent security policies. Cross-platform correlation analysis does not exist.

Third, organizational structure creates silos. GitHub is managed by the development team. Jenkins is managed by the DevOps team. Jira and Confluence are managed by the PM team or IT team. Slack is managed by the IT team. Docker Hub is managed by the infrastructure team. When a single credential crosses five teams' jurisdictions, who is responsible? There is no answer. So nobody takes responsibility.

The distinction from Over-shared Key is important to understand clearly. An Over-shared Key is a credential excessively shared within the same platform type. For example, one Slack bot token reused across ten repositories, or one AWS key shared across five services. The copies proliferate within the same type -- repos, services, environments. A single platform's access control tools can detect this pattern.

A Drifted Key is fundamentally different. The credential crosses platform type boundaries. From a code repository to CI/CD. From CI/CD to a container image. From the image to an issue tracker. From the tracker to a documentation platform. From documentation to a messaging app. Each movement crosses a platform type boundary. And with each boundary crossing, visibility disappears.

If an Over-shared Key is "too many copies of a key in one room," a Drifted Key is "a key wandering through the entire building, left in random rooms on every floor." The latter is far harder to detect and creates a far wider attack surface.

Kill Chain -- How a Drifted Key Becomes an Active Breach

The Drifted Key kill chain progresses through five stages. The critical insight is that an attacker only needs to breach the weakest of the seven platforms.

Stage 1: Authorized Origin. The credential is stored in its legitimate location. In this scenario, the production PostgreSQL master password resides in AWS Secrets Manager. Access controls are configured, audit logging is active, and a rotation policy is in place. The security team considers this credential "under control." That assessment is accurate -- at this point.

Stage 2: Cross-Platform Drift. For reasons of development convenience, debugging, onboarding, and incident response, the credential is copied beyond its authorized platform type into heterogeneous platforms. Each copy has a rational justification. Hardcoding it in docker-compose is "to get local development running quickly." Injecting it into Jenkins is "to automate database migrations." Pasting it into a Jira ticket is "to share debugging context." Each reason is valid. But after six repetitions, a single password exists across seven platforms, far outside the boundaries that security policy was designed to protect.

Stage 3: Visibility Fragmentation. Each platform's security tooling monitors only its own domain. GitHub's secret scanning reports secrets found in repositories. Jenkins security configurations check build environment variables. Docker scanners report image vulnerabilities. But no system connects the fact that all three tools detected the same password. More critically, most organizations have no secret scanning at all for Jira and Confluence. Even where Slack DLP exists, it rarely covers DMs. At least three of the seven platforms are complete blind spots.

Stage 4: Weakest Platform Breach. The attacker targets the platform with the weakest security posture among the seven. If the Docker Hub image was pushed as public, anyone can pull the image and extract environment variables from the layer history. If the Jira ticket has external partner access, a compromised partner account exposes the password. Slack DMs are one phishing attack away from exposure. The security of all seven platforms is determined by the security level of the weakest one. This is the core risk of drift.

Stage 5: Cross-Platform Impact. With the leaked password, the attacker gains direct access to the production database. But the damage does not stop at the database. Knowing the same password exists in Jenkins environment variables, the attacker explores CI/CD pipeline manipulation possibilities. Additional credentials may be extracted from other environment variables in the Docker image. The connection string recorded in the Jira ticket reveals internal network architecture. The attack surface created by a single Drifted Key is categorically different from a single-platform credential exposure.

Why Traditional Security Tools Miss It

The reason Drifted Keys pass through existing security frameworks is straightforward: existing security tools are designed per platform, and drift is a cross-platform phenomenon.

Platform-specific security tool silos. GitHub Advanced Security provides robust secret scanning -- but it cannot know whether the same secret also exists in Jira. Snyk Container detects Docker image vulnerabilities, but a plaintext password baked into an image layer's environment variable is often not within its default scanning scope. Slack Enterprise DLP can detect sensitive information in messages, but organizations that enable DM scanning are a minority. Each tool excels within its domain. The problem is that drift occurs between domains.

Absence of cross-platform correlation analysis. Even if a SIEM aggregates logs from all platforms, the correlation analysis that "secret X detected in GitHub also exists in Jira ticket Y and is embedded in Docker Hub image Z's layer" is not something most SIEMs provide. Such analysis would require comparing the actual secret values found across platforms -- but most security tools hash or mask secret values in storage. Comparison is structurally impossible.

The specific challenge of secrets in Docker images. Docker images are layer-based. docker history reveals the commands of every layer. If a password is injected via ENV DB_PASSWORD=P@ssw0rd_Pr0d!, even overwriting it later with ENV DB_PASSWORD= leaves the original value in the previous layer. Multi-stage builds solve this, but a significant number of organizations still use legacy Dockerfiles. Docker's official documentation recommends --mount=type=secret for build-time secret injection, but adoption of this recommendation in practice remains low.

Secret exposure in CI/CD build logs. Jenkins, GitHub Actions, and GitLab CI all offer secret masking capabilities. However, masking only applies to values explicitly registered as "secrets." Values injected directly into environment variables, printed by scripts via echo, or included in error messages containing connection strings are not masked. When builds fail and developers share logs for debugging, secrets drift further.

Jira and Confluence as security blind spots. Atlassian platforms do not provide secret scanning by default. Passwords recorded in plaintext in Jira tickets or Confluence pages generate no alerts. Access control is set at the project level, but in most organizations, Jira projects are open to a broad range of team members. A password pasted "for debugging context" sits indefinitely in a ticket accessible to dozens of people.

Real-World Breaches and Industry Data

Credential drift is not a theoretical risk category. It is a documented, recurring cause of real breaches.

A 2023 large-scale analysis of public images pushed to Docker Hub found secrets in approximately 8.5% of images analyzed. AWS keys, database passwords, and API tokens were embedded in plaintext in image layers. A significant portion of these secrets were credentials that had drifted from private infrastructure to Docker Hub -- passwords that should have existed only in internal systems, exposed to the entire world through public container images.

GitGuardian's 2025 State of Secrets Sprawl report found that over 90% of secrets detected in GitHub repositories were still valid five days after detection. This means that even when secrets are detected, rotation does not follow. If a secret has also drifted to other platforms, rotating it in one location likely leaves the old value intact in the remaining six locations.

The CircleCI breach in January 2023 demonstrated how CI/CD environments can become credential drift hubs. After an attacker stole a session token from a CircleCI engineer's laptop, they accessed CircleCI's production environment and exfiltrated customer secrets. Secrets stored in CI/CD systems are predominantly credentials that drifted from their original platforms. When CI/CD is compromised, every secret that drifted there is exposed simultaneously.

CSA's 2026 State of NHI Security report found that 73% of organizations operate NHI credentials across three or more cloud and SaaS platforms. However, fewer than 15% have processes to track how these credentials move and replicate across platform boundaries. Drift is universal, but the capability to detect drift is not.

The Verizon 2025 DBIR reported that credential-based attacks account for approximately 20% of all breaches analyzed. A significant portion of these involve stolen credentials that were reused or had drifted across multiple systems. When an attacker obtains a single credential, exploring where else that credential exists is a fundamental step in the attack process.

OWASP's NHI Top 10 classifies Secret Exposure as a major risk, identifying the proliferation of secrets across code, logs, configuration files, and ticket systems as a core cause. The analysis emphasizes that cross-platform sprawl -- not single-platform exposure -- is what determines the actual scale of damage.

Detection and Response Guide

Detecting and responding to credential drift requires an approach that goes beyond individual platform scanning.

Build a cross-platform secret inventory. Scan for secrets across every platform the organization uses -- code repositories, CI/CD systems, container registries, issue trackers, documentation platforms, and messaging tools -- and register findings in a unified inventory. The critical capability is identifying whether the same secret exists across multiple platforms. The goal is not "one finding in GitHub" but "this secret exists across seven platforms, and here is the complete map." For a comprehensive approach to secret detection, see Secret Detection: Complete Guide for 2026.

Harden Docker build secret management. Do not pass secrets via ENV or ARG. Docker BuildKit's --mount=type=secret ensures secrets are not recorded in image layers. Use multi-stage builds to prevent build-time secrets from persisting in the final image. Audit previously pushed images for embedded secrets -- if found, delete the images and rotate the credentials simultaneously.

Audit CI/CD log masking. Verify that Jenkins' Mask Passwords plugin, GitHub Actions' ::add-mask::, and GitLab CI's masked variables actually cover all secrets. Values injected directly into environment variables, printed by scripts, and embedded in error messages are commonly missed by masking configurations. Review log retention policies as well -- old logs may still contain exposed secrets.

Control secret sharing in Jira, Confluence, and Slack. Technical and cultural controls must work in parallel. Atlassian Guard's (formerly Atlassian Access) DLP capabilities can detect secret patterns in Jira and Confluence. Slack Enterprise Grid's DLP can scan all messages including DMs. But most organizations have not activated these features or are not on Enterprise plans. Where technical controls are not feasible, at minimum establish and enforce explicit policies: "Never share passwords in tickets or DMs. Use Secrets Manager links for secret sharing."

When rotating a secret, update every drift point simultaneously. When rotating a secret, changing the value in Secrets Manager alone is insufficient. The previous value must be removed or invalidated across every drifted location: docker-compose files, Jenkins environment variables, Docker images, Jira tickets, Confluence pages, and Slack messages. If even one copy remains, drift recurs. This is exactly why a cross-platform inventory is essential.

When a breach is suspected, assess impact across the entire drift map. When a drifted credential is compromised, every platform where that credential existed is within the blast radius. Even if the leak originated from Docker Hub, the same password provides access to PostgreSQL, Jenkins pipelines, and internal documentation. Every drift point must be investigated. For implementation details on building detection capabilities, see Git Secret Scanning: Complete Implementation Guide.

How Cremit Argus Detects Drifted Keys

The core challenges that allow Drifted Keys to persist -- platform-level silos, absence of cross-platform visibility, inability to trace drift paths -- are precisely what Cremit Argus was built to solve.

Argus performs unified scanning across code repositories, CI/CD pipelines, container registries, issue trackers, documentation platforms, and messaging tools. The decisive difference from individual platform tools is that Argus correlates discovered secrets across platforms. It automatically verifies whether a secret value found in GitHub also exists in a Jira ticket, a Docker image, and a Slack message. The result is not "one finding in GitHub" but "this secret exists across seven platforms, and the drift path is Secrets Manager -> docker-compose -> Jenkins -> Docker Hub -> Jira -> Confluence -> Slack DM" -- the complete picture.

Argus visualizes credential drift paths. It maps where a credential was originally authorized to reside, what route it took, and how far it has spread. Security teams can immediately make two assessments from this map: first, which secrets have drifted the widest (prioritization); second, which platforms serve as drift hubs (structural issues). This enables not just individual secret remediation but improvement of the organization's entire credential management posture.

During rotation, Argus's cross-platform inventory ensures completeness. When rotating a secret, it immediately provides the full list of every platform where that secret exists, ensuring that not a single drift point is missed.

See how Argus detects cross-platform credential drift at cremit.io.

NHI Kill Chain Series Overview

This post is the sixth installment in the NHI Kill Chain series. Across nine posts, we analyze the most dangerous types of NHI credentials hiding inside organizations, each representing a distinct -- and interconnected -- risk.

A key exposed in a public repository, if left unrotated, becomes an Aged Key. A departed employee's key, if never revoked, becomes a Ghost Key. A key that drifts across multiple platforms becomes a Drifted Key. Understanding how one credential management failure cascades into another risk category is the central purpose of this series.

  1. Public Key -- What Happens 4 Minutes After a .env Hits GitHub
  2. Ghost Key -- The Departed Developer Whose AWS Key Still Clocks In Every Morning
  3. Shadow Key -- Quietly Hardcoded Right Next to the Secrets Manager
  4. Aged Key -- The Skeleton Key That Held Production Together for 3 Years
  5. Over-shared Key -- What Happens When 10 People Share a Single Slack Bot Token
  6. Zombie Key -- Deleting It from Code Doesn't Mean It's Dead
  7. Drifted Key -- How a Database Password Ended Up in Jira, GitHub, and a Docker Image (current post)
  8. Unattributed Key -- The Key Nobody Knows Who Created (coming soon)
  9. Compound Risk -- When Five Risk Types Converge on a Single Key (coming soon)

Previous post: [NHI Kill Chain: Zombie Key -- Deleting It from Code Doesn't Mean It's Dead](/blog/nhi-kill-chain-zombie-key)

Next post: NHI Kill Chain: Unattributed Key -- The Key Nobody Knows Who Created

Cremit is an NHI security company. [Learn more at cremit.io](https://cremit.io)

Share it with your networkLinkedInX

Enjoyed this post?

Share it with your network

Share:
Newsletter

Get the next one in your inbox

Monthly NHI research brief from the Cremit team. One email, high signal.

We never share your email. Unsubscribe in one click.

NHI Kill Chain: Drifted Key — How a Database Password Ended Up in Jira, GitHub, and a Docker Image | Cremit