DevSecOps Guides

DevSecOps Guides

Secret Management Like a Ninja: A Tale of Compromise, Recovery, and Mastery

This article tells the story of how secrets fail, how attackers exploit them, and how defenders can build impenetrable secret management practices; all with the precision and discipline of a ninja.

Reza's avatar
Reza
Nov 14, 2025
∙ Paid

It was 02:17 AM when the on-call pager emitted its piercing wail. The payments processing service had begun rejecting all authentication requests to the third-party payment gateway. The error logs screamed “Invalid API Key.” Within minutes, the incident commander had the answer: a junior developer—under deadline pressure—had pasted a temporary API key directly into a Python script, committed it, and pushed the code.

The key was found in Git history. But the real damage? When the CI pipeline re-ran after the push, the build logs—which were configured to retain artifacts for 90 days in a semi-public S3 bucket—contained full output of that script. An automated credential scanner, running across public repositories and CI platforms, detected the key within 12 minutes. By the time the team woke up, the attacker had already:

  1. Used the key to make test charges against the merchant account

  2. Extracted customer payment data (PII) from the integration environment

  3. Pivoted into the staging VPC using the key’s associated IAM role

This article ensures you never face this 02:17 AM pager. We’ll walk through how the attack happened, how to detect it pre-push, how to contain it during the push, and how to respond in minutes instead of hours.


Why Secrets Fail: Insecure vs. Secure Architecture

Insecure Architecture (The Baseline Risk)

Most organizations inherit a pattern like this:

The fundamental problem: Secrets are treated like code (checked in, versioned, replicated) when they should be treated like ephemeral, least-privilege, short-lived tokens.

Secure Architecture (Principles & Practices)

A secure secret architecture follows these contrasting principles:

The result: Even if an attacker steals a secret, it expires within 15 minutes. The audit log reveals the theft immediately. The scope of damage is limited to the specific API that credential touched.


Attack Vector 1: Hardcoded Secrets in Source Code

Scenario & TTPs

The Setup: A developer creates a debugging script, hardcodes a database password and API key, and commits it to the main branch. Even after deletion and a force-push, the secret persists in:

  • Git history (discoverable via git log or raw GitHub API)

  • Cloned forks and mirrors

  • CI cache layers

  • Automated backups

Attacker Tactics:

  • Reconnaissance: Use truffleHog, gitleaks, or custom regex scanners to mine public and private repositories

  • Discovery: Search for patterns like AKIA, -----BEGIN PRIVATE KEY-----, password=, api_key=

  • Extraction: Clone repository or access via GitHub API; extract credentials from commit history

  • Exploitation: Test credential validity; use it to access target system; exfiltrate data or pivot to related systems

Mermaid Diagrams for Attack Vector 1

Flowchart LR (Attack Path):

Sequence Diagram (Timeline):

State Diagram (Secret Lifecycle):

Defense Strategy Flowchart:

Defender Strategy (Mindmap)

Multi-layered defense strategy preventing secrets from entering Git, detecting leaks post-commit, and rapid incident response when breaches occur.

Practical Implementation & Commands

Step 1: Install Pre-Commit Hooks

# Install detect-secrets and pre-commit framework
pip install detect-secrets pre-commit

# Initialize detect-secrets baseline in your repo
detect-secrets scan --baseline .secrets.baseline

# Create .pre-commit-config.yaml in repo root
cat > .pre-commit-config.yaml <<’EOF’
repos:
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
        args: [’--baseline’, ‘.secrets.baseline’]
  - repo: https://github.com/awslabs/git-secrets
    rev: v1.3.0
    hooks:
      - id: git-secrets
EOF

# Install the hook
pre-commit install

Step 2: Detect Secrets in CI

# Example GitHub Actions workflow step
- name: Scan for secrets (gitleaks)
  uses: gitleaks/gitleaks-action@v2
  with:
    source: .
    config: .gitleaks.toml
    exit-code: 1  # Fail pipeline if secrets found

Step 3: Remediate Leaked Secret (AWS Example)

# IMMEDIATE: Revoke the compromised key
aws iam update-access-key \
  --access-key-id AKIAIOSFODNN7EXAMPLE \
  --status Inactive \
  --user-name deploy-service

# IMMEDIATE: Create replacement key
NEW_KEY=$(aws iam create-access-key --user-name deploy-service)
NEW_ACCESS_KEY=$(echo $NEW_KEY | jq -r .AccessKey.AccessKeyId)
NEW_SECRET_KEY=$(echo $NEW_KEY | jq -r .AccessKey.SecretAccessKey)

# UPDATE: Store new key in secret manager
aws secretsmanager create-secret \
  --name prod/deploy-service/aws-creds \
  --secret-string “{\”access_key\”:\”$NEW_ACCESS_KEY\”,\”secret_key\”:\”$NEW_SECRET_KEY\”}”

# PURGE: Remove secret from git history
pip install git-filter-repo
git filter-repo --invert-paths --path ‘sensitive-script.py’
git push --force
Attack Vector 1: Hardcoded Secrets in Git History

Attack Flow: Developer accidentally commits API keys/passwords → Git stores in history forever → Attacker scans repos with gitleaks/truffleHog → Finds credentials in commit diffs → Uses keys to access APIs, databases, cloud accounts. Even after deletion, secrets persist in .git objects, forks, and CI caches. Impact: Full compromise of associated resources, lateral movement via IAM roles, data exfiltration.


Attack Vector 2: CI/CD Pipeline Log Leakage

Scenario & TTPs

Keep reading with a 7-day free trial

Subscribe to DevSecOps Guides to keep reading this post and get 7 days of free access to the full post archives.

Already a paid subscriber? Sign in
© 2025 Reza
Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for great culture