Back

CICD-SEC-6: Insufficient Credential Hygiene - Overview

What is Insufficient Credential Hygiene?

Insufficient Credential Hygiene (CICD-SEC-6 in the OWASP Top 10 CI/CD Security Risks) is the failure to properly handle the large volume of secrets that flow through a modern engineering pipeline. Every build, test, deploy, and release step needs credentials—cloud keys, registry tokens, database passwords, signing keys, SaaS API tokens—and each of those secrets is created, stored, passed between steps, printed, cached, and eventually (ideally) rotated. When any link in that chain is careless, a secret leaks, lingers, or is over-privileged, and an attacker who obtains it inherits whatever access it grants.

It is important to see this as a hygiene problem rather than a single bug. The pipeline is not one place where secrets live; it is a river that secrets travel through. A key hardcoded in a repository, echoed into a build log, baked into a container image, stored as a long-lived static cloud key, and shared across a dozen pipelines is the same underlying failure viewed from five different vantage points: nobody owns the full lifecycle of the secret, so it accumulates exposure at every stage.

Core Concept

Good Credential Hygiene:
  Storage      -> secrets in a manager / CI secret store, never in code or Git
  Cloud access -> short-lived OIDC-federated tokens, minted per job
  Scope        -> one secret per environment/pipeline, least privilege
  Rotation     -> rotated on a schedule AND immediately on any exposure
  Logs         -> masked/redacted, echoing secrets forbidden and detected
  Detection    -> repos + history scanned in CI and pre-commit (gitleaks)
  Humans        -> no standing human access to production secrets

Insufficient Hygiene:
  Storage      -> API keys hardcoded in pipeline YAML, Dockerfiles, code
  Cloud access -> long-lived static access keys with broad, unrotated scope
  Scope        -> one god-token shared by every pipeline and repo
  Rotation     -> secret unchanged for years; never rotated after a leak
  Logs         -> secrets printed by debug output and set -x, kept forever
  Detection    -> no scanning; leaks discovered by the attacker first
  Humans        -> every engineer can read prod secrets from the console

Why It's Critical for CI/CD

CI/CD systems concentrate several conditions that make credential mishandling especially damaging:

Why Does This Matter?

Business Impact

Technical Impact

Technical Context

Where Secrets Leak in CI/CD

1. Hardcoded in Code, Pipeline Definitions, and Dockerfiles

# .github/workflows/deploy.yml  (INSECURE)
- name: Deploy
  run: aws s3 sync ./dist s3://prod-assets
  env:
    AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
    AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

# Dockerfile  (INSECURE)
ARG NPM_TOKEN=npm_9f8a...redacted...   # baked into an image layer forever

Risk: The secret is now in version control and/or image history—copied to every clone, fork, and pull of the image.

2. Committed to Git (and Left in History)

$ git log -p --all | grep -i "secret\|api_key\|password"
# Removing the file in a later commit does NOT remove it from history:
$ git show <old-commit>:config/prod.env   # secret still fully recoverable

Risk: Deleting a leaked file "fixes" only the tip of the branch. The value lives on in history until it is both purged and rotated.

3. Long-Lived Static Credentials with Broad Scope

Static AWS access key, created 3 years ago
  -> policy: AdministratorAccess ("*":"*")
  -> used by 14 pipelines across 3 teams
  -> never rotated, no expiry

Risk: One leak equals full account compromise, and the key works indefinitely with nothing to force it to expire.

4. Printed to Build Logs / Exposed via Debug

$ set -x                       # shell tracing prints every expanded variable
$ curl -H "Authorization: Bearer $API_TOKEN" https://api.example.com
+ curl -H 'Authorization: Bearer eyJhbGci...' https://api.example.com
$ echo "DEBUG token=$API_TOKEN"   # explicit echo defeats masking

Risk: The value is captured in logs that are retained, forwarded to aggregators, and often world-readable within the org.

5. Readable by Any Job Step / Over-Shared

All secrets injected as environment variables for the whole job
  -> a compromised test dependency in step 2 reads the DEPLOY_KEY
     that only step 5 actually needed

Risk: Secrets scoped to the entire job or organisation are readable by unrelated (and potentially malicious) steps and pipelines.

6. Baked into Artifacts and Images

$ docker history myapp:latest        # layers reveal build-time ARGs
$ tar tf build-artifact.tgz | grep -i env
config/.env.production               # secret shipped inside the artifact

Risk: Credentials embedded at build time travel with the artifact to registries, developer laptops, and untrusted environments.

The Many Places a CI/CD Secret Lives

