writing-skills
writing-skills
Use when creating new skills, editing existing skills, or verifying skills work before deployment
security-secrets-managementUse this skill when asked about secrets management, secret scanning, GitLeaks, truffleHog, ggshield, Vault, credential rotation, .env files, environment variables, secrets detection, or secrets storage. This skill enforces: pre-commit secret scanning with GitLeaks/truffleHog/ggshield, centralized secret storage with Vault/AWS Secrets Manager/GCP Secret Mana…
Independent GitHub snapshot · Automated classification · Original documentation governs
Design a secrets management strategy covering detection (GitLeaks, truffleHog, ggshield), centralized storage (Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault), automated rotation, Kubernetes External Secrets integration, and developer workflow prevention.
Exact user phrases: "secrets management", "secret scanning", "GitLeaks", "truffleHog", "ggshield", "vault", "credential rotation", ".env", "environment variables", "secret detection", "secret storage", "HashiCorp Vault", "AWS Secrets Manager", "GCP Secret Manager", "secret rotation", "pre-commit secret", "credential leak", "hardcoded secret", "External Secrets", "secret audit".
Before activating, verify:
Secrets management strategy as YAML configs and workflow documentation.
# Secret detection config (.gitleaks.toml)
# Pre-commit hook config
# Storage namespace layout
# Rotation policy
# ExternalSecret template
No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.
250 lines of configuration.
What is the primary infrastructure platform?
├── Multi-cloud or on-premises
│ └── HashiCorp Vault (dynamic secrets, PKI, multi-datacenter replication)
├── AWS-only
│ └── AWS Secrets Manager (RDS rotation, cross-account, Lambda integration)
├── GCP-only
│ └── GCP Secret Manager (IAM, multi-region replication, version management)
└── Azure-only
└── Azure Key Vault (RBAC, soft-delete, managed HSM tier)
Is Kubernetes in use?
├── Yes → External Secrets Operator + any of the above providers
├── No → Direct SDK integration per application
└── Both → Vault CSI Provider + External Secrets for K8s workloads
What is the compliance requirement?
├── SOC 2 → Audit logging, rotation, access controls
├── PCI DSS → HSMs, network isolation, key hierarchy
├── HIPAA → BAA with provider, audit trails, minimum necessary access
└── FedRAMP → FIPS 140-2 validated modules, GovCloud
Where should secrets be detected?
├── Pre-commit (fastest feedback, developer in flow)
│ ├── GitLeaks: custom regex rules, ~100ms per commit
│ ├── ggshield: 300+ detectors, ~200ms per commit
│ └── Order: GitLeaks → ggshield (fail-fast on regex)
├── Pre-push (catches what pre-commit misses)
│ ├── truffleHog verified: checks against live APIs, ~30s
│ └── Block push on verified secret
├── CI (branch protection, PR gates)
│ ├── Full scan on PR to main
│ ├── Diff scan only (faster, focused)
│ └── Block merge on HIGH/CRITICAL findings
└── Scheduled / periodic
├── Nightly full repo scan
├── Weekly scan of all repos in organization
└── Monthly scan of all repos + S3 buckets + GCS buckets + Slack history
GitLeaks: gitleaks detect --source . --config .gitleaks.toml.
Uses custom rules for project-specific patterns.
Target: internal tokens, JWTs, connection strings, cloud keys.
truffleHog: trufflehog git file://. --only-verified --fail.
Secondary deep scan verifying against live services.
Correlates with AWS STS, GitHub API, Slack API.
ggshield (GitGuardian): ggsecret scan pre-commit.
Covers 300+ detector types from 200+ services.
Higher SaaS API key coverage than GitLeaks alone.
Hook order: GitLeaks first (fast regex), ggshield second
(broad coverage), truffleHog last (verified deep scan).
Block commit if any tool detects a secret.
Allowlist known test credentials with path and regex rules.
Use SKIP=<hook> only with documented emergency reason.
Full history scan on push to main:
gitleaks detect --source . --verbose.
PR diff scan for new secrets:
gitleaks detect --source . --log-opts="..origin/main".
TruffleHog verified mode checks live services. AWS keys against STS.GetCallerIdentity. GitHub tokens against GitHub API. Slack tokens against Slack API.
CI gates:
Output: SARIF for GitHub Code Scanning integration. Verified secrets → PagerDuty or Slack urgent. Potential secrets → email digest to security team. Block PR merge on verified secret detection. Nightly full history scan for historical leaks.
Triage each flagged secret in CI report. Classify as true positive or false positive. Document evidence for classification.
Allowlist in .gitleaks.toml:
(test/fixtures/), (vendor/)Document rationale for every false positive. Example: "test token in fixture file", "example in docs".
Quarterly audit of allowlist — remove stale entries. Improve regex rules to reduce FP rate over time. Target: less than 5% FP for GitLeaks. Target: less than 10% FP for truffleHog.
HashiCorp Vault: multi-cloud or on-premises.
Dynamic secrets, PKI engine, transit engine.
Auth: Kubernetes (service account), AppRole (machine), OIDC (human).
Structure: secret/data/<env>/<service>/<key>.
AWS Secrets Manager: AWS-native storage. Automatic rotation with Lambda functions. Cross-account access via resource policy. Supports RDS, Redshift, DocumentDB, custom.
GCP Secret Manager: GCP-native storage. IAM-based access, multi-region replication. Version management with auto-cleanup.
Azure Key Vault: Azure-native storage. Soft-delete protection, RBAC integration.
Kubernetes: External Secrets Operator. Syncs from any provider to K8s secrets. Automatic refresh on rotation. Supports AWS, GCP, Azure, Vault, 20+ providers.
Rotation intervals:
Automation strategies: Secrets Manager: Lambda-based auto rotation for RDS. Vault dynamic secrets: auto-expire with configurable TTL. Vault static secrets: cron + SIGHUP reload.
Zero-downtime rotation: Dual credentials during rotation window. Old credential valid for N hours after new deployed. Co-rotation: create new version while old stays active. Grace period: old valid for configurable hours.
Template .env.example with placeholder values.
Document each variable with description and source.
Lint rules:
no-process-env for direct accessIDE: .env file highlighting with leak warnings.
Code review: checklist item in PR template.
"Any new secrets or credentials in this change?"
Pre-commit: mandatory via pre-commit framework.
Config in repo, enforced for all developers.
Ban: no secrets in code, config files, Dockerfiles, or Helm values — always reference the secret store.
Immediate: revoke credential, rotate to new value. Audit access logs for signs of misuse.
Containment: Invalidate all tokens tied to the credential. Rotate DB passwords if DB credential leaked. Check CloudTrail or Cloud Logging for unauthorized access. Check GitHub audit log for repo access.
Communication: Notify security team via incident channel. Notify affected service owners. Notify compliance if PII was potentially exposed.
Post-mortem: root cause analysis. Why was it missed? Improve scanning rules.
Runbook per secret type: API key leak, DB password, cloud credential, certificate, OAuth token.
Vault audit: all reads, writes, deletes. Logged with timestamp, path, auth method, client IP.
Cloud audit: CloudTrail (AWS), Cloud Logging (GCP), Azure Monitor (Key Vault).
Retention: 90 days hot, 7 years cold for compliance.
Alerts on anomalous access:
Dashboard: secret access trends by service and user. Review weekly for suspicious patterns.
Pre-commit hooks can be bypassed (--no-verify, git commit --amend, merge commits). Always add CI-level scanning and scheduled periodic scans as defense in depth.
Relying solely on pattern matching generates false positives. truffleHog verified mode checks against live APIs (AWS STS, GitHub, Slack) and eliminates most false positives.
Setting rotation intervals without considering credential propagation time causes outages. Database credentials need a dual-credential window during rotation (old stays valid 24-48h after rotation). Test rotation in staging first.
Secrets Manager policies that grant wildcard access (secretsmanager:* or secret:*) defeat the purpose of centralized storage. Use least privilege with explicit paths and actions.
Overwriting secrets without keeping previous versions makes rollback impossible during incidents. Always version secrets and keep last 5 versions.
CI/CD pipeline variables often grant access to all jobs in a project. Stored in plaintext in the CI provider's database. Use the secrets manager directly from CI instead.
Without audit logging, leaked credentials cannot be traced to the source. Always log who accessed what secret, when, and from where.
Using the same secret across dev/staging/prod violates least privilege and complicates rotation. Every environment gets its own secrets with separate access policies.
Static API keys and passwords that never expire are the highest risk. Replace with dynamic secrets (short TTL, auto-revoke) whenever possible.
When a secret leaks, every minute counts. Without a pre-defined runbook per secret type, response time increases 3-5x.
GitLeaks is fastest for custom regex patterns. truffleHog adds verified scanning against live APIs (zero false positives for verified). ggshield covers 300+ services with broadest SaaS coverage. Use all three in sequence: GitLeaks (fast), ggshield (broad), truffleHog (verified).
Vault is the most flexible (multi-cloud, dynamic secrets, PKI, transit encryption). AWS Secrets Manager is best for AWS-only shops with RDS rotation. GCP Secret Manager provides multi-region replication with IAM. Azure Key Vault offers managed HSM and RBAC. Choose based on platform lock-in tolerance and multi-cloud needs.
Static secrets have infinite lifetime and require manual rotation. Dynamic secrets have configurable TTL, auto-expire, and auto-revoke. Dynamic secrets eliminate the risk of credential leak from stale credentials. Always prefer dynamic for databases, service accounts, and API tokens.
External Secrets Operator is the most flexible (20+ providers, auto-refresh, namespace-scoped). Vault CSI Provider mounts secrets as volumes (no K8s Secret resource, reduces attack surface). In-tree K8s Secrets are base64 encoded only, no rotation, no access audit. Never use in-tree secrets for production.
# .github/workflows/secret-scan.yml
name: Secret Scan
on:
pull_request:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: GitLeaks Scan
uses: gitleaks/gitleaks-action@v2
with:
config-path: .gitleaks.toml
- name: truffleHog Verified Scan
run: |
trufflehog git file://. --only-verified --fail \
--github-token ${{ secrets.GITHUB_TOKEN }}
secret-scan:
stage: test
script:
- gitleaks detect --source . --config .gitleaks.toml --verbose
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
# .github/workflows/deploy.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Fetch secrets from Vault
uses: hashicorp/vault-action@v2
with:
url: https://vault.example.com
method: jwt
secrets: |
secret/data/prod/db password | DB_PASSWORD;
secret/data/prod/api key | API_KEY;
- name: Deploy
run: ./deploy.sh
env:
DB_PASSWORD: ${{ steps.secrets.outputs.DB_PASSWORD }}
Committing .env files to Git is the root cause of most credential leaks. .env contains production credentials. .env.example with placeholder values should be committed instead. Enforce via .gitignore and a CI check that rejects PRs containing .env or .env.* excluding .env.example.
Using the same database password for dev, staging, and production. A developer with dev access can read production credentials. Compromise of a lower environment exposes production. Each environment must have separate credentials with independent access policies and rotation schedules.
Embedding secrets in container images or compiled binaries during build. Anyone with registry access can extract secrets from the image. Always inject secrets at runtime via volume mount, environment injection, or secrets manager SDK. Verify with docker history that no secrets are in image layers.
Service account JSON keys with indefinite lifetime and broad permissions stored on developer machines. If the machine is compromised, the key is compromised. Use workload identity federation (OIDC) instead — short-lived tokens with automatic rotation and no static secret material.
Engineers manually rotating secrets via SSH and config file edits. No audit trail, no rollback plan, high error rate. Automate rotation with secrets manager rotation functions or Vault dynamic secrets. Manual rotation must have a documented runbook.
Application logging framework captures environment variables or request parameters containing secrets. Secrets appear in log aggregation tools with long retention. Implement secret redaction in logging pipeline. Test by searching logs for common secret patterns.
security-container-security for secrets injection into containers
security-api-security for API key management and JWT signing secrets
` interface EventObserver { onEvent(event: T): Promise; }
class EventBus { private observers: Set<EventObserver> = new Set(); subscribe(observer: EventObserver): void { this.observers.add(observer); } unsubscribe(observer: EventObserver): void { this.observers.delete(observer); } async emit(event: T): Promise { const results = Array.from(this.observers).map(o => o.onEvent(event)); await Promise.allSettled(results); } } `
config: defaults: timeout: 30s retryCount: 3 overrides: production: timeout: 60s retryCount: 5 development: timeout: 300s retryCount: 1
| Metric | Threshold | Severity | Action |
|---|---|---|---|
| Error rate | > 1% over 5min | Critical | Page on-call |
| p99 latency | > 2s over 5min | Warning | Investigate |
| Throughput drop | > 50% over 1min | Critical | Check upstream |
| Queue depth | > 1000 over 1min | Warning | Scale consumers |
| Disk usage | > 85% | Warning | Clean or expand |
| Memory usage | > 90% heap | Critical | Restart or scale |
| Anti-Pattern | Symptom | Root Cause | Solution |
|---|---|---|---|
| Premature optimization | Complex code for no measured benefit | Guessing instead of profiling | Measure first, optimize based on data |
| Copy-paste reuse | Duplicate code across codebase | Lack of abstraction | Extract shared logic into libraries |
| Gold-plating | Features with no current requirement | Over-engineering | YAGNI — build what's needed now |
| Magical thinking | Assumptions without validation | Skipping error handling | Handle all failure modes explicitly |
Cache hierarchy: L1 (in-memory local) → L2 (distributed Redis/Memcached) → L3 (CDN/Edge). Cache invalidation: TTL-based (simple, stale), event-based (complex, fresh), write-through (consistent, higher write latency), write-behind (fast writes, eventual consistency).