delivered for clients · names withheldmodernization Privileged access

Secrets in code, pipelines and config files to HashiCorp Vault

Cohash finds secrets in repositories, CI variables, container images and config files and moves them into HashiCorp Vault. Workloads log in with Kubernetes, cloud IAM or pipeline OIDC, and static tokens go away. Database and cloud credentials become dynamic. Secret scanning with push protection stops new leaks. We rotate every exposed secret as well as moving it, because anything that sat in Git history has to be treated as compromised.

  1. 01Discovery
  2. 02Vault foundation
  3. 03Move and rotate by application
  4. 04Dynamic credentials
  5. 05Prevention
case-study / hardcoded-secrets-to-vault delivered
beforeSecrets in code, CI variables and config files afterHashiCorp Vault 2.x
01 · CODE AND WORKLOADS 02 · SECRETS PLATFORM 03 · TARGETS Git repositories: push protection · pre-commit scan Git repositories push protection ·pre-commit scan CI pipelines: OIDC token per run CI pipelines OIDC token per run Kubernetes workloads: service account tokens Kubernetes workloads service account tokens HashiCorp Vault 2.x: auto-unseal · audit devices HashiCorp Vault 2.x auto-unseal · auditdevices Vault policies in Terraform: reviewed by pull request Vault policies inTerraform reviewed by pullrequest Databases: dynamic per-workload logins Databases dynamic per-workloadlogins Cloud accounts: short-lived credentials Cloud accounts short-livedcredentials Third-party APIs: rotated keys in Vault Third-party APIs rotated keys in Vault
case file

The story

Told without the client's name or anything that could identify them.

what happened

A financial services firm's platform team kept finding the same database password in new repositories, and its CI pipelines held long-lived cloud keys as project variables. Nobody could say which services would break if a key was rotated, so keys stayed as they were. We scanned repositories with full history, CI variables, container images and config stores, grouped the findings by credential and traced each one's users from logs. Then we built Vault on a supported 2.x release with Kubernetes, cloud IAM and pipeline OIDC logins. Secrets moved and were rotated application by application, databases and cloud accounts switched to dynamic credentials, and push protection now blocks new leaks at commit time.

why it was urgent

Secret leakage sits at number two on OWASP's 2025 Non-Human Identities Top 10. Vault 2.0 went generally available on 14 April 2026, now on IBM's support cycle, and 2.2.0 followed on 15 October 2026. On the GitHub side, Secret Protection, which includes push protection, has been a separate product since 1 April 2025.

problem statement
  • openSecret scanning keeps finding the same database password in new repositories.
  • recurringCI pipelines hold long-lived cloud keys as project variables.
  • blockedThe apps still read one static password out of the same config file they've been using for years.
  • openNobody knows which services break if a given API key is rotated.
architecture

The estate, before and after

before
before

Before: static secrets spread across code, CI and config

Passwords and keys lived in repositories, CI variables and config files, and several services shared the same credential. Nobody rotated them because nobody knew who else depended on each one.

Before: static secrets spread across code, CI and config Passwords and keys lived in repositories, CI variables and config files, and several services shared the same credential. Nobody rotated them because nobody knew who else depended on each one. 01 · WHERE SECRETS LIVED 02 · WORKLOADS 03 · TARGETS hardcoded password static secret long-lived key shared login static keys shared API key Git repositories passwords in code andhistory CI project variables long-lived cloud keys Config files and images static passwords Applications and services shared credentials Deploy pipelines Databases one shared password Cloud accounts static access keys Third-party APIs one key, many services
Read the diagram as text
  1. Git repositories → Applications and services: hardcoded password
  2. Config files and images → Applications and services: static secret
  3. CI project variables → Deploy pipelines: long-lived key
  4. Applications and services → Databases: shared login
  5. Deploy pipelines → Cloud accounts: static keys
  6. Applications and services → Third-party APIs: shared API key
after
after

After: workloads get credentials from HashiCorp Vault at run time

Each workload authenticates with its platform identity and gets a short-lived credential from Vault. We keep Vault policies in Terraform, and push protection keeps new secrets out of Git.

After: workloads get credentials from HashiCorp Vault at run time Each workload authenticates with its platform identity and gets a short-lived credential from Vault. We keep Vault policies in Terraform, and push protection keeps new secrets out of Git. 01 · CODE AND WORKLOADS 02 · SECRETS PLATFORM 03 · TARGETS clean commits JWT/OIDC login Kubernetes auth policies dynamic credentials short-lived credentials rotated API key Git repositories push protection · pre-commitscan CI pipelines OIDC token per run Kubernetes workloads service account tokens HashiCorp Vault 2.x auto-unseal · auditdevices Vault policies inTerraform reviewed by pullrequest Databases dynamic per-workload logins Cloud accounts short-lived credentials Third-party APIs rotated keys in Vault
Read the diagram as text
  1. Git repositories → CI pipelines: clean commits
  2. CI pipelines → HashiCorp Vault 2.x: JWT/OIDC login
  3. Kubernetes workloads → HashiCorp Vault 2.x: Kubernetes auth
  4. Vault policies in Terraform → HashiCorp Vault 2.x: policies
  5. HashiCorp Vault 2.x → Databases: dynamic credentials
  6. HashiCorp Vault 2.x → Cloud accounts: short-lived credentials
  7. HashiCorp Vault 2.x → Third-party APIs: rotated API key