LocationTypical Hygiene FailureConsequence
Source code / configHardcoded key or passwordLeaks to every clone and fork
Git historyRemoved from HEAD but not purgedFully recoverable indefinitely
Pipeline YAMLPlaintext token in the workflow fileReadable by anyone with repo access
Build logsEchoed / traced secret, masking bypassedRetained and forwarded downstream
Environment variablesAll secrets exposed to every stepRead by unrelated / malicious steps
Artifacts & imagesSecret baked into a layer or bundleTravels wherever the artifact goes
Cloud IAMLong-lived, broad, unrotated static keyDurable full-account compromise on leak

Real-World Impact

Case Study 1: Cloud Keys Committed to Public Repositories (ongoing class)

Failure:

Impact:

Root Cause: Static credentials placed directly in code with no secret scanning to catch them and no short-lived alternative in use. Cloud providers now run their own secret-scanning partnerships and can automatically quarantine exposed keys precisely because this class is so common.

Case Study 2: Secrets Recoverable from Git History (class)

Failure:

Impact:

Root Cause: Treating a source-tree deletion as remediation. The durable lesson of this class is that a leaked secret must be rotated, not merely deleted—history rewriting reduces exposure but rotation is what actually invalidates the credential.

Case Study 3: Secrets Leaked Through Build Logs (class)

Failure:

Impact:

Root Cause: Masking only redacts the exact known value in the exact expected form; tracing and transformations defeat it. The lesson is to prevent secrets reaching logs at all, not to rely solely on redaction.

Prevalence and Detection

Leaked and mishandled credentials are consistently among the most common and most quickly exploited findings in CI/CD and cloud security. Secret-scanning tools flag exposed credentials across a large fraction of active repositories, and automated harvesting means the window between exposure and abuse is frequently minutes, not days.

Rather than cite precise counts (which vary by source and year), the defensible picture is:

Note: exact percentages and leak counts differ between reports and years. Treat any single figure as illustrative; the durable takeaway is that secrets leak constantly, are found fast, and are reused faster.

Common Misunderstandings

Myth 1: "The repo is private, so a hardcoded secret is fine"

Reality: Private repos are cloned to laptops, forked, mirrored, and made public by accident; contributors leave; access is broad. A secret in code is a secret shared with everyone who ever touches the repo. Keep secrets out of code regardless of visibility.

Myth 2: "I deleted the secret, so it's gone"

Reality: Deleting a file removes it from the current tree, not from Git history, forks, caches, or logs. The only reliable remediation for an exposed secret is to rotate it; purging history is a cleanup step, not the fix.

Myth 3: "The CI platform masks secrets in logs, so echoing is safe"

Reality: Masking matches the exact known value. Shell tracing, base64/JSON encoding, partial printing, and error messages routinely emit forms the masker never sees. Prevent secrets from reaching logs; don't rely on redaction to catch them.

Myth 4: "One powerful token for all pipelines is simpler"

Reality: A shared, broadly scoped token means one leak compromises everything and makes rotation terrifying (it breaks every pipeline at once). Scope secrets narrowly per environment and job so a leak is contained and rotation is routine.

Myth 5: "Static keys are fine as long as they're stored in the secret manager"

Reality: A secret manager protects storage, but a long-lived static key still leaks through logs, artifacts, and reuse. Prefer short-lived, OIDC-federated credentials that expire in minutes, so a leaked token is useless almost immediately.

Myth 6: "We'd notice if a secret leaked"

Reality: Without automated secret scanning in CI and pre-commit, leaks are usually discovered by the attacker first. Detection has to be automated and continuous—humans do not spot a key buried in a diff or a log.

How Insufficient Credential Hygiene Differs from Related CI/CD Risks

AspectInsufficient Credential Hygiene (CICD-SEC-6)Poisoned Pipeline Execution (CICD-SEC-4)Insufficient PBAC (CICD-SEC-5)
Root causeSecrets mishandled across their lifecycleUntrusted code runs in the pipelinePipeline identities over-permissioned
What the attacker getsA reusable credentialExecution inside the pipelineExcess access from a legitimate identity
Typical fixShort-lived secrets, scanning, rotationIsolate/untrust external inputLeast-privilege pipeline roles
DetectionSecret scanning, log/leak monitoringPipeline change review, sandboxingAccess review, permission audit

Key Takeaways

  1. Secrets have a lifecycle, not a location—creation, storage, transit, use, logging, and rotation all need hygiene, not just where the secret is "kept."
  2. A leaked credential is often the whole attack—pipeline secrets are trusted by production, so reuse needs no further exploit.
  3. Deletion is not rotation—an exposed secret is compromised until it is rotated, regardless of history cleanup.
  4. Short-lived beats well-stored—OIDC-federated, minutes-long credentials shrink the value of any leak to almost nothing.
  5. Detection must be automated—scan repos, history, and logs continuously; attackers scan yours already.

How to Identify if You're Vulnerable

Ask these questions about your pipelines:

If you answered "yes" to the risky items or "no"/"not sure" to the controls, you likely have exploitable credential-hygiene gaps today.

Next Steps