[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AF62K0CZGX7P25WZ2ZCRFD":3,"skill-same:01M6AF62K0CZGX7P25WZ2ZCRFD":137},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":96,"commitSha":97,"skillDirectory":98,"forksCount":99,"repositoryHtmlUrl":100,"repositoryHomepageUrl":101,"ownerHtmlUrl":102,"ownerBlogUrl":103,"ownerDescription":104,"updatedAt":105,"install":106,"resources":119},"01M6AF62K0CZGX7P25WZ2ZCRFD","implementing-hashicorp-vault-dynamic-secrets",null,"Configures HashiCorp Vault dynamic secrets engines for database credentials, AWS IAM keys, and PKI certificates, with automatic generation, lease management, and rotation to eliminate static secrets in application configuration. Use when eliminating long-lived static credentials, configuring a Vault secrets engine, generating ephemeral database or cloud credentials, or automating credential rotation for compliance (PCI-DSS, NIST 800-53 IA-5).","mukul975\u002FAnthropic-Cybersecurity-Skills","mukul975","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F42860185?v=4","01M6ADEQR8T5M4EEG6C67BQCWF","Mahipal","01M6ADJPMYWG1E5GM1FWBE3128",35990,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fimplementing-hashicorp-vault-dynamic-secrets\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"implementing hashicorp vault dynamic secrets","t1003","AWS-secrets","database-credentials","secrets-management","dynamic-secrets","HashiCorp-Vault","t1098","initial-access","t1078","cybersecurity","pki","reconnaissance","NIST","iam","database","development","pr","identity","change","2026-11-10 10:12:30",false,"---\nname: implementing-hashicorp-vault-dynamic-secrets\ndescription: 'Configures HashiCorp Vault dynamic secrets engines for database credentials,\n  AWS IAM keys, and PKI certificates, with automatic generation, lease management,\n  and rotation to eliminate static secrets in application configuration. Use when\n  eliminating long-lived static credentials, configuring a Vault secrets engine,\n  generating ephemeral database or cloud credentials, or automating credential rotation\n  for compliance (PCI-DSS, NIST 800-53 IA-5).\n\n  '\ndomain: cybersecurity\nsubdomain: identity-access-management\ntags:\n- HashiCorp-Vault\n- dynamic-secrets\n- secrets-management\n- database-credentials\n- AWS-secrets\n- PKI\nversion: '1.0'\nauthor: mahipal\nlicense: Apache-2.0\nnist_csf:\n- PR.AA-01\n- PR.AA-02\n- PR.AA-05\n- PR.AA-06\nmitre_attack:\n- T1078\n- T1110\n- T1556\n- T1098\n- T1003\nmitre_f3:\n  version: '1.1'\n  tactics:\n  - initial-access\n  - positioning\n  - stealth\n  - resource-development\n  techniques:\n  - id: F1006.001\n    name: 'Account Takeover: Exposed API Key'\n    tactic: initial-access\n    source: f3\n  - id: F1006.002\n    name: 'Account Takeover: Exposed Login Credential'\n    tactic: initial-access\n    source: f3\n  - id: T1586\n    name: Compromise Accounts\n    tactic: resource-development\n    source: attack\n  - id: T1555\n    name: Credentials from Password Stores\n    tactic: reconnaissance\n    source: attack\n  - id: F1005.004\n    name: 'Account Manipulation: Change Account Details'\n    tactic: positioning\n    source: f3\n  - id: F1033\n    name: Insider Access Abuse\n    tactic: initial-access\n    source: f3\n---\n\n# Implementing HashiCorp Vault Dynamic Secrets\n\n## When to Use\n\n- Applications use static database credentials stored in configuration files or environment variables\n- AWS IAM access keys are long-lived and shared across services\n- Need to eliminate credential sprawl by generating short-lived, per-request secrets\n- Compliance requirements mandate credential rotation (PCI-DSS Requirement 8, NIST 800-53 IA-5)\n- Implementing zero-trust secret management where credentials are never stored at rest\n- Migrating from manual credential management to automated secrets lifecycle\n\n**Do not use** for storing static secrets that cannot be dynamically generated (use Vault's KV secrets engine instead); dynamic secrets are for credentials that can be programmatically created and revoked on target systems.\n\n## Prerequisites\n\n- HashiCorp Vault 1.15+ (Community or Enterprise edition)\n- Vault server initialized and unsealed with auto-unseal configured (AWS KMS, Azure Key Vault, or Transit)\n- Target database systems with admin credentials for Vault to create\u002Frevoke dynamic accounts\n- AWS IAM account with permissions to create\u002Fdelete IAM users and access keys\n- Network connectivity from Vault to all target systems\n- Vault policies and authentication methods configured for consuming applications\n\n## Workflow\n\n### Step 1: Deploy and Configure Vault Server\n\nInitialize Vault with production-grade configuration:\n\n```hcl\n# vault-config.hcl - Production Vault server configuration\nstorage \"raft\" {\n  path    = \"\u002Fopt\u002Fvault\u002Fdata\"\n  node_id = \"vault-1\"\n\n  retry_join {\n    leader_api_addr = \"https:\u002F\u002Fvault-2.corp.local:8200\"\n  }\n  retry_join {\n    leader_api_addr = \"https:\u002F\u002Fvault-3.corp.local:8200\"\n  }\n}\n\nlistener \"tcp\" {\n  address       = \"0.0.0.0:8200\"\n  tls_cert_file = \"\u002Fopt\u002Fvault\u002Ftls\u002Fvault-cert.pem\"\n  tls_key_file  = \"\u002Fopt\u002Fvault\u002Ftls\u002Fvault-key.pem\"\n}\n\nseal \"awskms\" {\n  region     = \"us-east-1\"\n  kms_key_id = \"alias\u002Fvault-unseal-key\"\n}\n\napi_addr      = \"https:\u002F\u002Fvault-1.corp.local:8200\"\ncluster_addr  = \"https:\u002F\u002Fvault-1.corp.local:8201\"\n\ntelemetry {\n  prometheus_retention_time = \"24h\"\n  disable_hostname          = true\n}\n\nui = true\n```\n\n```bash\n# Initialize Vault cluster\nvault operator init -key-shares=5 -key-threshold=3\n\n# Enable audit logging\nvault audit enable file file_path=\u002Fvar\u002Flog\u002Fvault\u002Faudit.log\n\n# Enable AppRole authentication for applications\nvault auth enable approle\n\n# Create policy for database secret consumers\nvault policy write db-consumer - \u003C\u003CEOF\n# Allow reading dynamic database credentials\npath \"database\u002Fcreds\u002Fapp-readonly\" {\n  capabilities = [\"read\"]\n}\npath \"database\u002Fcreds\u002Fapp-readwrite\" {\n  capabilities = [\"read\"]\n}\n\n# Allow renewing and revoking own leases\npath \"sys\u002Fleases\u002Frenew\" {\n  capabilities = [\"update\"]\n}\npath \"sys\u002Fleases\u002Frevoke\" {\n  capabilities = [\"update\"]\n}\n\n# Allow reading own token info\npath \"auth\u002Ftoken\u002Flookup-self\" {\n  capabilities = [\"read\"]\n}\nEOF\n\n# Create AppRole for application\nvault write auth\u002Fapprole\u002Frole\u002Fwebapp \\\n    token_policies=\"db-consumer\" \\\n    token_ttl=1h \\\n    token_max_ttl=4h \\\n    secret_id_ttl=720h \\\n    secret_id_num_uses=0\n```\n\n### Step 2: Configure Database Secrets Engine\n\nSet up dynamic credential generation for PostgreSQL and MySQL:\n\n```bash\n# Enable the database secrets engine\nvault secrets enable database\n\n# Configure PostgreSQL connection\nvault write database\u002Fconfig\u002Fproduction-postgres \\\n    plugin_name=postgresql-database-plugin \\\n    allowed_roles=\"app-readonly,app-readwrite,app-admin\" \\\n    connection_url=\"postgresql:\u002F\u002F{{username}}:{{password}}@db-primary.corp.local:5432\u002Fappdb?sslmode=verify-full\" \\\n    username=\"vault_admin\" \\\n    password=\"$VAULT_DB_PASSWORD\" \\\n    password_authentication=\"scram-sha-256\"\n\n# Rotate the root credentials so Vault manages them exclusively\nvault write -force database\u002Frotate-root\u002Fproduction-postgres\n\n# Create read-only role (TTL: 1 hour, max 24 hours)\nvault write database\u002Froles\u002Fapp-readonly \\\n    db_name=production-postgres \\\n    creation_statements=\"CREATE ROLE \\\"{{name}}\\\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \\\n        GRANT SELECT ON ALL TABLES IN SCHEMA public TO \\\"{{name}}\\\"; \\\n        ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO \\\"{{name}}\\\";\" \\\n    revocation_statements=\"REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM \\\"{{name}}\\\"; \\\n        DROP ROLE IF EXISTS \\\"{{name}}\\\";\" \\\n    default_ttl=\"1h\" \\\n    max_ttl=\"24h\"\n\n# Create read-write role (TTL: 30 minutes, max 8 hours)\nvault write database\u002Froles\u002Fapp-readwrite \\\n    db_name=production-postgres \\\n    creation_statements=\"CREATE ROLE \\\"{{name}}\\\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \\\n        GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO \\\"{{name}}\\\"; \\\n        ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO \\\"{{name}}\\\";\" \\\n    revocation_statements=\"REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM \\\"{{name}}\\\"; \\\n        DROP ROLE IF EXISTS \\\"{{name}}\\\";\" \\\n    default_ttl=\"30m\" \\\n    max_ttl=\"8h\"\n\n# Configure MySQL connection\nvault write database\u002Fconfig\u002Fproduction-mysql \\\n    plugin_name=mysql-database-plugin \\\n    allowed_roles=\"mysql-readonly,mysql-readwrite\" \\\n    connection_url=\"{{username}}:{{password}}@tcp(mysql-primary.corp.local:3306)\u002F\" \\\n    username=\"vault_admin\" \\\n    password=\"$VAULT_MYSQL_PASSWORD\"\n\nvault write database\u002Froles\u002Fmysql-readonly \\\n    db_name=production-mysql \\\n    creation_statements=\"CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; \\\n        GRANT SELECT ON appdb.* TO '{{name}}'@'%';\" \\\n    revocation_statements=\"DROP USER IF EXISTS '{{name}}'@'%';\" \\\n    default_ttl=\"1h\" \\\n    max_ttl=\"24h\"\n\n# Test dynamic credential generation\necho \"Testing PostgreSQL dynamic credentials:\"\nvault read database\u002Fcreds\u002Fapp-readonly\n# Returns: username=v-approle-app-read-xxxxx, password=\u003Crandom>, lease_id=database\u002Fcreds\u002Fapp-readonly\u002Fxxxxx\n```\n\n### Step 3: Configure AWS Secrets Engine\n\nGenerate ephemeral AWS IAM credentials:\n\n```bash\n# Enable the AWS secrets engine\nvault secrets enable aws\n\n# Configure the AWS secrets engine with root credentials\nvault write aws\u002Fconfig\u002Froot \\\n    access_key=\"$AWS_ACCESS_KEY_ID\" \\\n    secret_key=\"$AWS_SECRET_ACCESS_KEY\" \\\n    region=\"us-east-1\"\n\n# Configure lease settings\nvault write aws\u002Fconfig\u002Flease \\\n    lease=\"30m\" \\\n    lease_max=\"1h\"\n\n# Create IAM User role for S3 read-only access\nvault write aws\u002Froles\u002Fs3-readonly \\\n    credential_type=iam_user \\\n    policy_document=-\u003C\u003CEOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:GetObject\",\n        \"s3:ListBucket\",\n        \"s3:GetBucketLocation\"\n      ],\n      \"Resource\": [\n        \"arn:aws:s3:::app-data-bucket\",\n        \"arn:aws:s3:::app-data-bucket\u002F*\"\n      ]\n    }\n  ]\n}\nEOF\n\n# Create Assumed Role for EC2 management (preferred over IAM users)\nvault write aws\u002Froles\u002Fec2-admin \\\n    credential_type=assumed_role \\\n    role_arns=\"arn:aws:iam::123456789012:role\u002FVaultEC2AdminRole\" \\\n    default_sts_ttl=\"30m\" \\\n    max_sts_ttl=\"1h\"\n\n# Create Federation Token role for cross-account access\nvault write aws\u002Froles\u002Fcross-account-readonly \\\n    credential_type=federation_token \\\n    policy_document=-\u003C\u003CEOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"sts:AssumeRole\"\n      ],\n      \"Resource\": \"arn:aws:iam::987654321098:role\u002FCrossAccountReadOnly\"\n    }\n  ]\n}\nEOF\n\n# Test AWS dynamic credentials\necho \"Testing AWS STS credentials:\"\nvault read aws\u002Fcreds\u002Fec2-admin\n# Returns: access_key, secret_key, security_token with 30-minute TTL\n```\n\n### Step 4: Configure PKI Secrets Engine for Dynamic Certificates\n\nGenerate short-lived TLS certificates on demand:\n\n```bash\n# Enable PKI secrets engine for root CA\nvault secrets enable -path=pki pki\nvault secrets tune -max-lease-ttl=87600h pki\n\n# Generate root CA certificate\nvault write pki\u002Froot\u002Fgenerate\u002Finternal \\\n    common_name=\"Corp Internal Root CA\" \\\n    ttl=87600h \\\n    key_type=ec \\\n    key_bits=384\n\n# Enable PKI for intermediate CA\nvault secrets enable -path=pki_int pki\nvault secrets tune -max-lease-ttl=43800h pki_int\n\n# Generate intermediate CA CSR\nvault write pki_int\u002Fintermediate\u002Fgenerate\u002Finternal \\\n    common_name=\"Corp Intermediate CA\" \\\n    key_type=ec \\\n    key_bits=256\n\n# Sign intermediate CA with root CA\nvault write pki\u002Froot\u002Fsign-intermediate \\\n    csr=@intermediate.csr \\\n    format=pem_bundle \\\n    ttl=43800h\n\n# Configure issuing URLs\nvault write pki_int\u002Fconfig\u002Furls \\\n    issuing_certificates=\"https:\u002F\u002Fvault.corp.local:8200\u002Fv1\u002Fpki_int\u002Fca\" \\\n    crl_distribution_points=\"https:\u002F\u002Fvault.corp.local:8200\u002Fv1\u002Fpki_int\u002Fcrl\"\n\n# Create role for web server certificates (TTL: 30 days)\nvault write pki_int\u002Froles\u002Fweb-server \\\n    allowed_domains=\"corp.local,internal.corp.com\" \\\n    allow_subdomains=true \\\n    max_ttl=720h \\\n    key_type=ec \\\n    key_bits=256 \\\n    require_cn=true \\\n    enforce_hostnames=true\n\n# Create role for service mesh certificates (TTL: 24 hours)\nvault write pki_int\u002Froles\u002Fservice-mesh \\\n    allowed_domains=\"service.consul\" \\\n    allow_subdomains=true \\\n    max_ttl=24h \\\n    key_type=ec \\\n    key_bits=256 \\\n    allow_ip_sans=true \\\n    server_flag=true \\\n    client_flag=true\n\n# Issue a certificate\nvault write pki_int\u002Fissue\u002Fweb-server \\\n    common_name=\"api.corp.local\" \\\n    alt_names=\"api.internal.corp.com\" \\\n    ttl=720h\n```\n\n### Step 5: Integrate Applications with Vault\n\nConfigure applications to consume dynamic secrets:\n\n```python\n\"\"\"\nApplication integration with HashiCorp Vault for dynamic database credentials.\nUses the hvac Python client with automatic lease renewal.\n\"\"\"\nimport hvac\nimport threading\nimport time\nimport logging\n\nclass VaultDynamicCredentialManager:\n    def __init__(self, vault_addr, role_id, secret_id):\n        self.client = hvac.Client(url=vault_addr)\n        self.role_id = role_id\n        self.secret_id = secret_id\n        self.logger = logging.getLogger(\"vault_credentials\")\n        self._current_creds = None\n        self._lease_id = None\n        self._renewal_thread = None\n        self._stop_event = threading.Event()\n\n    def authenticate(self):\n        \"\"\"Authenticate to Vault using AppRole.\"\"\"\n        response = self.client.auth.approle.login(\n            role_id=self.role_id,\n            secret_id=self.secret_id\n        )\n        self.client.token = response[\"auth\"][\"client_token\"]\n        self.logger.info(\"Authenticated to Vault via AppRole\")\n\n    def get_database_credentials(self, role=\"app-readonly\"):\n        \"\"\"Request dynamic database credentials from Vault.\"\"\"\n        self.authenticate()\n\n        response = self.client.secrets.database.generate_credentials(\n            name=role\n        )\n\n        self._current_creds = {\n            \"username\": response[\"data\"][\"username\"],\n            \"password\": response[\"data\"][\"password\"],\n        }\n        self._lease_id = response[\"lease_id\"]\n        lease_duration = response[\"lease_duration\"]\n\n        self.logger.info(\n            f\"Obtained dynamic credentials: user={self._current_creds['username']}, \"\n            f\"lease={self._lease_id}, ttl={lease_duration}s\"\n        )\n\n        # Start background lease renewal\n        self._start_renewal(lease_duration)\n\n        return self._current_creds\n\n    def _start_renewal(self, lease_duration):\n        \"\"\"Start background thread to renew lease before expiration.\"\"\"\n        if self._renewal_thread and self._renewal_thread.is_alive():\n            self._stop_event.set()\n            self._renewal_thread.join()\n\n        self._stop_event.clear()\n        renewal_interval = lease_duration * 0.7  # Renew at 70% of TTL\n\n        def renew_loop():\n            while not self._stop_event.wait(renewal_interval):\n                try:\n                    self.client.sys.renew_lease(\n                        lease_id=self._lease_id,\n                        increment=lease_duration\n                    )\n                    self.logger.info(f\"Renewed lease: {self._lease_id}\")\n                except hvac.exceptions.InvalidRequest:\n                    self.logger.warning(\"Lease expired, obtaining new credentials\")\n                    self.get_database_credentials()\n                    break\n                except Exception as e:\n                    self.logger.error(f\"Lease renewal failed: {e}\")\n\n        self._renewal_thread = threading.Thread(target=renew_loop, daemon=True)\n        self._renewal_thread.start()\n\n    def revoke_credentials(self):\n        \"\"\"Explicitly revoke current dynamic credentials.\"\"\"\n        if self._lease_id:\n            self._stop_event.set()\n            self.client.sys.revoke_lease(self._lease_id)\n            self.logger.info(f\"Revoked lease: {self._lease_id}\")\n            self._current_creds = None\n            self._lease_id = None\n\n    def get_aws_credentials(self, role=\"s3-readonly\"):\n        \"\"\"Request dynamic AWS credentials from Vault.\"\"\"\n        self.authenticate()\n\n        response = self.client.secrets.aws.generate_credentials(\n            name=role\n        )\n\n        return {\n            \"access_key\": response[\"data\"][\"access_key\"],\n            \"secret_key\": response[\"data\"][\"secret_key\"],\n            \"security_token\": response[\"data\"].get(\"security_token\"),\n            \"lease_id\": response[\"lease_id\"],\n            \"ttl\": response[\"lease_duration\"]\n        }\n\n# Usage example\nvault_mgr = VaultDynamicCredentialManager(\n    vault_addr=\"https:\u002F\u002Fvault.corp.local:8200\",\n    role_id=\"\u003Capprole-role-id>\",\n    secret_id=\"\u003Capprole-secret-id>\"\n)\n\ndb_creds = vault_mgr.get_database_credentials(\"app-readonly\")\n# Use db_creds[\"username\"] and db_creds[\"password\"] for database connection\n```\n\n### Step 6: Monitor Vault Operations and Lease Management\n\nTrack dynamic secret usage and lease lifecycle:\n\n```bash\n# Monitor active leases\nvault list sys\u002Fleases\u002Flookup\u002Fdatabase\u002Fcreds\u002Fapp-readonly\nvault list sys\u002Fleases\u002Flookup\u002Faws\u002Fcreds\u002Fs3-readonly\n\n# Check lease details\nvault write sys\u002Fleases\u002Flookup lease_id=\"database\u002Fcreds\u002Fapp-readonly\u002Fabcd1234\"\n\n# Revoke all leases for a specific path (emergency credential rotation)\nvault lease revoke -prefix database\u002Fcreds\u002Fapp-readonly\n\n# Vault metrics for monitoring (Prometheus format)\n# Key metrics to monitor:\n# vault.expire.num_leases - Total active leases\n# vault.expire.revoke - Lease revocations per second\n# vault.secret.kv.count - Total stored secrets\n# vault.runtime.alloc_bytes - Memory allocation\n\n# Configure Vault audit log analysis\ncat > vault_audit_monitor.sh \u003C\u003C 'SCRIPT'\n#!\u002Fbin\u002Fbash\n# Monitor Vault audit logs for suspicious activity\n\nAUDIT_LOG=\"\u002Fvar\u002Flog\u002Fvault\u002Faudit.log\"\n\n# Count credential requests per hour\necho \"=== Dynamic Credential Requests (Last Hour) ===\"\njq -r 'select(.type == \"response\" and .request.path | startswith(\"database\u002Fcreds\u002F\")) |\n    \"\\(.time) \\(.request.path) \\(.auth.display_name)\"' \\\n    \"$AUDIT_LOG\" | tail -100\n\n# Detect unusual credential request patterns\necho \"\"\necho \"=== High-Volume Credential Consumers ===\"\njq -r 'select(.type == \"request\" and .request.path | startswith(\"database\u002Fcreds\u002F\")) |\n    .auth.display_name' \\\n    \"$AUDIT_LOG\" | sort | uniq -c | sort -rn | head -10\n\n# Check for failed authentication attempts\necho \"\"\necho \"=== Failed Auth Attempts ===\"\njq -r 'select(.type == \"response\" and .error != null and\n    .request.path | startswith(\"auth\u002F\")) |\n    \"\\(.time) \\(.request.path) \\(.error)\"' \\\n    \"$AUDIT_LOG\" | tail -20\nSCRIPT\nchmod +x vault_audit_monitor.sh\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| **Dynamic Secrets** | Credentials generated on-demand by Vault with automatic expiration, ensuring each consumer receives unique short-lived credentials |\n| **Lease** | Time-bound agreement where Vault guarantees the credential is valid; consumers must renew before expiration or request new credentials |\n| **Secrets Engine** | Vault plugin that generates, stores, or encrypts data; database, AWS, PKI, and KV are common engines |\n| **AppRole** | Vault authentication method designed for machine-to-machine authentication using role ID and secret ID pairs |\n| **Root Credential Rotation** | Process of having Vault take exclusive ownership of the admin credential used to create dynamic secrets, eliminating human knowledge of the root password |\n| **Lease Revocation** | Immediate invalidation of dynamic credentials, used during incident response to revoke all credentials for compromised paths |\n\n## Tools & Systems\n\n- **HashiCorp Vault**: Secrets management platform providing dynamic secrets, encryption as a service, and identity-based access control\n- **Vault Agent**: Sidecar process that handles Vault authentication, token renewal, and secret caching for applications\n- **Vault Secrets Operator**: Kubernetes operator that syncs Vault secrets into Kubernetes Secrets for pod consumption\n- **hvac**: Python client library for HashiCorp Vault API operations\n\n## Common Scenarios\n\n### Scenario: Eliminating Static Database Credentials in Microservices\n\n**Context**: 50 microservices share 3 static PostgreSQL credentials stored in environment variables across Kubernetes deployments. A credential leak requires rotating all 50 services simultaneously.\n\n**Approach**:\n1. Deploy Vault with Raft storage in a 3-node HA cluster within Kubernetes\n2. Configure database secrets engine with PostgreSQL connection using admin credentials\n3. Create per-service Vault roles with least-privilege SQL grants\n4. Deploy Vault Secrets Operator to inject dynamic credentials into pod environment variables\n5. Update application connection logic to handle credential rotation via lease renewal\n6. Rotate the Vault root credential to remove human knowledge of the admin password\n7. Monitor lease lifecycle and set alerts for renewal failures\n\n**Pitfalls**:\n- Not handling credential rotation in application connection pools (connections using expired credentials fail)\n- Setting TTLs too short causes excessive credential generation load on the database\n- Not configuring proper revocation statements leaves orphaned database users after lease expiration\n- Running Vault without HA causes single point of failure for all application authentication\n\n## Output Format\n\n```\nHASHICORP VAULT DYNAMIC SECRETS REPORT\n=========================================\nVault Version:     1.16.2 Enterprise\nCluster Status:    HA Active (3 nodes)\nSeal Type:         AWS KMS (auto-unseal)\n\nSECRETS ENGINES\ndatabase\u002F:         PostgreSQL, MySQL (2 connections)\naws\u002F:              IAM User, Assumed Role, Federation Token\npki_int\u002F:          Internal CA (EC P-256)\n\nDYNAMIC CREDENTIAL METRICS (Last 24 Hours)\nTotal Credentials Generated:    4,287\n  Database (PostgreSQL):        2,891\n  Database (MySQL):             543\n  AWS STS:                      612\n  PKI Certificates:             241\n\nACTIVE LEASES\nTotal Active:                   387\n  database\u002Fcreds\u002Fapp-readonly:  198\n  database\u002Fcreds\u002Fapp-readwrite: 89\n  aws\u002Fcreds\u002Fs3-readonly:        67\n  pki_int\u002Fissue\u002Fweb-server:     33\n\nLEASE LIFECYCLE\nAverage TTL:                    45 minutes\nRenewals (24h):                 12,847\nRevocations (24h):              3,901\nExpired (not renewed):          12\n\nSECURITY\nFailed Auth Attempts (24h):     3\nRoot Credential Rotated:        YES (all databases)\nAudit Logging:                  ENABLED (file + syslog)\nPolicy Violations (24h):        7 (permission denied)\n```\n","# Implementing HashiCorp Vault Dynamic Secrets\n\n## When to Use\n\n- Applications use static database credentials stored in configuration files or environment variables\n- AWS IAM access keys are long-lived and shared across services\n- Need to eliminate credential sprawl by generating short-lived, per-request secrets\n- Compliance requirements mandate credential rotation (PCI-DSS Requirement 8, NIST 800-53 IA-5)\n- Implementing zero-trust secret management where credentials are never stored at rest\n- Migrating from manual credential management to automated secrets lifecycle\n\n**Do not use** for storing static secrets that cannot be dynamically generated (use Vault's KV secrets engine instead); dynamic secrets are for credentials that can be programmatically created and revoked on target systems.\n\n## Prerequisites\n\n- HashiCorp Vault 1.15+ (Community or Enterprise edition)\n- Vault server initialized and unsealed with auto-unseal configured (AWS KMS, Azure Key Vault, or Transit)\n- Target database systems with admin credentials for Vault to create\u002Frevoke dynamic accounts\n- AWS IAM account with permissions to create\u002Fdelete IAM users and access keys\n- Network connectivity from Vault to all target systems\n- Vault policies and authentication methods configured for consuming applications\n\n## Workflow\n\n### Step 1: Deploy and Configure Vault Server\n\nInitialize Vault with production-grade configuration:\n\n```hcl\n# vault-config.hcl - Production Vault server configuration\nstorage \"raft\" {\n  path    = \"\u002Fopt\u002Fvault\u002Fdata\"\n  node_id = \"vault-1\"\n\n  retry_join {\n    leader_api_addr = \"https:\u002F\u002Fvault-2.corp.local:8200\"\n  }\n  retry_join {\n    leader_api_addr = \"https:\u002F\u002Fvault-3.corp.local:8200\"\n  }\n}\n\nlistener \"tcp\" {\n  address       = \"0.0.0.0:8200\"\n  tls_cert_file = \"\u002Fopt\u002Fvault\u002Ftls\u002Fvault-cert.pem\"\n  tls_key_file  = \"\u002Fopt\u002Fvault\u002Ftls\u002Fvault-key.pem\"\n}\n\nseal \"awskms\" {\n  region     = \"us-east-1\"\n  kms_key_id = \"alias\u002Fvault-unseal-key\"\n}\n\napi_addr      = \"https:\u002F\u002Fvault-1.corp.local:8200\"\ncluster_addr  = \"https:\u002F\u002Fvault-1.corp.local:8201\"\n\ntelemetry {\n  prometheus_retention_time = \"24h\"\n  disable_hostname          = true\n}\n\nui = true\n```\n\n```bash\n# Initialize Vault cluster\nvault operator init -key-shares=5 -key-threshold=3\n\n# Enable audit logging\nvault audit enable file file_path=\u002Fvar\u002Flog\u002Fvault\u002Faudit.log\n\n# Enable AppRole authentication for applications\nvault auth enable approle\n\n# Create policy for database secret consumers\nvault policy write db-consumer - \u003C\u003CEOF\n# Allow reading dynamic database credentials\npath \"database\u002Fcreds\u002Fapp-readonly\" {\n  capabilities = [\"read\"]\n}\npath \"database\u002Fcreds\u002Fapp-readwrite\" {\n  capabilities = [\"read\"]\n}\n\n# Allow renewing and revoking own leases\npath \"sys\u002Fleases\u002Frenew\" {\n  capabilities = [\"update\"]\n}\npath \"sys\u002Fleases\u002Frevoke\" {\n  capabilities = [\"update\"]\n}\n\n# Allow reading own token info\npath \"auth\u002Ftoken\u002Flookup-self\" {\n  capabilities = [\"read\"]\n}\nEOF\n\n# Create AppRole for application\nvault write auth\u002Fapprole\u002Frole\u002Fwebapp \\\n    token_policies=\"db-consumer\" \\\n    token_ttl=1h \\\n    token_max_ttl=4h \\\n    secret_id_ttl=720h \\\n    secret_id_num_uses=0\n```\n\n### Step 2: Configure Database Secrets Engine\n\nSet up dynamic credential generation for PostgreSQL and MySQL:\n\n```bash\n# Enable the database secrets engine\nvault secrets enable database\n\n# Configure PostgreSQL connection\nvault write database\u002Fconfig\u002Fproduction-postgres \\\n    plugin_name=postgresql-database-plugin \\\n    allowed_roles=\"app-readonly,app-readwrite,app-admin\" \\\n    connection_url=\"postgresql:\u002F\u002F{{username}}:{{password}}@db-primary.corp.local:5432\u002Fappdb?sslmode=verify-full\" \\\n    username=\"vault_admin\" \\\n    password=\"$VAULT_DB_PASSWORD\" \\\n    password_authentication=\"scram-sha-256\"\n\n# Rotate the root credentials so Vault manages them exclusively\nvault write -force database\u002Frotate-root\u002Fproduction-postgres\n\n# Create read-only role (TTL: 1 hour, max 24 hours)\nvault write database\u002Froles\u002Fapp-readonly \\\n    db_name=production-postgres \\\n    creation_statements=\"CREATE ROLE \\\"{{name}}\\\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \\\n        GRANT SELECT ON ALL TABLES IN SCHEMA public TO \\\"{{name}}\\\"; \\\n        ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO \\\"{{name}}\\\";\" \\\n    revocation_statements=\"REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM \\\"{{name}}\\\"; \\\n        DROP ROLE IF EXISTS \\\"{{name}}\\\";\" \\\n    default_ttl=\"1h\" \\\n    max_ttl=\"24h\"\n\n# Create read-write role (TTL: 30 minutes, max 8 hours)\nvault write database\u002Froles\u002Fapp-readwrite \\\n    db_name=production-postgres \\\n    creation_statements=\"CREATE ROLE \\\"{{name}}\\\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \\\n        GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO \\\"{{name}}\\\"; \\\n        ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO \\\"{{name}}\\\";\" \\\n    revocation_statements=\"REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM \\\"{{name}}\\\"; \\\n        DROP ROLE IF EXISTS \\\"{{name}}\\\";\" \\\n    default_ttl=\"30m\" \\\n    max_ttl=\"8h\"\n\n# Configure MySQL connection\nvault write database\u002Fconfig\u002Fproduction-mysql \\\n    plugin_name=mysql-database-plugin \\\n    allowed_roles=\"mysql-readonly,mysql-readwrite\" \\\n    connection_url=\"{{username}}:{{password}}@tcp(mysql-primary.corp.local:3306)\u002F\" \\\n    username=\"vault_admin\" \\\n    password=\"$VAULT_MYSQL_PASSWORD\"\n\nvault write database\u002Froles\u002Fmysql-readonly \\\n    db_name=production-mysql \\\n    creation_statements=\"CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; \\\n        GRANT SELECT ON appdb.* TO '{{name}}'@'%';\" \\\n    revocation_statements=\"DROP USER IF EXISTS '{{name}}'@'%';\" \\\n    default_ttl=\"1h\" \\\n    max_ttl=\"24h\"\n\n# Test dynamic credential generation\necho \"Testing PostgreSQL dynamic credentials:\"\nvault read database\u002Fcreds\u002Fapp-readonly\n# Returns: username=v-approle-app-read-xxxxx, password=\u003Crandom>, lease_id=database\u002Fcreds\u002Fapp-readonly\u002Fxxxxx\n```\n\n### Step 3: Configure AWS Secrets Engine\n\nGenerate ephemeral AWS IAM credentials:\n\n```bash\n# Enable the AWS secrets engine\nvault secrets enable aws\n\n# Configure the AWS secrets engine with root credentials\nvault write aws\u002Fconfig\u002Froot \\\n    access_key=\"$AWS_ACCESS_KEY_ID\" \\\n    secret_key=\"$AWS_SECRET_ACCESS_KEY\" \\\n    region=\"us-east-1\"\n\n# Configure lease settings\nvault write aws\u002Fconfig\u002Flease \\\n    lease=\"30m\" \\\n    lease_max=\"1h\"\n\n# Create IAM User role for S3 read-only access\nvault write aws\u002Froles\u002Fs3-readonly \\\n    credential_type=iam_user \\\n    policy_document=-\u003C\u003CEOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:GetObject\",\n        \"s3:ListBucket\",\n        \"s3:GetBucketLocation\"\n      ],\n      \"Resource\": [\n        \"arn:aws:s3:::app-data-bucket\",\n        \"arn:aws:s3:::app-data-bucket\u002F*\"\n      ]\n    }\n  ]\n}\nEOF\n\n# Create Assumed Role for EC2 management (preferred over IAM users)\nvault write aws\u002Froles\u002Fec2-admin \\\n    credential_type=assumed_role \\\n    role_arns=\"arn:aws:iam::123456789012:role\u002FVaultEC2AdminRole\" \\\n    default_sts_ttl=\"30m\" \\\n    max_sts_ttl=\"1h\"\n\n# Create Federation Token role for cross-account access\nvault write aws\u002Froles\u002Fcross-account-readonly \\\n    credential_type=federation_token \\\n    policy_document=-\u003C\u003CEOF\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"sts:AssumeRole\"\n      ],\n      \"Resource\": \"arn:aws:iam::987654321098:role\u002FCrossAccountReadOnly\"\n    }\n  ]\n}\nEOF\n\n# Test AWS dynamic credentials\necho \"Testing AWS STS credentials:\"\nvault read aws\u002Fcreds\u002Fec2-admin\n# Returns: access_key, secret_key, security_token with 30-minute TTL\n```\n\n### Step 4: Configure PKI Secrets Engine for Dynamic Certificates\n\nGenerate short-lived TLS certificates on demand:\n\n```bash\n# Enable PKI secrets engine for root CA\nvault secrets enable -path=pki pki\nvault secrets tune -max-lease-ttl=87600h pki\n\n# Generate root CA certificate\nvault write pki\u002Froot\u002Fgenerate\u002Finternal \\\n    common_name=\"Corp Internal Root CA\" \\\n    ttl=87600h \\\n    key_type=ec \\\n    key_bits=384\n\n# Enable PKI for intermediate CA\nvault secrets enable -path=pki_int pki\nvault secrets tune -max-lease-ttl=43800h pki_int\n\n# Generate intermediate CA CSR\nvault write pki_int\u002Fintermediate\u002Fgenerate\u002Finternal \\\n    common_name=\"Corp Intermediate CA\" \\\n    key_type=ec \\\n    key_bits=256\n\n# Sign intermediate CA with root CA\nvault write pki\u002Froot\u002Fsign-intermediate \\\n    csr=@intermediate.csr \\\n    format=pem_bundle \\\n    ttl=43800h\n\n# Configure issuing URLs\nvault write pki_int\u002Fconfig\u002Furls \\\n    issuing_certificates=\"https:\u002F\u002Fvault.corp.local:8200\u002Fv1\u002Fpki_int\u002Fca\" \\\n    crl_distribution_points=\"https:\u002F\u002Fvault.corp.local:8200\u002Fv1\u002Fpki_int\u002Fcrl\"\n\n# Create role for web server certificates (TTL: 30 days)\nvault write pki_int\u002Froles\u002Fweb-server \\\n    allowed_domains=\"corp.local,internal.corp.com\" \\\n    allow_subdomains=true \\\n    max_ttl=720h \\\n    key_type=ec \\\n    key_bits=256 \\\n    require_cn=true \\\n    enforce_hostnames=true\n\n# Create role for service mesh certificates (TTL: 24 hours)\nvault write pki_int\u002Froles\u002Fservice-mesh \\\n    allowed_domains=\"service.consul\" \\\n    allow_subdomains=true \\\n    max_ttl=24h \\\n    key_type=ec \\\n    key_bits=256 \\\n    allow_ip_sans=true \\\n    server_flag=true \\\n    client_flag=true\n\n# Issue a certificate\nvault write pki_int\u002Fissue\u002Fweb-server \\\n    common_name=\"api.corp.local\" \\\n    alt_names=\"api.internal.corp.com\" \\\n    ttl=720h\n```\n\n### Step 5: Integrate Applications with Vault\n\nConfigure applications to consume dynamic secrets:\n\n```python\n\"\"\"\nApplication integration with HashiCorp Vault for dynamic database credentials.\nUses the hvac Python client with automatic lease renewal.\n\"\"\"\nimport hvac\nimport threading\nimport time\nimport logging\n\nclass VaultDynamicCredentialManager:\n    def __init__(self, vault_addr, role_id, secret_id):\n        self.client = hvac.Client(url=vault_addr)\n        self.role_id = role_id\n        self.secret_id = secret_id\n        self.logger = logging.getLogger(\"vault_credentials\")\n        self._current_creds = None\n        self._lease_id = None\n        self._renewal_thread = None\n        self._stop_event = threading.Event()\n\n    def authenticate(self):\n        \"\"\"Authenticate to Vault using AppRole.\"\"\"\n        response = self.client.auth.approle.login(\n            role_id=self.role_id,\n            secret_id=self.secret_id\n        )\n        self.client.token = response[\"auth\"][\"client_token\"]\n        self.logger.info(\"Authenticated to Vault via AppRole\")\n\n    def get_database_credentials(self, role=\"app-readonly\"):\n        \"\"\"Request dynamic database credentials from Vault.\"\"\"\n        self.authenticate()\n\n        response = self.client.secrets.database.generate_credentials(\n            name=role\n        )\n\n        self._current_creds = {\n            \"username\": response[\"data\"][\"username\"],\n            \"password\": response[\"data\"][\"password\"],\n        }\n        self._lease_id = response[\"lease_id\"]\n        lease_duration = response[\"lease_duration\"]\n\n        self.logger.info(\n            f\"Obtained dynamic credentials: user={self._current_creds['username']}, \"\n            f\"lease={self._lease_id}, ttl={lease_duration}s\"\n        )\n\n        # Start background lease renewal\n        self._start_renewal(lease_duration)\n\n        return self._current_creds\n\n    def _start_renewal(self, lease_duration):\n        \"\"\"Start background thread to renew lease before expiration.\"\"\"\n        if self._renewal_thread and self._renewal_thread.is_alive():\n            self._stop_event.set()\n            self._renewal_thread.join()\n\n        self._stop_event.clear()\n        renewal_interval = lease_duration * 0.7  # Renew at 70% of TTL\n\n        def renew_loop():\n            while not self._stop_event.wait(renewal_interval):\n                try:\n                    self.client.sys.renew_lease(\n                        lease_id=self._lease_id,\n                        increment=lease_duration\n                    )\n                    self.logger.info(f\"Renewed lease: {self._lease_id}\")\n                except hvac.exceptions.InvalidRequest:\n                    self.logger.warning(\"Lease expired, obtaining new credentials\")\n                    self.get_database_credentials()\n                    break\n                except Exception as e:\n                    self.logger.error(f\"Lease renewal failed: {e}\")\n\n        self._renewal_thread = threading.Thread(target=renew_loop, daemon=True)\n        self._renewal_thread.start()\n\n    def revoke_credentials(self):\n        \"\"\"Explicitly revoke current dynamic credentials.\"\"\"\n        if self._lease_id:\n            self._stop_event.set()\n            self.client.sys.revoke_lease(self._lease_id)\n            self.logger.info(f\"Revoked lease: {self._lease_id}\")\n            self._current_creds = None\n            self._lease_id = None\n\n    def get_aws_credentials(self, role=\"s3-readonly\"):\n        \"\"\"Request dynamic AWS credentials from Vault.\"\"\"\n        self.authenticate()\n\n        response = self.client.secrets.aws.generate_credentials(\n            name=role\n        )\n\n        return {\n            \"access_key\": response[\"data\"][\"access_key\"],\n            \"secret_key\": response[\"data\"][\"secret_key\"],\n            \"security_token\": response[\"data\"].get(\"security_token\"),\n            \"lease_id\": response[\"lease_id\"],\n            \"ttl\": response[\"lease_duration\"]\n        }\n\n# Usage example\nvault_mgr = VaultDynamicCredentialManager(\n    vault_addr=\"https:\u002F\u002Fvault.corp.local:8200\",\n    role_id=\"\u003Capprole-role-id>\",\n    secret_id=\"\u003Capprole-secret-id>\"\n)\n\ndb_creds = vault_mgr.get_database_credentials(\"app-readonly\")\n# Use db_creds[\"username\"] and db_creds[\"password\"] for database connection\n```\n\n### Step 6: Monitor Vault Operations and Lease Management\n\nTrack dynamic secret usage and lease lifecycle:\n\n```bash\n# Monitor active leases\nvault list sys\u002Fleases\u002Flookup\u002Fdatabase\u002Fcreds\u002Fapp-readonly\nvault list sys\u002Fleases\u002Flookup\u002Faws\u002Fcreds\u002Fs3-readonly\n\n# Check lease details\nvault write sys\u002Fleases\u002Flookup lease_id=\"database\u002Fcreds\u002Fapp-readonly\u002Fabcd1234\"\n\n# Revoke all leases for a specific path (emergency credential rotation)\nvault lease revoke -prefix database\u002Fcreds\u002Fapp-readonly\n\n# Vault metrics for monitoring (Prometheus format)\n# Key metrics to monitor:\n# vault.expire.num_leases - Total active leases\n# vault.expire.revoke - Lease revocations per second\n# vault.secret.kv.count - Total stored secrets\n# vault.runtime.alloc_bytes - Memory allocation\n\n# Configure Vault audit log analysis\ncat > vault_audit_monitor.sh \u003C\u003C 'SCRIPT'\n#!\u002Fbin\u002Fbash\n# Monitor Vault audit logs for suspicious activity\n\nAUDIT_LOG=\"\u002Fvar\u002Flog\u002Fvault\u002Faudit.log\"\n\n# Count credential requests per hour\necho \"=== Dynamic Credential Requests (Last Hour) ===\"\njq -r 'select(.type == \"response\" and .request.path | startswith(\"database\u002Fcreds\u002F\")) |\n    \"\\(.time) \\(.request.path) \\(.auth.display_name)\"' \\\n    \"$AUDIT_LOG\" | tail -100\n\n# Detect unusual credential request patterns\necho \"\"\necho \"=== High-Volume Credential Consumers ===\"\njq -r 'select(.type == \"request\" and .request.path | startswith(\"database\u002Fcreds\u002F\")) |\n    .auth.display_name' \\\n    \"$AUDIT_LOG\" | sort | uniq -c | sort -rn | head -10\n\n# Check for failed authentication attempts\necho \"\"\necho \"=== Failed Auth Attempts ===\"\njq -r 'select(.type == \"response\" and .error != null and\n    .request.path | startswith(\"auth\u002F\")) |\n    \"\\(.time) \\(.request.path) \\(.error)\"' \\\n    \"$AUDIT_LOG\" | tail -20\nSCRIPT\nchmod +x vault_audit_monitor.sh\n```\n\n## Key Concepts\n\n| Term | Definition |\n|------|------------|\n| **Dynamic Secrets** | Credentials generated on-demand by Vault with automatic expiration, ensuring each consumer receives unique short-lived credentials |\n| **Lease** | Time-bound agreement where Vault guarantees the credential is valid; consumers must renew before expiration or request new credentials |\n| **Secrets Engine** | Vault plugin that generates, stores, or encrypts data; database, AWS, PKI, and KV are common engines |\n| **AppRole** | Vault authentication method designed for machine-to-machine authentication using role ID and secret ID pairs |\n| **Root Credential Rotation** | Process of having Vault take exclusive ownership of the admin credential used to create dynamic secrets, eliminating human knowledge of the root password |\n| **Lease Revocation** | Immediate invalidation of dynamic credentials, used during incident response to revoke all credentials for compromised paths |\n\n## Tools & Systems\n\n- **HashiCorp Vault**: Secrets management platform providing dynamic secrets, encryption as a service, and identity-based access control\n- **Vault Agent**: Sidecar process that handles Vault authentication, token renewal, and secret caching for applications\n- **Vault Secrets Operator**: Kubernetes operator that syncs Vault secrets into Kubernetes Secrets for pod consumption\n- **hvac**: Python client library for HashiCorp Vault API operations\n\n## Common Scenarios\n\n### Scenario: Eliminating Static Database Credentials in Microservices\n\n**Context**: 50 microservices share 3 static PostgreSQL credentials stored in environment variables across Kubernetes deployments. A credential leak requires rotating all 50 services simultaneously.\n\n**Approach**:\n1. Deploy Vault with Raft storage in a 3-node HA cluster within Kubernetes\n2. Configure database secrets engine with PostgreSQL connection using admin credentials\n3. Create per-service Vault roles with least-privilege SQL grants\n4. Deploy Vault Secrets Operator to inject dynamic credentials into pod environment variables\n5. Update application connection logic to handle credential rotation via lease renewal\n6. Rotate the Vault root credential to remove human knowledge of the admin password\n7. Monitor lease lifecycle and set alerts for renewal failures\n\n**Pitfalls**:\n- Not handling credential rotation in application connection pools (connections using expired credentials fail)\n- Setting TTLs too short causes excessive credential generation load on the database\n- Not configuring proper revocation statements leaves orphaned database users after lease expiration\n- Running Vault without HA causes single point of failure for all application authentication\n\n## Output Format\n\n```\nHASHICORP VAULT DYNAMIC SECRETS REPORT\n=========================================\nVault Version:     1.16.2 Enterprise\nCluster Status:    HA Active (3 nodes)\nSeal Type:         AWS KMS (auto-unseal)\n\nSECRETS ENGINES\ndatabase\u002F:         PostgreSQL, MySQL (2 connections)\naws\u002F:              IAM User, Assumed Role, Federation Token\npki_int\u002F:          Internal CA (EC P-256)\n\nDYNAMIC CREDENTIAL METRICS (Last 24 Hours)\nTotal Credentials Generated:    4,287\n  Database (PostgreSQL):        2,891\n  Database (MySQL):             543\n  AWS STS:                      612\n  PKI Certificates:             241\n\nACTIVE LEASES\nTotal Active:                   387\n  database\u002Fcreds\u002Fapp-readonly:  198\n  database\u002Fcreds\u002Fapp-readwrite: 89\n  aws\u002Fcreds\u002Fs3-readonly:        67\n  pki_int\u002Fissue\u002Fweb-server:     33\n\nLEASE LIFECYCLE\nAverage TTL:                    45 minutes\nRenewals (24h):                 12,847\nRevocations (24h):              3,901\nExpired (not renewed):          12\n\nSECURITY\nFailed Auth Attempts (24h):     3\nRoot Credential Rotated:        YES (all databases)\nAudit Logging:                  ENABLED (file + syslog)\nPolicy Violations (24h):        7 (permission denied)\n```\n",{"name":5,"tags":52,"author":54,"domain":37,"license":15,"version":55,"mitre_f3":56,"nist_csf":83,"subdomain":88,"description":89,"mitre_attack":90},[33,32,31,30,29,53],"PKI","mahipal","1.0",{"tactics":57,"version":61,"techniques":62},[35,58,59,60],"positioning","stealth","resource-development","1.1",[63,67,70,74,77,80],{"id":64,"name":65,"source":66,"tactic":35},"F1006.001","Account Takeover: Exposed API Key","f3",{"id":68,"name":69,"source":66,"tactic":35},"F1006.002","Account Takeover: Exposed Login Credential",{"id":71,"name":72,"source":73,"tactic":60},"T1586","Compromise Accounts","attack",{"id":75,"name":76,"source":73,"tactic":39},"T1555","Credentials from Password Stores",{"id":78,"name":79,"source":66,"tactic":58},"F1005.004","Account Manipulation: Change Account Details",{"id":81,"name":82,"source":66,"tactic":35},"F1033","Insider Access Abuse",[84,85,86,87],"PR.AA-01","PR.AA-02","PR.AA-05","PR.AA-06","identity-access-management","Configures HashiCorp Vault dynamic secrets engines for database credentials, AWS IAM keys, and PKI certificates, with automatic generation, lease management, and rotation to eliminate static secrets in application configuration. Use when eliminating long-lived static credentials, configuring a Vault secrets engine, generating ephemeral database or cloud credentials, or automating credential rotation for compliance (PCI-DSS, NIST 800-53 IA-5).\n",[91,92,93,94,95],"T1078","T1110","T1556","T1098","T1003","main","54a798831d2266a3ca61ce68a7acb80b81160d57","skills\u002Fimplementing-hashicorp-vault-dynamic-secrets",4395,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills","https:\u002F\u002Fmahipal.engineer\u002FAnthropic-Cybersecurity-Skills\u002F","https:\u002F\u002Fgithub.com\u002Fmukul975","Mahipal.engineer","🔐 Cybersecurity | 💻 Dev | 📷 Street Photographer\r\n🎓 MSc | 📚 Research & AI Security","2026-08-31 12:32:44",{"source":8,"skillName":5,"commands":107,"prompt":117,"zipAvailable":118},[108,111,114],{"tool":109,"command":110},"npx","npx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill implementing-hashicorp-vault-dynamic-secrets",{"tool":112,"command":113},"bunx","bunx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill implementing-hashicorp-vault-dynamic-secrets",{"tool":115,"command":116},"pnpm","pnpm dlx skills add mukul975\u002FAnthropic-Cybersecurity-Skills --skill implementing-hashicorp-vault-dynamic-secrets","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fimplementing-hashicorp-vault-dynamic-secrets\u002FSKILL.md",true,[120,125,131],{"path":121,"resourceType":121,"resourceTypeDesc":122,"sizeBytes":123,"sourceHtmlUrl":124},"LICENSE","许可证",11255,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fimplementing-hashicorp-vault-dynamic-secrets\u002FLICENSE",{"path":126,"resourceType":127,"resourceTypeDesc":128,"sizeBytes":129,"sourceHtmlUrl":130},"references\u002Fapi-reference.md","REFERENCE","参考文档",2591,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fimplementing-hashicorp-vault-dynamic-secrets\u002Freferences\u002Fapi-reference.md",{"path":132,"resourceType":133,"resourceTypeDesc":134,"sizeBytes":135,"sourceHtmlUrl":136},"scripts\u002Fagent.py","SCRIPT","脚本",8828,"https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fimplementing-hashicorp-vault-dynamic-secrets\u002Fscripts\u002Fagent.py",[138,163,187,214,240,267],{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":145,"publishedAt":47},"01M6AGDM3HJXTKXX15ZZ0ZVCJ3","verifying-build-provenance-with-slsa-sigstore","Verifies artifact signatures and SLSA provenance using Sigstore's cosign (verify, verify-attestation, verify-blob-attestation) and slsa-verifier (verify-artifact), enforcing keyless OIDC builder identity and source repo against SLSA Build levels. Use in CI\u002FCD before deploying artifacts, when consuming third-party attestations, establishing a SLSA Build L3 pipeline, or confirming provenance during incident response or admission control.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fverifying-build-provenance-with-slsa-sigstore\u002FSKILL.md",[144],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[146,147,148,149,150,37,151,45,44,152,153,154,155,156,157,158,159,160,161,162],"sigstore","provenance","slsa","verifying build provenance with slsa sigstore","security","incident response","code","artifacts","ci","supply-chain","pipeline","supply-chain-security","t1195","attestation","code-signing","cosign","keyless",{"skillNo":164,"name":165,"nameZh":6,"description":166,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":167,"categories":168,"keywords":170,"publishedAt":47},"01M6AGDGBPWYVZ2F11GFKJ4HZ9","validating-tpm-measured-boot-attestation","Verifies TPM 2.0 measured-boot integrity and remote attestation with tpm2-tools -- reading PCRs (tpm2_pcrread), replaying the boot event log, generating and checking signed quotes (tpm2_quote\u002Ftpm2_checkquote), and sealing secrets to a PCR policy. Use to confirm a system booted trusted firmware\u002Fkernel for Zero Trust device posture, detect boot-chain tampering via PCR drift, or build a golden-value baseline for fleet attestation.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-tpm-measured-boot-attestation\u002FSKILL.md",[169],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[171,159,172,173,150,174,37,44,175,176,177,178,179,180,181,182,183,184,185,186],"boot","TPM","validating tpm measured boot attestation","policy","verification","ZeRO","firmware","Tools","measured-boot","PCR","integrity","secrets","remote-attestation","tpm2-tools","integrity-verification","trusted-computing",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":191,"categories":192,"keywords":197,"publishedAt":47},"01M6AGDCW0Y4FXZ3362GT1941M","validating-backup-integrity-for-recovery","Validates backup integrity through cryptographic hash verification, automated restore testing, corruption detection, and recoverability checks to confirm backups are reliable for disaster recovery and ransomware response. Use before relying on backups for recovery, when building post-backup validation pipelines, auditing backup infrastructure for compliance, or checking immutable\u002Fair-gapped backups for silent corruption or tampering.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fvalidating-backup-integrity-for-recovery\u002FSKILL.md",[193,196],{"categoryNo":194,"categoryName":195,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[181,198,199,200,201,37,202,203,175,204,205,206,207,208,209,36,210,211,212,213],"backup","recovery","validating backup integrity for recovery","testing","infrastructure","validation","compliance","hash-verification","incident-response","ransomware","cryptocurrency","detection","t1490","immutable","disaster-recovery","restore-testing",{"skillNo":215,"name":216,"nameZh":6,"description":217,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":218,"categories":219,"keywords":221,"publishedAt":47},"01M6AGD9GBG2KZ336AE763J3WH","triaging-windows-with-kape","Runs KAPE (Kroll Artifact Parser and Extractor) to collect targeted forensic artifacts (registry hives, $MFT, event logs, prefetch, browser data) via Targets and parse them with Modules wrapping Eric Zimmerman's EZ Tools (PECmd, MFTECmd, RECmd). Use during early incident containment\u002Ftriage when full disk imaging is impractical but a defensible, parseable Windows artifact set is needed quickly, including at-scale remote collection.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-windows-with-kape\u002FSKILL.md",[220],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[222,223,224,37,225,226,227,228,229,230,231,232,233,234,235,236,178,237,238,239],"windows","kape","triaging windows with kape","registry","browser","logs","windows-forensics","dfir","mft","mftecmd","data","prefetch","eric-zimmerman","digital-forensics","SET","collection","pecmd","artifact-collection",{"skillNo":241,"name":242,"nameZh":6,"description":243,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":244,"categories":245,"keywords":247,"publishedAt":47},"01M6AGD5PW5J4EVZM958WD74ZQ","triaging-vulnerabilities-with-ssvc-framework","Triages and prioritizes vulnerabilities with CISA's Stakeholder-Specific Vulnerability Categorization (SSVC) decision tree, weighing exploitation status (via the CISA KEV catalog and FIRST EPSS API), technical impact, automatability, and mission prevalence to output Track\u002FTrack*\u002FAttend\u002FAct decisions. Use when prioritizing vulnerability scan results (OpenVAS, Nessus, Qualys) for remediation planning beyond raw CVSS scores.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-vulnerabilities-with-ssvc-framework\u002FSKILL.md",[246],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[248,249,250,37,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266],"vulnerabilities","framework","triaging vulnerabilities with ssvc framework","status","planning","CISA","vulnerability-management","risk-management","nessus","qualys","openvas","cvss","remediation","risk","vulnerability","api","prioritization","ssvc","decision-tree",{"skillNo":268,"name":269,"nameZh":6,"description":270,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":271,"categories":272,"keywords":274,"publishedAt":47},"01M6AGD24TTQQM4CXG69E3B9TJ","triaging-security-incident","Performs initial triage of security incidents using the NIST SP 800-61r3 and SANS PICERL frameworks, classifying incident type, assigning priority by business impact, and routing to the appropriate response team. Use when a SIEM\u002FEDR alert needs human classification, concurrent alerts must be prioritized, or a user report or threat-intel IOC match requires initial incident categorization.","https:\u002F\u002Fgithub.com\u002Fmukul975\u002FAnthropic-Cybersecurity-Skills\u002Fblob\u002Fmain\u002Fskills\u002Ftriaging-security-incident\u002FSKILL.md",[273],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[150,275,37,276,277,278,279,280,40,281,282,36,283,210,284,285,286,287,288,289],"triaging security incident","siem","file","ioc","soc","NIST-800-61","severity","edr","execution","analysis","classification","severity-classification","incident-triage","SANS-PICERL","SOC-operations"]