results

What the client got

What changed for the client once the work was done. Described, not scored: we don't publish client figures.

  1. result 01

    Every secret has an owner and a known blast radius

    We grouped the inventory by credential, not file. Every entry names an owner and the systems that secret can open.

  2. result 02

    Copies left in Git history no longer work

    We rotated each secret as it moved into Vault. That also proved nothing was still reading the old value out of a config file.

  3. result 03

    Workloads log in with platform identity

    Kubernetes service accounts, cloud IAM roles and pipeline OIDC tokens authenticate to Vault, so no static Vault token sits in a CI variable.

  4. result 04

    Databases and cloud accounts issue short-lived logins

    We switched on the database and cloud secrets engines where the target supports them. Each workload now has its own credential, and it expires on its own.

  5. result 05

    New leaks are stopped at push

    We turned on push protection and pre-commit scanning to block secrets before they land, and wrote a runbook naming who rotates a leaked secret and how quickly.

what can go wrong

Risks we plan for

  1. Moving without rotating

    Copying a secret into Vault doesn't help if the old value still works from Git history. We rotate every one we move.

  2. Shared credentials with unknown users

    One API key often serves five services. Rotate it and four you didn't know about break, so we trace usage in logs first.

  3. Vault becomes the outage

    If every service depends on Vault, Vault needs DR replication or a tested snapshot restore. That work is part of the plan, not an afterthought.

  4. Static tokens to reach Vault

    Replacing a password with a long-lived Vault token in the same CI variable moves the problem. Workloads use platform identity to log in.

ai in this move

Where AI helps, and where it needs guardrails

Vault 2.1.0 made Agentic IAM generally available as an Enterprise feature, issuing short-lived, scoped credentials to AI agents. We also treat coding assistants and MCP clients as a new leak path: MCP server configs often hold API keys in plain JSON, and assistants paste secrets into prompts and commits. Agents get credentials from Vault at run time for one task, and secret scanning covers agent-written code like any other.

forward deployed engineers →
you keep

What you're left with

We write these for your setup, and they're working documents. Your team should be able to keep things running from them long after we've gone.

  • inventory01

    Secret inventory grouped by credential, owner and blast radius

    yours to keep
  • code02

    Vault auth methods and policies as Terraform, reviewed by pull request

    yours to keep
  • document03

    Per-application migration and rotation record

    yours to keep
  • document04

    Dynamic credential setup for databases and cloud accounts

    yours to keep
  • runbook05

    Push protection and leak-response runbook

    yours to keep
talent and delivery · hashicorp vault 2.x

Certified engineers, wherever you need them.

Some clients want a project team, some want a couple of engineers on theirs. Either works. Onsite, nearshore or offshore, with handovers across time zones that keep things moving.

Onsite

Engineers at your sites in the US

Nearshore

Overlapping hours with US teams

Offshore

Overnight progress on your backlog

All time zones

Coverage handed over across time zones

24-hour coverage · US Central time
OnsiteUS business hours
Nearshoreoverlapping US hours
Offshoreovernight progress
Combinedhandover, not hand-off
01Vault, a cloud secret manager or our PAM tool?

Depends on your clouds and what you already pay for. Vault is strongest across multiple clouds and on-premises, and for dynamic credentials. On one cloud, the native secret store may be simpler. Human admin access often sits better in a PAM tool like CyberArk. Plenty of companies use two of these, with a clear boundary.

02Do we need Vault Enterprise?

Only if you need namespaces, replication or Agentic IAM. Community Edition covers a lot of migrations, so we work out what you really need before anyone talks licences.

03How long does this take?

It depends on the number of applications, how many share credentials and how much code needs changing to read from Vault. Discovery gives a count of distinct secrets and owners, and the plan follows from that.

04What about secrets already in Git history?

Rewriting Git history is optional, and it's disruptive. Rotation isn't optional. Once a secret is rotated, the old value in history opens nothing.

sources 5 sources linked last checked 2026-10-20 content fingerprint c25d9e85
  1. 01InfoQ: Vault 2.0 under IBM (24 Apr 2026)infoq.com ↗
  2. 02HashiCorp: Vault release notes (2.1.0 and 2.2.0)developer.hashicorp.com ↗
  3. 03GitHub changelog: Introducing GitHub Secret Protection and GitHub Code Security (4 Mar 2025)github.blog ↗
  4. 04OWASP: Non-Human Identities Top 10 for 2025owasp.org ↗
  5. 05HashiCorp Developer: Vault database secrets enginedeveloper.hashicorp.com ↗
Reviewed by the Cohash team Product names are trademarks of their owners. how we handle facts and data →
next step

Planning this move?

A 30-minute working session with a senior engineer. No slides.

useful to bring
  • The platform and the version you're on
  • Where you need to get to, and by when
  • What's custom: rules, plugins, integrations
  • Any audit finding or deadline driving it