diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 6aca4cb..ff25b70 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -72,6 +72,84 @@ "category": "integration", "license": "MPL-2.0", "strict": false + }, + { + "name": "vault-credential-generation", + "source": "./vault/credential-generation", + "description": "Generate dynamic credentials for databases, cloud providers, and encryption keys.", + "version": "0.2.0", + "author": { + "name": "HashiCorp" + }, + "keywords": ["vault", "secrets", "credentials", "database", "transit", "pki", "vault-agent", "dynamic-credentials"], + "category": "integration", + "license": "MPL-2.0", + "strict": false + }, + { + "name": "vault-app-access", + "source": "./vault/app-access", + "description": "Give applications secure access to Vault secrets with authentication and policies.", + "version": "0.2.0", + "author": { + "name": "HashiCorp" + }, + "keywords": ["vault", "auth", "authentication", "access", "approle", "kubernetes", "oidc", "policies"], + "category": "integration", + "license": "MPL-2.0", + "strict": false + }, + { + "name": "vault-deployment", + "source": "./vault/deployment", + "description": "Deploy and operate Vault on Kubernetes with HA, DR, and monitoring.", + "version": "0.2.0", + "author": { + "name": "HashiCorp" + }, + "keywords": ["vault", "deployment", "kubernetes", "vso", "ha", "dr", "monitoring", "troubleshooting"], + "category": "integration", + "license": "MPL-2.0", + "strict": false + }, + { + "name": "vault-multi-tenancy", + "source": "./vault/multi-tenancy", + "description": "Set up multi-tenant Vault with namespaces, replication, and policy-as-code.", + "version": "0.2.0", + "author": { + "name": "HashiCorp" + }, + "keywords": ["vault", "enterprise", "multi-tenancy", "namespaces", "replication", "sentinel", "mfa", "hsm"], + "category": "integration", + "license": "MPL-2.0", + "strict": false + }, + { + "name": "vault-ai-workflows", + "source": "./vault/ai-workflows", + "description": "Use AI assistants to manage Vault secrets through MCP integration.", + "version": "0.2.0", + "author": { + "name": "HashiCorp" + }, + "keywords": ["vault", "mcp", "ai", "workflows", "claude", "secrets", "automation"], + "category": "integration", + "license": "MPL-2.0", + "strict": false + }, + { + "name": "vault-hashicorp-secrets-engines", + "source": "./vault/hashicorp-secrets-engines", + "description": "Vault secrets engines for HashiCorp products (Consul, Nomad, Terraform Cloud).", + "version": "0.2.0", + "author": { + "name": "HashiCorp" + }, + "keywords": ["vault", "consul", "nomad", "terraform", "secrets-engines", "acl-tokens", "dynamic-tokens"], + "category": "integration", + "license": "MPL-2.0", + "strict": false } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index ece1f01..2598384 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,42 @@ All notable changes to the HashiCorp Agent Skills. ## Unreleased +### Changed +- Renamed Vault plugins to job-oriented names following Terraform/Packer pattern: + - `vault-secrets-management` → `vault-credential-generation` + - `vault-authentication` → `vault-app-access` + - `vault-operations` → `vault-deployment` + - `vault-enterprise` → `vault-multi-tenancy` + - `vault-mcp-integration` → `vault-ai-workflows` + - `vault-hashicorp-secrets-engines` → was `vault-hashicorp-integrations` +- Transformed all 16 Vault skills to include "What Are You Trying to Solve?" decision frameworks +- Updated skill headers with problem-oriented navigation (jump links) +- Added mental model sections explaining how each Vault component works +- Added decision tables mapping user problems to solutions + ### Added - `terraform-search-import` skill for discovering existing resources with Terraform Search and bulk import +- Vault product with 6 plugins and 16 skills + - `vault-credential-generation`: secrets-engines, vault-agent + - `vault-app-access`: auth-methods, policies, token-management, identity-system, response-wrapping + - `vault-deployment`: kubernetes-integration, production-operations, troubleshooting + - `vault-multi-tenancy`: enterprise-features (namespaces, replication, Sentinel, MFA, HSM) + - `vault-ai-workflows`: vault-mcp-server, mcp-secrets-workflows + - `vault-hashicorp-secrets-engines`: consul-secrets, nomad-secrets, terraform-cloud-secrets +- Token management, identity system, and response wrapping skills for authentication workflows +- HashiCorp product integration skills for Consul, Nomad, and Terraform Cloud/Enterprise +- Vault Enterprise skills for multi-tenancy, replication, and policy-as-code +- Vault MCP Server integration skills for AI-assisted secrets management +- Enhanced SPEC.md files with comprehensive user stories and functional requirements +- Vault MCP Server integration for all Vault plugins +- Product template system in `examples/` directory + - `examples/README.md` - Comprehensive guide for adding products, plugins, and skills + - `examples/spec.md` - Spec-Kit format specification with user stories + - `examples/questionnaire.md` - Questions reference for automation + - `examples/new-product-template/` - Template files with placeholders + - `examples/commands/new-product/` - `/new-product` slash command for interactive scaffolding +- `CONTRIBUTING.md` - Contribution guidelines +- 11 Claude Code plugins with 29 total skills ## 0.1.0 diff --git a/README.md b/README.md index a5ae88e..54ee476 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ A collection of Agent skills and Claude Code plugins for HashiCorp products. |:--------|:----------| | [Terraform](./terraform/) | Write HCL code, build modules, develop providers, and run tests | | [Packer](./packer/) | Build machine images on AWS, Azure, and Windows; integrate with HCP Packer registry | +| [Vault](./vault/) | Manage secrets, configure authentication, operate clusters, and integrate with AI assistants | > **Legal Note:** Your use of a third party MCP Client/LLM is subject solely to the terms of use for such MCP/LLM, and IBM is not responsible for the performance of such third party tools. IBM expressly disclaims any and all warranties and liability for third party MCP Clients/LLMs, and may not be able to provide support to resolve issues which are caused by the third party tools. @@ -37,6 +38,12 @@ claude plugin install terraform-module-generation@hashicorp claude plugin install terraform-provider-development@hashicorp claude plugin install packer-builders@hashicorp claude plugin install packer-hcp@hashicorp +claude plugin install vault-secrets-management@hashicorp +claude plugin install vault-authentication@hashicorp +claude plugin install vault-operations@hashicorp +claude plugin install vault-enterprise@hashicorp +claude plugin install vault-mcp-integration@hashicorp +claude plugin install vault-hashicorp-integrations@hashicorp ``` Or use the interactive interface: @@ -52,7 +59,7 @@ agent-skills/ │ └── marketplace.json ├── terraform/ # Terraform skills ├── packer/ # Packer skills -├── / # Future products (Vault, Consul, etc.) +├── vault/ # Vault skills └── README.md ``` diff --git a/vault/README.md b/vault/README.md new file mode 100644 index 0000000..b76c0fb --- /dev/null +++ b/vault/README.md @@ -0,0 +1,125 @@ +# HashiCorp Vault Agent Skills + +Agent skills for HashiCorp Vault identity-based secrets and encryption management. + +## Overview + +Vault secures, stores, and tightly controls access to tokens, passwords, certificates, encryption keys, and other sensitive data. These skills provide AI-assisted guidance organized around **jobs to be done**—the problems you're actually trying to solve. + +## Available Plugins + +| Plugin | Job to Be Done | Skills | +|--------|----------------|--------| +| [vault-credential-generation](credential-generation/) | Generate dynamic credentials for my app | `secrets-engines`, `vault-agent` | +| [vault-app-access](app-access/) | Give my app secure access to Vault | `auth-methods`, `policies`, `token-management`, `identity-system`, `response-wrapping` | +| [vault-deployment](deployment/) | Deploy and operate Vault | `kubernetes-integration`, `production-operations`, `troubleshooting` | +| [vault-multi-tenancy](multi-tenancy/) | Set up multi-tenant Vault | `enterprise-features` | +| [vault-ai-workflows](ai-workflows/) | Use AI to manage secrets | `vault-mcp-server`, `mcp-secrets-workflows` | +| [vault-hashicorp-secrets-engines](hashicorp-secrets-engines/) | Secrets engines for Consul, Nomad, TFC | `consul-secrets`, `nomad-secrets`, `terraform-cloud-secrets` | + +## Installation + +### Install All Vault Plugins + +```bash +claude plugin install vault-credential-generation@hashicorp +claude plugin install vault-app-access@hashicorp +claude plugin install vault-deployment@hashicorp +claude plugin install vault-multi-tenancy@hashicorp +claude plugin install vault-ai-workflows@hashicorp +claude plugin install vault-hashicorp-secrets-engines@hashicorp +``` + +### Install Individual Skills + +```bash +# Credential generation +npx skills add hashicorp/agent-skills/vault/credential-generation/skills/secrets-engines +npx skills add hashicorp/agent-skills/vault/credential-generation/skills/vault-agent + +# App access (authentication, identity, and tokens) +npx skills add hashicorp/agent-skills/vault/app-access/skills/auth-methods +npx skills add hashicorp/agent-skills/vault/app-access/skills/policies +npx skills add hashicorp/agent-skills/vault/app-access/skills/token-management +npx skills add hashicorp/agent-skills/vault/app-access/skills/identity-system +npx skills add hashicorp/agent-skills/vault/app-access/skills/response-wrapping + +# Deployment (operations) +npx skills add hashicorp/agent-skills/vault/deployment/skills/kubernetes-integration +npx skills add hashicorp/agent-skills/vault/deployment/skills/production-operations +npx skills add hashicorp/agent-skills/vault/deployment/skills/troubleshooting + +# Multi-tenancy (enterprise) +npx skills add hashicorp/agent-skills/vault/multi-tenancy/skills/enterprise-features + +# AI workflows (MCP integration) +npx skills add hashicorp/agent-skills/vault/ai-workflows/skills/vault-mcp-server +npx skills add hashicorp/agent-skills/vault/ai-workflows/skills/mcp-secrets-workflows + +# HashiCorp secrets engines +npx skills add hashicorp/agent-skills/vault/hashicorp-secrets-engines/skills/consul-secrets +npx skills add hashicorp/agent-skills/vault/hashicorp-secrets-engines/skills/nomad-secrets +npx skills add hashicorp/agent-skills/vault/hashicorp-secrets-engines/skills/terraform-cloud-secrets +``` + +## MCP Server Integration + +All Vault plugins include configuration for the [Vault MCP Server](https://github.com/hashicorp/vault-mcp-server): + +```bash +export VAULT_ADDR="https://vault.example.com:8200" +export VAULT_TOKEN="hvs.xxxxx" +export VAULT_NAMESPACE="admin" # Optional, for Enterprise +``` + +The MCP server enables Claude and other AI assistants to interact directly with Vault: +- Create and manage secrets engine mounts +- Read, write, and list secrets +- Manage KV v1 and v2 secrets + +See [vault-ai-workflows](ai-workflows/) for setup and usage patterns. + +## Plugin Overview + +### Core Vault Skills + +- **secrets-engines**: KV, Database, AWS, Transit, PKI, SSH engines +- **vault-agent**: Auto-auth, caching, templating, sidecar patterns + +### Authentication and Identity Skills + +- **auth-methods**: AppRole, Kubernetes, OIDC, AWS, Azure, GCP, LDAP +- **policies**: HCL syntax, templated policies, CI/CD patterns +- **token-management**: Service, batch, periodic, orphan tokens, accessors +- **identity-system**: Entities, aliases, groups, OIDC provider +- **response-wrapping**: Cubbyhole, wrapped tokens, secure secret distribution + +### Operations Skills + +- **kubernetes-integration**: VSO, Agent Injector, CSI Provider +- **production-operations**: HA, DR, monitoring, backup, upgrades +- **troubleshooting**: Diagnostics, debugging, anti-patterns + +### Enterprise Skills (requires Vault Enterprise license) + +- **enterprise-features**: Namespaces, replication, Sentinel, MFA, HSM + +### MCP Integration Skills + +- **vault-mcp-server**: Installation, configuration, IDE integration +- **mcp-secrets-workflows**: Tool usage patterns for AI workflows + +### HashiCorp Integration Skills + +- **consul-secrets**: Dynamic Consul ACL tokens +- **nomad-secrets**: Dynamic Nomad ACL tokens +- **terraform-cloud-secrets**: Dynamic Terraform Cloud/Enterprise API tokens + +## Documentation + +- [Vault Documentation](https://developer.hashicorp.com/vault) +- [Vault Enterprise](https://developer.hashicorp.com/vault/docs/enterprise) +- [Vault API Reference](https://developer.hashicorp.com/vault/api-docs) +- [Vault Tutorials](https://developer.hashicorp.com/vault/tutorials) +- [Vault MCP Server](https://github.com/hashicorp/vault-mcp-server) +- [HCP Vault](https://developer.hashicorp.com/hcp/docs/vault) diff --git a/vault/ai-workflows/.claude-plugin/plugin.json b/vault/ai-workflows/.claude-plugin/plugin.json new file mode 100644 index 0000000..0f327b8 --- /dev/null +++ b/vault/ai-workflows/.claude-plugin/plugin.json @@ -0,0 +1,40 @@ +{ + "name": "vault-ai-workflows", + "version": "0.2.0", + "description": "Use AI assistants to manage Vault secrets. Covers Vault MCP Server installation, VS Code integration, and AI-assisted secrets management workflows.", + "author": "HashiCorp", + "homepage": "https://github.com/hashicorp/vault-mcp-server", + "repository": "https://github.com/hashicorp/agent-skills", + "license": "MPL-2.0", + "keywords": [ + "vault", + "mcp", + "ai", + "workflows", + "claude", + "secrets", + "automation" + ], + "mcpServers": { + "vault": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "-e", + "VAULT_ADDR", + "-e", + "VAULT_TOKEN", + "-e", + "VAULT_NAMESPACE", + "hashicorp/vault-mcp-server" + ], + "env": { + "VAULT_ADDR": "${VAULT_ADDR}", + "VAULT_TOKEN": "${VAULT_TOKEN}", + "VAULT_NAMESPACE": "${VAULT_NAMESPACE}" + } + } + } +} diff --git a/vault/ai-workflows/SPEC.md b/vault/ai-workflows/SPEC.md new file mode 100644 index 0000000..0bf16cd --- /dev/null +++ b/vault/ai-workflows/SPEC.md @@ -0,0 +1,117 @@ +# Specification: vault-ai-workflows + +**Status**: Published +**Version**: 0.2.0 + +--- + +## Overview + +This plugin helps you **use AI assistants to manage Vault secrets**. Covers the HashiCorp Vault MCP (Model Context Protocol) Server setup, VS Code and Claude Desktop integration, and common secrets management workflows using MCP tools. + +--- + +## User Stories + +### US-1: Developer Setting Up Vault MCP Server (P1) + +A developer wants to configure the Vault MCP Server so Claude or another AI assistant can help manage secrets in their development Vault instance. + +**Acceptance Criteria**: +1. Given a setup request, when the skill is invoked, then it provides Docker and from-source installation options. +2. Given a VS Code question, when asked about integration, then the skill provides mcp.json configuration. +3. Given a security question, when asked about production use, then the skill explains security considerations and CORS configuration. + +### US-2: Platform Engineer Configuring MCP for Team (P1) + +A platform engineer needs to configure the Vault MCP Server for team use with appropriate security controls. + +**Acceptance Criteria**: +1. Given a multi-user question, when the skill is invoked, then it explains rate limiting and session management. +2. Given a transport question, when asked about stdio vs HTTP, then the skill provides trade-offs for each mode. +3. Given a TLS question, when asked about secure connections, then the skill provides certificate configuration. + +### US-3: Developer Managing Secrets via MCP (P1) + +A developer wants to use Claude with the Vault MCP Server to create, read, and manage secrets in a KV secrets engine. + +**Acceptance Criteria**: +1. Given a KV management request, when the skill is invoked, then it provides workflow patterns for create_mount, write_secret, read_secret. +2. Given a listing question, when asked how to explore secrets, then the skill shows list_mounts and list_secrets patterns. +3. Given a cleanup question, when asked about deletion, then the skill explains delete_secret and delete_mount usage. + +### US-4: DevOps Engineer Automating Mount Management (P2) + +A DevOps engineer wants to use AI-assisted workflows to create and configure secrets engine mounts. + +**Acceptance Criteria**: +1. Given a mount creation request, when the skill is invoked, then it provides create_mount patterns for KV v1/v2. +2. Given a mount listing question, when asked about discovery, then the skill shows list_mounts usage. +3. Given a cleanup question, when asked about mount removal, then the skill explains delete_mount with warnings. + +--- + +## Functional Requirements + +| ID | Requirement | +|----|-------------| +| FR-001 | Skill MUST cover Vault MCP Server installation (Docker, source) | +| FR-002 | Skill MUST explain transport modes (stdio, StreamableHTTP) | +| FR-003 | Skill MUST cover environment variables (VAULT_ADDR, VAULT_TOKEN, VAULT_NAMESPACE) | +| FR-004 | Skill MUST include VS Code/Claude Desktop integration | +| FR-005 | Skill MUST cover rate limiting configuration | +| FR-006 | Skill MUST explain CORS and security considerations | +| FR-007 | Skill MUST cover all MCP tools: create_mount, list_mounts, delete_mount | +| FR-008 | Skill MUST cover all MCP tools: write_secret, read_secret, list_secrets, delete_secret | +| FR-009 | Skill MUST include example workflows for common tasks | +| FR-010 | Skill MUST differentiate KV v1 vs v2 patterns with MCP | + +--- + +## Skills Included + +| Skill | Description | +|-------|-------------| +| `vault-mcp-server` | Install and configure the Vault MCP Server | +| `mcp-secrets-workflows` | Use MCP tools for secrets management workflows | + +--- + +## MCP Tools Reference + +### Mount Management Tools + +| Tool | Parameters | Description | +|------|------------|-------------| +| `create_mount` | type, path, description | Create KV v1, KV v2, or PKI mount | +| `list_mounts` | (none) | List all mounts in Vault | +| `delete_mount` | path | Delete a mount | + +### Key-Value Tools + +| Tool | Parameters | Description | +|------|------------|-------------| +| `write_secret` | mount, path, key, value | Write a secret to KV mount | +| `read_secret` | mount, path | Read a secret from KV mount | +| `list_secrets` | mount, path | List secrets under a path | +| `delete_secret` | mount, path, key (optional) | Delete secret or specific key | + +--- + +## Non-Functional Requirements + +### NFR-1: Security Awareness + +Skills MUST include security notes about not using MCP server with untrusted clients or LLMs. + +### NFR-2: Local-Only Recommendation + +Skills MUST note the MCP server is intended for local development use at this stage. + +--- + +## References + +- [Vault MCP Server GitHub](https://github.com/hashicorp/vault-mcp-server) +- [Model Context Protocol](https://modelcontextprotocol.io/introduction) +- [VS Code MCP Integration](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) diff --git a/vault/ai-workflows/skills/mcp-secrets-workflows/SKILL.md b/vault/ai-workflows/skills/mcp-secrets-workflows/SKILL.md new file mode 100644 index 0000000..5ffcf73 --- /dev/null +++ b/vault/ai-workflows/skills/mcp-secrets-workflows/SKILL.md @@ -0,0 +1,88 @@ +--- +name: mcp-secrets-workflows +description: Use Vault MCP Server tools for secrets workflows. Use when asked to create mounts, read/write KV secrets, list existing secrets, rotate values, or clean up deprecated paths through an AI assistant. Covers create_mount, list_mounts, write_secret, read_secret, list_secrets, delete_secret, and delete_mount. +--- + +# MCP Secrets Workflows + +## What Are You Trying to Solve? + +### "I need a new secrets mount for an app" +Use `create_mount`, then verify with `list_mounts`. + +### "I need to store or retrieve secrets" +Use `write_secret`, `read_secret`, and `list_secrets`. + +### "I need to rotate a credential safely" +Use read -> write -> verify sequence. + +### "I need to remove deprecated secrets" +Use explicit pre-delete checks before `delete_secret` or `delete_mount`. + +## Quick Tool Map + +| Goal | Primary tools | +|------|---------------| +| Create mount | `create_mount`, `list_mounts` | +| Read/write values | `write_secret`, `read_secret` | +| Discover paths | `list_secrets`, `list_mounts` | +| Rotate value | `read_secret`, `write_secret`, `read_secret` | +| Delete key/path | `delete_secret` | +| Delete entire mount | `delete_mount` | + +## Workflow Patterns + +### Pattern 1: Bootstrap New App Secrets + +1. Create mount: `create_mount(type=kv2, path=)` +2. Write initial values with `write_secret` +3. Verify written paths with `list_secrets` + +Use `kv2` by default for versioning and recovery options. + +### Pattern 2: Audit Existing Secrets + +1. Enumerate mounts with `list_mounts` +2. Enumerate paths with `list_secrets` +3. Read selected paths with `read_secret` + +Prefer listing before reading to avoid guessing paths. + +### Pattern 3: Rotate a Secret + +1. Read current secret (`read_secret`) to confirm path and key names +2. Write new value (`write_secret`) +3. Re-read (`read_secret`) to verify update + +For production rotation, coordinate with downstream consumers before write. + +### Pattern 4: Cleanup Deprecated Secrets (Destructive) + +1. Verify target scope with `list_secrets` +2. Confirm no active consumers +3. Delete specific values (`delete_secret`) first +4. Delete mount (`delete_mount`) only when fully unused + +Do not run `delete_mount` until steps 1-3 are complete and acknowledged. + +## Safety Checklist for Destructive Operations + +Before `delete_secret` or `delete_mount`, confirm: + +- Target path is correct and explicitly listed +- Secret or mount is no longer used by applications or jobs +- Recovery plan exists (for KV v1, deletion is permanent) +- Caller explicitly approved deletion + +## Output Expectations + +When assisting users, return: + +- What changed (mount/path/key) +- What was verified +- Any follow-up action required by operators or apps + +## References + +- For full parameter tables, examples, and advanced scenarios, see [references/mcp-secrets-workflows.md](references/mcp-secrets-workflows.md) +- For MCP server setup and transport/security configuration, see [../vault-mcp-server/SKILL.md](../vault-mcp-server/SKILL.md) diff --git a/vault/ai-workflows/skills/mcp-secrets-workflows/references/mcp-secrets-workflows.md b/vault/ai-workflows/skills/mcp-secrets-workflows/references/mcp-secrets-workflows.md new file mode 100644 index 0000000..725dc04 --- /dev/null +++ b/vault/ai-workflows/skills/mcp-secrets-workflows/references/mcp-secrets-workflows.md @@ -0,0 +1,498 @@ +--- +name: mcp-secrets-workflows-reference +description: Detailed reference for Vault MCP Server tool usage patterns and common secrets management workflows +--- + +# MCP Secrets Workflows Reference + +This reference provides detailed patterns for using Vault MCP Server tools. + +--- + +## MCP Tools Reference + +### Mount Management Tools + +#### create_mount + +Creates a new secrets engine mount in Vault. + +**Parameters:** + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `type` | string | Yes | Mount type: `kv`, `kv2`, `pki` | +| `path` | string | Yes | Mount path (no leading/trailing slashes) | +| `description` | string | No | Human-readable description | + +**Examples:** + +``` +Create a KV v2 mount: + type: "kv2" + path: "myapp" + description: "Application secrets for MyApp" + +Create a KV v1 mount: + type: "kv" + path: "legacy-app" + +Create a PKI mount: + type: "pki" + path: "pki-internal" +``` + +**Notes:** +- Mount paths must be unique +- Cannot create mounts at reserved paths (sys/, auth/, etc.) +- Type `kv2` is recommended over `kv` for versioning + +--- + +#### list_mounts + +Lists all secrets engine mounts in Vault. + +**Parameters:** None + +**Response includes:** +- Mount path +- Type +- Description +- Configuration + +**Usage:** +``` +"What secrets engines are available?" +"List all mounts" +"Show me the secrets engines" +``` + +--- + +#### delete_mount + +Deletes a secrets engine mount. + +**Parameters:** + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `path` | string | Yes | Mount path to delete | + +**Warning:** This permanently deletes all secrets stored in the mount! + +**Examples:** + +``` +Delete a mount: + path: "old-app" +``` + +**Notes:** +- Requires appropriate permissions +- Cannot be undone +- All secrets in mount are permanently deleted + +--- + +### Key-Value Tools + +#### write_secret + +Writes a key-value pair to a secret path. + +**Parameters:** + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `mount` | string | Yes | Mount path | +| `path` | string | Yes | Secret path within mount | +| `key` | string | Yes | Key name | +| `value` | string | Yes | Value to store | + +**Examples:** + +``` +Write a single key: + mount: "myapp" + path: "config" + key: "api_key" + value: "sk_live_abc123" + +Write to nested path: + mount: "myapp" + path: "databases/postgres" + key: "password" + value: "secretpassword" +``` + +**Notes:** +- KV v2: Creates new version, preserves history +- KV v1: Overwrites existing value +- Multiple keys require multiple write_secret calls + +--- + +#### read_secret + +Reads a secret from a path. + +**Parameters:** + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `mount` | string | Yes | Mount path | +| `path` | string | Yes | Secret path within mount | + +**Examples:** + +``` +Read a secret: + mount: "myapp" + path: "config" + +Read nested path: + mount: "myapp" + path: "databases/postgres" +``` + +**Response includes:** +- All key-value pairs at the path +- Metadata (KV v2): version, created_time, etc. + +--- + +#### list_secrets + +Lists secret paths under a given path. + +**Parameters:** + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `mount` | string | Yes | Mount path | +| `path` | string | No | Path to list (defaults to root) | + +**Examples:** + +``` +List all secrets in mount: + mount: "myapp" + +List under specific path: + mount: "myapp" + path: "databases" +``` + +**Notes:** +- Returns paths, not secret values +- Paths ending with `/` are directories +- Useful for discovery + +--- + +#### delete_secret + +Deletes a secret or specific key. + +**Parameters:** + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `mount` | string | Yes | Mount path | +| `path` | string | Yes | Secret path | +| `key` | string | No | Specific key to delete | + +**Examples:** + +``` +Delete entire secret: + mount: "myapp" + path: "old-config" + +Delete specific key: + mount: "myapp" + path: "config" + key: "deprecated_key" +``` + +**Notes:** +- KV v2: Soft delete (can be undeleted via Vault CLI) +- KV v1: Permanent delete +- Without `key`: deletes entire secret +- With `key`: deletes only that key + +--- + +## Complete Workflow Examples + +### Example 1: New Application Setup + +Complete workflow for bootstrapping secrets for a new application. + +**Goal:** Set up secrets infrastructure for "payments-service" + +**Step-by-step:** + +``` +Step 1: Create dedicated mount + Tool: create_mount + Parameters: + type: "kv2" + path: "payments-service" + description: "Secrets for payments microservice" + +Step 2: Write database credentials + Tool: write_secret + Parameters: + mount: "payments-service" + path: "database/postgres" + key: "host" + value: "postgres.internal.example.com" + + Tool: write_secret + Parameters: + mount: "payments-service" + path: "database/postgres" + key: "username" + value: "payments_app" + + Tool: write_secret + Parameters: + mount: "payments-service" + path: "database/postgres" + key: "password" + value: "generated-secure-password" + +Step 3: Write API keys + Tool: write_secret + Parameters: + mount: "payments-service" + path: "integrations/stripe" + key: "secret_key" + value: "sk_live_xxx" + + Tool: write_secret + Parameters: + mount: "payments-service" + path: "integrations/stripe" + key: "webhook_secret" + value: "whsec_xxx" + +Step 4: Verify setup + Tool: list_secrets + Parameters: + mount: "payments-service" +``` + +--- + +### Example 2: Secret Rotation + +Update existing secrets while maintaining audit trail. + +**Goal:** Rotate database password for an application + +**Step-by-step:** + +``` +Step 1: Read current secret (verify path) + Tool: read_secret + Parameters: + mount: "myapp" + path: "database" + +Step 2: Write new password (KV v2 creates new version) + Tool: write_secret + Parameters: + mount: "myapp" + path: "database" + key: "password" + value: "new-secure-password-2024" + +Step 3: Verify update + Tool: read_secret + Parameters: + mount: "myapp" + path: "database" +``` + +**Note:** Previous version remains accessible via Vault CLI for rollback. + +--- + +### Example 3: Secrets Discovery and Audit + +Explore existing secrets structure. + +**Goal:** Understand what secrets exist in a mount + +**Step-by-step:** + +``` +Step 1: List all mounts + Tool: list_mounts + +Step 2: List top-level secrets + Tool: list_secrets + Parameters: + mount: "myapp" + +Step 3: Explore subdirectories + Tool: list_secrets + Parameters: + mount: "myapp" + path: "databases" + +Step 4: Read specific secrets + Tool: read_secret + Parameters: + mount: "myapp" + path: "databases/postgres" +``` + +--- + +### Example 4: Cleanup Deprecated Secrets + +Remove old secrets systematically. + +**Goal:** Clean up secrets for decommissioned application + +**Step-by-step:** + +``` +Step 1: Audit existing secrets + Tool: list_secrets + Parameters: + mount: "old-app" + +Step 2: Document secrets (for backup purposes) + Tool: read_secret (for each path) + +Step 3: Delete individual secrets + Tool: delete_secret + Parameters: + mount: "old-app" + path: "config" + + Tool: delete_secret + Parameters: + mount: "old-app" + path: "database" + +Step 4: Delete the mount + Tool: delete_mount + Parameters: + path: "old-app" +``` + +**Warning:** Ensure secrets are no longer needed before deletion! + +--- + +## KV v1 vs KV v2 Behavior + +### Write Behavior + +| Aspect | KV v1 | KV v2 | +|--------|-------|-------| +| Write same path | Overwrites | Creates new version | +| History | None | Full version history | +| Rollback | Not possible | Restore previous version | + +### Delete Behavior + +| Aspect | KV v1 | KV v2 | +|--------|-------|-------| +| Default delete | Permanent | Soft delete | +| Recovery | Not possible | Undelete via CLI | +| Permanent delete | Same as delete | Requires "destroy" | + +### Path Differences + +``` +KV v1 API path: secret/myapp/config +KV v2 API path: secret/data/myapp/config + +MCP tools abstract this difference - use: + mount: "secret" + path: "myapp/config" +``` + +--- + +## Error Handling + +### Common Errors + +| Error | Cause | Solution | +|-------|-------|----------| +| "permission denied" | Token lacks policy | Update token policy | +| "no route to host" | Vault unreachable | Check VAULT_ADDR | +| "mount does not exist" | Invalid mount path | Use list_mounts to find | +| "secret not found" | Path doesn't exist | Use list_secrets to explore | + +### Required Policies + +```hcl +# Policy for full MCP access +path "sys/mounts" { + capabilities = ["read", "list"] +} + +path "sys/mounts/*" { + capabilities = ["create", "delete", "read", "list"] +} + +# For KV v2 secrets +path "+/data/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +path "+/metadata/*" { + capabilities = ["read", "list", "delete"] +} +``` + +--- + +## Best Practices + +### Security + +1. **Minimal permissions**: Use tokens with only required capabilities +2. **Sensitive awareness**: Remember LLM can see secret values +3. **Audit logging**: All operations are logged in Vault audit log +4. **Short TTLs**: Use short-lived tokens for MCP sessions + +### Organization + +1. **Consistent naming**: Use pattern like `app/environment/type` +2. **Logical grouping**: Group related secrets under same path +3. **Documentation**: Use mount descriptions for discoverability +4. **KV v2 preferred**: Enable versioning for recoverability + +### Workflow + +1. **Verify before delete**: Always list/read before deleting +2. **Test in dev**: Practice workflows in development first +3. **Backup sensitive**: Document critical secrets before changes +4. **Incremental changes**: Make small, verifiable changes + +--- + +## Additional Resources + +- [Vault MCP Server GitHub](https://github.com/hashicorp/vault-mcp-server) +- [KV Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/kv) +- [Vault Policies](https://developer.hashicorp.com/vault/docs/concepts/policies) + +--- + +## Related + +- [vault-mcp-server.md](../vault-mcp-server/references/vault-mcp-server.md) - MCP server configuration +- [secrets-engines.md](../../../secrets-management/skills/secrets-engines/references/secrets-engines.md) - Secrets engine configuration +- [policies.md](../../../authentication/skills/policies/references/policies.md) - Policy syntax diff --git a/vault/ai-workflows/skills/vault-mcp-server/SKILL.md b/vault/ai-workflows/skills/vault-mcp-server/SKILL.md new file mode 100644 index 0000000..ee34ccf --- /dev/null +++ b/vault/ai-workflows/skills/vault-mcp-server/SKILL.md @@ -0,0 +1,281 @@ +--- +name: vault-mcp-server +description: Install and configure the Vault MCP Server for AI-assisted secrets management. Use when asked about setting up MCP for Vault, configuring Claude or VS Code to use Vault, or integrating AI assistants with HashiCorp Vault. Covers Docker setup, transport modes, environment variables, and security configuration. +--- + +# Vault MCP Server + +## What Are You Trying to Solve? + +### "I want Claude or VS Code to manage Vault secrets" +→ Install **Vault MCP Server** via Docker. [Jump to Quick Start](#quick-start-docker) + +### "I need to configure VS Code for Vault integration" +→ Create **mcp.json** configuration. [Jump to VS Code Integration](#vs-code-integration) + +### "I want to run the server as an HTTP service" +→ Use **StreamableHTTP mode** with CORS. [Jump to HTTP Mode](#streamablehttp-mode) + +### "I'm having connection issues" +→ Check **Docker networking and token**. [Jump to Troubleshooting](#troubleshooting) + +--- + +## How Vault MCP Server Works + +1. **Start Server** → Run as Docker container or binary (stdio or HTTP mode) +2. **Connect Client** → Claude Desktop or VS Code connects via MCP protocol +3. **Authenticate** → Server uses provided VAULT_TOKEN for all operations +4. **AI Uses Tools** → AI can create mounts, read/write secrets, list paths + +**Key insight:** The MCP server proxies AI requests to Vault—AI gets Vault capabilities without direct API access. + +--- + +## Security Notes + +> **Warning**: The MCP server is intended for **local development use**. The server may expose Vault data to the connected MCP client and LLM. Do not use with untrusted MCP clients or LLMs. + +> **Important**: For HTTP mode, always configure `MCP_ALLOWED_ORIGINS` to prevent DNS rebinding attacks. + +--- + +## Reference + +- [Vault MCP Server GitHub](https://github.com/hashicorp/vault-mcp-server) +- [Detailed MCP Server Reference](references/vault-mcp-server.md) + +--- + +## Quick Start (Docker) + +```bash +# Start Vault MCP Server with Docker +docker run -i --rm \ + -e VAULT_ADDR='http://host.docker.internal:8200' \ + -e VAULT_TOKEN='' \ + hashicorp/vault-mcp-server +``` + +--- + +## Installation Options + +### Docker (Recommended) + +```bash +# Pull the official image +docker pull hashicorp/vault-mcp-server + +# Run in stdio mode (for Claude Desktop, VS Code) +docker run -i --rm \ + -e VAULT_ADDR='http://host.docker.internal:8200' \ + -e VAULT_TOKEN='' \ + -e VAULT_NAMESPACE='admin' \ + hashicorp/vault-mcp-server + +# Run in HTTP mode +docker run --rm -p 8080:8080 \ + -e VAULT_ADDR='http://vault:8200' \ + -e VAULT_TOKEN='' \ + -e TRANSPORT_MODE='http' \ + -e MCP_ALLOWED_ORIGINS='http://localhost:3000' \ + hashicorp/vault-mcp-server +``` + +### From Source + +```bash +git clone https://github.com/hashicorp/vault-mcp-server.git +cd vault-mcp-server + +# Build +make build + +# Run stdio mode +./vault-mcp-server + +# Run HTTP mode +./vault-mcp-server http --transport-port 8080 +``` + +--- + +## Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `VAULT_ADDR` | `http://127.0.0.1:8200` | Vault server address | +| `VAULT_TOKEN` | (required) | Vault authentication token | +| `VAULT_NAMESPACE` | (optional) | Vault Enterprise namespace | +| `TRANSPORT_MODE` | `stdio` | `stdio` or `http` | +| `TRANSPORT_HOST` | `127.0.0.1` | HTTP bind host | +| `TRANSPORT_PORT` | `8080` | HTTP bind port | +| `MCP_ENDPOINT` | `/mcp` | HTTP endpoint path | +| `MCP_ALLOWED_ORIGINS` | `""` | CORS allowed origins (comma-separated) | +| `MCP_CORS_MODE` | `strict` | `strict`, `development`, or `disabled` | +| `MCP_TLS_CERT_FILE` | `""` | TLS certificate path | +| `MCP_TLS_KEY_FILE` | `""` | TLS key path | +| `MCP_RATE_LIMIT_GLOBAL` | `10:20` | Global rate limit (rps:burst) | +| `MCP_RATE_LIMIT_SESSION` | `5:10` | Per-session rate limit (rps:burst) | + +--- + +## VS Code Integration + +Create `.vscode/mcp.json` in your workspace: + +### Stdio Mode (Recommended) + +```json +{ + "inputs": [ + { + "type": "promptString", + "id": "vault_addr", + "description": "Vault Address", + "password": false + }, + { + "type": "promptString", + "id": "vault_token", + "description": "Vault Token", + "password": true + } + ], + "servers": { + "vault-mcp-server": { + "command": "docker", + "args": [ + "run", "-i", "--rm", + "-e", "VAULT_ADDR=${input:vault_addr}", + "-e", "VAULT_TOKEN=${input:vault_token}", + "hashicorp/vault-mcp-server" + ] + } + } +} +``` + +### HTTP Mode + +```json +{ + "inputs": [ + { + "type": "promptString", + "id": "vault_token", + "description": "Vault Token", + "password": true + } + ], + "servers": { + "vault-mcp-server": { + "url": "http://localhost:8080/mcp?VAULT_ADDR=http://127.0.0.1:8200", + "headers": { + "X-Vault-Token": "${input:vault_token}" + } + } + } +} +``` + +--- + +## Transport Modes + +### Stdio Mode (Default) + +- Used by Claude Desktop, VS Code with Docker +- MCP server runs as subprocess +- Communication via stdin/stdout +- Best for local development + +### StreamableHTTP Mode + +- Server runs as HTTP service +- Multiple clients can connect +- Requires CORS configuration for security +- Use for shared development environments + +--- + +## Rate Limiting + +Control request rates to protect your Vault server: + +```bash +# Global: 10 requests/second, burst of 20 +# Session: 5 requests/second, burst of 10 +docker run -i --rm \ + -e VAULT_ADDR='http://vault:8200' \ + -e VAULT_TOKEN='' \ + -e MCP_RATE_LIMIT_GLOBAL='10:20' \ + -e MCP_RATE_LIMIT_SESSION='5:10' \ + hashicorp/vault-mcp-server +``` + +--- + +## TLS Configuration + +For secure HTTP transport: + +```bash +docker run --rm -p 8443:8443 \ + -v /path/to/certs:/certs:ro \ + -e TRANSPORT_MODE='http' \ + -e TRANSPORT_PORT='8443' \ + -e MCP_TLS_CERT_FILE='/certs/cert.pem' \ + -e MCP_TLS_KEY_FILE='/certs/key.pem' \ + hashicorp/vault-mcp-server +``` + +--- + +## Available MCP Tools + +Once connected, the following tools are available: + +| Tool | Description | +|------|-------------| +| `create_mount` | Create KV, KV v2, or PKI mount | +| `list_mounts` | List all mounts | +| `delete_mount` | Delete a mount | +| `write_secret` | Write secret to KV mount | +| `read_secret` | Read secret from KV mount | +| `list_secrets` | List secrets in path | +| `delete_secret` | Delete secret or key | + +For detailed tool usage patterns, see [mcp-secrets-workflows](../mcp-secrets-workflows/SKILL.md). + +--- + +## Troubleshooting + +### Connection Refused + +```bash +# Check Vault is accessible +curl $VAULT_ADDR/v1/sys/health + +# For Docker, use host.docker.internal (macOS/Windows) +# or --network=host (Linux) +docker run --network=host -i --rm \ + -e VAULT_ADDR='http://127.0.0.1:8200' \ + hashicorp/vault-mcp-server +``` + +### Token Errors + +```bash +# Verify token is valid +vault token lookup + +# Check token has required policies +vault token capabilities $VAULT_TOKEN sys/mounts +``` + +--- + +For detailed configuration examples and advanced patterns, see [references/vault-mcp-server.md](references/vault-mcp-server.md). diff --git a/vault/ai-workflows/skills/vault-mcp-server/references/vault-mcp-server.md b/vault/ai-workflows/skills/vault-mcp-server/references/vault-mcp-server.md new file mode 100644 index 0000000..73f34f2 --- /dev/null +++ b/vault/ai-workflows/skills/vault-mcp-server/references/vault-mcp-server.md @@ -0,0 +1,441 @@ +--- +name: vault-mcp-server-reference +description: Detailed configuration reference for the Vault MCP Server including installation, transport modes, environment variables, and IDE integration +--- + +# Vault MCP Server Reference + +This reference provides detailed configuration for the HashiCorp Vault MCP Server. + +--- + +## Overview + +The Vault MCP Server implements the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) to enable AI assistants to interact with HashiCorp Vault. It supports both stdio and StreamableHTTP transports. + +--- + +## Installation + +### Docker (Recommended) + +```bash +# Pull latest image +docker pull hashicorp/vault-mcp-server + +# Verify installation +docker run --rm hashicorp/vault-mcp-server --version +``` + +### From Source + +```bash +# Clone repository +git clone https://github.com/hashicorp/vault-mcp-server.git +cd vault-mcp-server + +# Build (requires Go 1.24+) +make build + +# Build Docker image +make docker-build + +# Build with custom registry +make docker-build DOCKER_REGISTRY=your-registry.com +``` + +--- + +## Transport Modes + +### Stdio Mode (Default) + +Standard input/output mode for subprocess communication. + +```bash +# Run in stdio mode +./vault-mcp-server +# or explicitly +./vault-mcp-server stdio + +# With Docker +docker run -i --rm \ + -e VAULT_ADDR='http://host.docker.internal:8200' \ + -e VAULT_TOKEN='' \ + hashicorp/vault-mcp-server +``` + +**When to use:** +- Claude Desktop integration +- VS Code with Docker +- Local development +- Single-user scenarios + +### StreamableHTTP Mode + +HTTP server mode for multi-client access. + +```bash +# Run in HTTP mode +./vault-mcp-server http --transport-port 8080 + +# With Docker +docker run --rm -p 8080:8080 \ + -e TRANSPORT_MODE='http' \ + -e TRANSPORT_PORT='8080' \ + -e VAULT_ADDR='http://vault:8200' \ + -e VAULT_TOKEN='' \ + hashicorp/vault-mcp-server +``` + +**When to use:** +- Shared development environments +- Multiple clients connecting +- Custom tooling integration + +--- + +## Environment Variables Reference + +### Vault Connection + +| Variable | Default | Required | Description | +|----------|---------|----------|-------------| +| `VAULT_ADDR` | `http://127.0.0.1:8200` | No | Vault server URL | +| `VAULT_TOKEN` | - | **Yes** | Authentication token | +| `VAULT_NAMESPACE` | - | No | Enterprise namespace | + +### Transport Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `TRANSPORT_MODE` | `stdio` | `stdio` or `http` | +| `TRANSPORT_HOST` | `127.0.0.1` | HTTP bind address | +| `TRANSPORT_PORT` | `8080` | HTTP bind port | +| `MCP_ENDPOINT` | `/mcp` | HTTP endpoint path | + +### Security Configuration + +| Variable | Default | Description | +|----------|---------|-------------| +| `MCP_ALLOWED_ORIGINS` | `""` | CORS allowed origins (comma-separated) | +| `MCP_CORS_MODE` | `strict` | `strict`, `development`, `disabled` | +| `MCP_TLS_CERT_FILE` | `""` | TLS certificate file path | +| `MCP_TLS_KEY_FILE` | `""` | TLS private key file path | + +### Rate Limiting + +| Variable | Default | Description | +|----------|---------|-------------| +| `MCP_RATE_LIMIT_GLOBAL` | `10:20` | Global limit (requests/sec:burst) | +| `MCP_RATE_LIMIT_SESSION` | `5:10` | Per-session limit (requests/sec:burst) | + +--- + +## IDE Integration + +### Visual Studio Code + +Create `.vscode/mcp.json` in your workspace: + +#### Stdio Mode with Docker + +```json +{ + "inputs": [ + { + "type": "promptString", + "id": "vault_addr", + "description": "Vault Address (e.g., http://127.0.0.1:8200)", + "password": false + }, + { + "type": "promptString", + "id": "vault_token", + "description": "Vault Token", + "password": true + }, + { + "type": "promptString", + "id": "vault_namespace", + "description": "Vault Namespace (optional)", + "password": false + } + ], + "servers": { + "vault-mcp-server": { + "command": "docker", + "args": [ + "run", "-i", "--rm", + "-e", "VAULT_ADDR=${input:vault_addr}", + "-e", "VAULT_TOKEN=${input:vault_token}", + "-e", "VAULT_NAMESPACE=${input:vault_namespace}", + "hashicorp/vault-mcp-server" + ] + } + } +} +``` + +#### HTTP Mode + +```json +{ + "inputs": [ + { + "type": "promptString", + "id": "vault_token", + "description": "Vault Token", + "password": true + }, + { + "type": "promptString", + "id": "vault_namespace", + "description": "Vault Namespace (optional)", + "password": false + } + ], + "servers": { + "vault-mcp-server": { + "url": "http://localhost:8080/mcp?VAULT_ADDR=http://127.0.0.1:8200", + "headers": { + "X-Vault-Token": "${input:vault_token}", + "X-Vault-Namespace": "${input:vault_namespace}" + } + } + } +} +``` + +### Claude Desktop + +Add to Claude Desktop configuration: + +```json +{ + "mcpServers": { + "vault": { + "command": "docker", + "args": [ + "run", "-i", "--rm", + "-e", "VAULT_ADDR=http://host.docker.internal:8200", + "-e", "VAULT_TOKEN=", + "hashicorp/vault-mcp-server" + ] + } + } +} +``` + +### Gemini Extensions + +```bash +# Create environment file +cat > ~/.gemini/.env << EOF +VAULT_ADDR=http://127.0.0.1:8200 +VAULT_TOKEN= +VAULT_NAMESPACE=admin +EOF + +# Install and run +gemini extensions install https://github.com/hashicorp/vault-mcp-server +gemini +``` + +--- + +## HTTP Mode Configuration Details + +### CORS Configuration + +```bash +# Strict mode (default) - requires explicit origins +docker run -p 8080:8080 \ + -e TRANSPORT_MODE='http' \ + -e MCP_CORS_MODE='strict' \ + -e MCP_ALLOWED_ORIGINS='http://localhost:3000,https://myapp.example.com' \ + hashicorp/vault-mcp-server + +# Development mode - allows localhost automatically +docker run -p 8080:8080 \ + -e TRANSPORT_MODE='http' \ + -e MCP_CORS_MODE='development' \ + hashicorp/vault-mcp-server + +# Disabled - no CORS headers (not recommended) +docker run -p 8080:8080 \ + -e TRANSPORT_MODE='http' \ + -e MCP_CORS_MODE='disabled' \ + hashicorp/vault-mcp-server +``` + +### TLS Configuration + +```bash +# Generate self-signed certificate (development) +openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes + +# Run with TLS +docker run -p 8443:8443 \ + -v $(pwd)/certs:/certs:ro \ + -e TRANSPORT_MODE='http' \ + -e TRANSPORT_PORT='8443' \ + -e MCP_TLS_CERT_FILE='/certs/cert.pem' \ + -e MCP_TLS_KEY_FILE='/certs/key.pem' \ + hashicorp/vault-mcp-server +``` + +### Rate Limiting + +```bash +# Configure rate limits +# Format: requests_per_second:burst_size +docker run -p 8080:8080 \ + -e TRANSPORT_MODE='http' \ + -e MCP_RATE_LIMIT_GLOBAL='20:50' \ + -e MCP_RATE_LIMIT_SESSION='10:25' \ + hashicorp/vault-mcp-server +``` + +--- + +## Vault Configuration in HTTP Mode + +In HTTP mode, Vault configuration can be provided through multiple methods (in order of precedence): + +1. **HTTP Query Parameters**: `?VAULT_ADDR=...` +2. **HTTP Headers**: `X-Vault-Token`, `X-Vault-Namespace` +3. **Environment Variables**: Standard Vault env vars + +### Example Request + +```bash +curl -X POST http://localhost:8080/mcp \ + -H "Content-Type: application/json" \ + -H "X-Vault-Token: hvs.xxx" \ + -H "X-Vault-Namespace: admin" \ + -d '{"method": "list_mounts"}' +``` + +--- + +## Docker Networking + +### macOS / Windows + +Use `host.docker.internal` to access host network: + +```bash +docker run -i --rm \ + -e VAULT_ADDR='http://host.docker.internal:8200' \ + hashicorp/vault-mcp-server +``` + +### Linux + +Use `--network=host` or explicit IP: + +```bash +# Option 1: Host network +docker run --network=host -i --rm \ + -e VAULT_ADDR='http://127.0.0.1:8200' \ + hashicorp/vault-mcp-server + +# Option 2: Docker network with Vault container +docker network create mcp +docker run --network=mcp -i --rm \ + -e VAULT_ADDR='http://vault:8200' \ + hashicorp/vault-mcp-server +``` + +--- + +## Security Considerations + +### Token Permissions + +Create a dedicated token with minimal permissions: + +```hcl +# Minimal policy for MCP operations +path "sys/mounts" { + capabilities = ["read", "list"] +} + +path "sys/mounts/*" { + capabilities = ["create", "delete"] +} + +path "secret/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} +``` + +```bash +vault policy write mcp-user mcp-policy.hcl +vault token create -policy=mcp-user -ttl=8h +``` + +### Audit Logging + +All MCP operations are logged in Vault audit logs: + +```bash +# Enable audit logging +vault audit enable file file_path=/var/log/vault/audit.log + +# View MCP operations +grep "mcp" /var/log/vault/audit.log +``` + +--- + +## Troubleshooting + +### Connection Issues + +```bash +# Test Vault connectivity +curl $VAULT_ADDR/v1/sys/health + +# Check Docker can reach Vault +docker run --rm curlimages/curl \ + curl -s http://host.docker.internal:8200/v1/sys/health +``` + +### Token Issues + +```bash +# Verify token +vault token lookup + +# Check capabilities +vault token capabilities $VAULT_TOKEN sys/mounts +vault token capabilities $VAULT_TOKEN secret/data/test +``` + +### Debug Logging + +```bash +# Enable debug output +docker run -i --rm \ + -e VAULT_ADDR='http://host.docker.internal:8200' \ + -e VAULT_TOKEN='' \ + -e LOG_LEVEL='debug' \ + hashicorp/vault-mcp-server +``` + +--- + +## Additional Resources + +- [Vault MCP Server GitHub](https://github.com/hashicorp/vault-mcp-server) +- [Model Context Protocol Specification](https://modelcontextprotocol.io/specification) +- [VS Code MCP Integration](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) + +--- + +## Related + +- [mcp-secrets-workflows.md](../mcp-secrets-workflows/references/mcp-secrets-workflows.md) - MCP tool usage patterns +- [auth-methods.md](../../../authentication/skills/auth-methods/references/auth-methods.md) - Token authentication diff --git a/vault/app-access/.claude-plugin/plugin.json b/vault/app-access/.claude-plugin/plugin.json new file mode 100644 index 0000000..b19fe4c --- /dev/null +++ b/vault/app-access/.claude-plugin/plugin.json @@ -0,0 +1,39 @@ +{ + "name": "vault-app-access", + "version": "0.2.0", + "description": "Give applications secure access to Vault secrets. Covers authentication methods (AppRole, Kubernetes, OIDC, AWS), access policies, token management, identity, and secure credential distribution.", + "author": "HashiCorp", + "homepage": "https://developer.hashicorp.com/vault/docs/auth", + "repository": "https://github.com/hashicorp/agent-skills", + "license": "MPL-2.0", + "keywords": [ + "vault", + "auth", + "authentication", + "access", + "approle", + "kubernetes", + "oidc", + "policies", + "hashicorp" + ], + "mcpServers": { + "vault": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "-e", + "VAULT_ADDR", + "-e", + "VAULT_TOKEN", + "hashicorp/vault-mcp-server" + ], + "env": { + "VAULT_ADDR": "${VAULT_ADDR}", + "VAULT_TOKEN": "${VAULT_TOKEN}" + } + } + } +} diff --git a/vault/app-access/SPEC.md b/vault/app-access/SPEC.md new file mode 100644 index 0000000..6b22ebd --- /dev/null +++ b/vault/app-access/SPEC.md @@ -0,0 +1,156 @@ +# Specification: vault-app-access + +**Status**: Published +**Version**: 0.3.0 + +--- + +## Overview + +This plugin helps you **give applications secure access to Vault**. Covers authentication methods (AppRole, Kubernetes, OIDC, AWS, Azure, GCP, LDAP), access control policies, token lifecycle management, unified identity, and secure secret distribution via response wrapping. + +--- + +## User Stories + +### US-1: Platform Engineer Configuring Kubernetes Authentication (P1) + +A platform engineer needs to configure Kubernetes workloads to authenticate with Vault and retrieve secrets without manual token management. + +**Why this priority**: Kubernetes is the dominant container orchestration platform. K8s-native auth is essential for cloud-native deployments. + +**Acceptance Criteria**: +1. Given a user asks about Kubernetes auth, when the skill is invoked, then it provides Kubernetes auth method configuration including role binding and ClusterRoleBinding setup. +2. Given a user mentions service accounts, when queried, then the skill explains service account binding patterns and annotations_as_alias_metadata. +3. Given a Kubernetes 1.21+ question, when asked about token handling, then the skill explains short-lived bound service account token options. + +### US-2: DevOps Engineer Setting Up CI/CD Authentication (P1) + +A DevOps engineer needs to configure GitHub Actions/GitLab CI to authenticate with Vault for deployment secrets. + +**Why this priority**: Secure CI/CD integration is critical for DevOps pipelines. + +**Acceptance Criteria**: +1. Given a CI/CD authentication question, when the skill is invoked, then it provides AppRole or JWT auth configuration. +2. Given a trusted broker pattern question, when queried, then the skill explains response wrapping and secure credential distribution. +3. Given a response wrapping question, when asked about SecretID, then the skill explains wrapped SecretID workflow with TTL enforcement. + +### US-3: Security Engineer Writing Access Policies (P1) + +A security engineer needs to create fine-grained access control policies for multiple teams accessing different secrets paths. + +**Why this priority**: Policies are the foundation of Vault's security model. Incorrect policies create security risks. + +**Acceptance Criteria**: +1. Given a user requests policy creation, when the skill is invoked, then it generates valid HCL policy syntax with proper path patterns. +2. Given a user asks about templated policies, when queried, then the skill explains identity templating with {{identity.entity}} patterns. +3. Given a KV v2 question, when asked about paths, then the skill emphasizes /data/ path segment requirement. +4. Given a response wrapping policy question, when asked, then the skill shows min/max_wrapping_ttl enforcement. + +### US-4: Identity Admin Configuring SSO (P2) + +An identity administrator needs to configure OIDC authentication for human users via Okta/Azure AD. + +**Acceptance Criteria**: +1. Given an OIDC configuration request, when the skill is invoked, then it provides complete OIDC auth setup including claims mapping. +2. Given a group-based access question, when queried, then the skill explains external groups and policy assignment. +3. Given an OIDC group mapping question, when asked about workflow, then the skill explains the full OIDC group mapping workflow. + +### US-5: Security Engineer Implementing Trusted Broker (P2) + +A security engineer needs to implement the AppRole trusted broker pattern for secure CI/CD secret distribution. + +**Acceptance Criteria**: +1. Given a trusted broker question, when the skill is invoked, then it provides complete trusted broker architecture with workflow diagram. +2. Given a policy question, when asked about broker permissions, then the skill shows broker policy with wrapping TTL constraints. +3. Given a security configuration question, when asked, then the skill explains secret_id_num_uses, secret_id_ttl, and CIDR binding. + +### US-6: Platform Engineer Managing Token Lifecycle (P1) + +A platform engineer needs to understand and manage different token types for various workload patterns. + +**Why this priority**: Token management is fundamental to Vault operations. Incorrect token usage causes outages. + +**Acceptance Criteria**: +1. Given a token type question, when the skill is invoked, then it explains service vs batch tokens and when to use each. +2. Given a long-running service question, when queried, then the skill provides periodic token configuration. +3. Given a token renewal question, when asked, then the skill explains TTL, max TTL, and renewal strategies. + +### US-7: Administrator Configuring Unified Identity (P2) + +An administrator needs to map users from multiple auth methods to a single identity for consistent policy application. + +**Acceptance Criteria**: +1. Given an identity configuration question, when the skill is invoked, then it explains entities, aliases, and group membership. +2. Given an OIDC provider question, when queried, then the skill provides Vault-as-OIDC-provider configuration. +3. Given a policy inheritance question, when asked, then the skill explains entity and group policy assignment. + +### US-8: Developer Implementing Secure Secret Handoff (P2) + +A developer needs to securely pass secrets to another service using response wrapping. + +**Acceptance Criteria**: +1. Given a response wrapping question, when the skill is invoked, then it explains cubbyhole and wrapped token patterns. +2. Given a malfeasance detection question, when queried, then the skill explains single-use tokens and detection. +3. Given a bootstrap question, when asked, then the skill provides wrapped token bootstrap workflow. + +--- + +## Functional Requirements + +| ID | Requirement | +|----|-------------| +| FR-001 | Skill MUST cover AppRole authentication with trusted broker pattern | +| FR-002 | Skill MUST cover Kubernetes auth with 1.21+ token handling | +| FR-003 | Skill MUST cover OIDC auth with group mapping workflow | +| FR-004 | Skill MUST cover AWS IAM auth with server ID header | +| FR-005 | Skill MUST cover Azure AD, GCP IAM, LDAP auth methods | +| FR-006 | Skill MUST explain Identity system and entities | +| FR-007 | Skill MUST cover HCL policy syntax with all capabilities | +| FR-008 | Skill MUST explain KV v2 /data/ path requirement | +| FR-009 | Skill MUST cover templated policies with identity tokens | +| FR-010 | Skill MUST cover response wrapping TTL enforcement | +| FR-011 | Skill MUST explain CI/CD pipeline policy patterns | +| FR-012 | Skill MUST cover Sentinel policies (Enterprise) | +| FR-013 | Skill MUST explain service vs batch token differences | +| FR-014 | Skill MUST cover periodic token configuration | +| FR-015 | Skill MUST explain token accessor usage patterns | +| FR-016 | Skill MUST cover orphan token creation and implications | +| FR-017 | Skill MUST explain entity and alias creation | +| FR-018 | Skill MUST cover internal and external group types | +| FR-019 | Skill MUST explain identity token (OIDC) generation | +| FR-020 | Skill MUST cover cubbyhole secrets engine | +| FR-021 | Skill MUST explain wrap/unwrap operations | +| FR-022 | Skill MUST cover wrapped token bootstrap patterns | + +--- + +## Skills Included + +| Skill | Description | +|-------|-------------| +| `auth-methods` | Configure AppRole, Kubernetes, OIDC, AWS, Azure, GCP, LDAP auth | +| `policies` | Write HCL policies, templated policies, and debug permissions | +| `token-management` | Manage service, batch, periodic, orphan tokens and accessors | +| `identity-system` | Configure entities, aliases, groups, and OIDC provider | +| `response-wrapping` | Implement cubbyhole wrapping and secure secret distribution | + +--- + +## Content Sources + +- HashiCorp Vault Documentation +- Vault Tutorials +- CSA Enterprise Patterns (genericized) + +--- + +## References + +- [Vault Auth Methods](https://developer.hashicorp.com/vault/docs/auth) +- [AppRole Auth](https://developer.hashicorp.com/vault/docs/auth/approle) +- [Kubernetes Auth](https://developer.hashicorp.com/vault/docs/auth/kubernetes) +- [Vault Policies](https://developer.hashicorp.com/vault/docs/concepts/policies) +- [Token Concepts](https://developer.hashicorp.com/vault/docs/concepts/tokens) +- [Identity Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/identity) +- [Response Wrapping](https://developer.hashicorp.com/vault/docs/concepts/response-wrapping) diff --git a/vault/app-access/skills/auth-methods/SKILL.md b/vault/app-access/skills/auth-methods/SKILL.md new file mode 100644 index 0000000..f74e75f --- /dev/null +++ b/vault/app-access/skills/auth-methods/SKILL.md @@ -0,0 +1,180 @@ +--- +name: auth-methods +description: Configure Vault authentication methods. Use when asked about AppRole, Kubernetes auth, OIDC/JWT, AWS IAM auth, Azure auth, GCP auth, LDAP, GitHub auth, or the trusted broker pattern. Covers identity verification and token generation. +--- + +# Vault Authentication Methods + +## What Are You Trying to Solve? + +### "I need my CI/CD pipeline to access Vault" +→ Use **AppRole** with response wrapping for secure bootstrap. [Jump to AppRole](#approle-recommended-for-automation) + +### "I need my Kubernetes pods to get secrets" +→ Use **Kubernetes auth** bound to service accounts. [Jump to Kubernetes](#kubernetes) + +### "I need human users to login via SSO" +→ Use **OIDC** with your identity provider (Okta, Azure AD). [Jump to OIDC](#oidc-human-users) + +### "I have an AWS workload that needs secrets" +→ Use **AWS IAM auth** for EC2/Lambda/ECS. [Jump to AWS](#aws-iam) + +### "I'm not sure which auth method to use" +→ See the [selection guide](#auth-method-selection) below. + +--- + +## How Vault Authentication Works + +1. **Authenticate** → Client presents credentials (role_id/secret_id, JWT, IAM signature) +2. **Validate** → Vault verifies with identity provider or trusted source +3. **Authorize** → Vault issues token with attached policies +4. **Access** → Client uses token for subsequent API calls (all operations audited) + +--- + +## Auth Method Selection + +| Your Workload | Recommended Auth | Why | +|---------------|------------------|-----| +| CI/CD (GitHub Actions, GitLab, Jenkins) | AppRole or JWT | Machine identity, short-lived | +| Kubernetes pods | Kubernetes | Native service account binding | +| Human users (Okta, Azure AD) | OIDC | SSO integration | +| AWS EC2/Lambda/ECS | AWS IAM | Cloud-native identity | +| Azure VMs/Functions | Azure | Managed identity | +| GCP GCE/Functions | GCP | Service account identity | +| Legacy LDAP directory | LDAP | Enterprise directory | + +--- + +## Reference + +- [Vault Auth Methods Documentation](https://developer.hashicorp.com/vault/docs/auth) +- [Detailed Auth Methods Reference](references/auth-methods.md) + +--- + +## Quick Reference + +### AppRole (Recommended for Automation) + +```bash +# Enable AppRole +vault auth enable approle + +# Create role +vault write auth/approle/role/my-app \ + token_policies="app-policy" \ + token_ttl=1h \ + secret_id_ttl=10m + +# Get credentials +vault read auth/approle/role/my-app/role-id +vault write -f auth/approle/role/my-app/secret-id + +# Login +vault write auth/approle/login \ + role_id="" \ + secret_id="" +``` + +### Kubernetes + +```bash +# Enable Kubernetes auth +vault auth enable kubernetes + +# Configure with cluster info +vault write auth/kubernetes/config \ + kubernetes_host="https://kubernetes.default.svc:443" + +# Create role bound to service account +vault write auth/kubernetes/role/my-app \ + bound_service_account_names=my-app-sa \ + bound_service_account_namespaces=default \ + policies=app-policy \ + ttl=1h +``` + +### OIDC (Human Users) + +```bash +# Enable OIDC +vault auth enable oidc + +# Configure provider (e.g., Okta) +vault write auth/oidc/config \ + oidc_discovery_url="https://your-org.okta.com" \ + oidc_client_id="vault-client-id" \ + oidc_client_secret="client-secret" \ + default_role="default" + +# Create role +vault write auth/oidc/role/default \ + bound_audiences="vault-client-id" \ + allowed_redirect_uris="http://localhost:8250/oidc/callback" \ + user_claim="email" \ + policies="user-policy" + +# Login +vault login -method=oidc +``` + +### AWS IAM + +```bash +# Enable AWS auth +vault auth enable aws + +# Configure +vault write auth/aws/config/client \ + access_key="ACCESS_KEY" \ + secret_key="SECRET_KEY" + +# Create IAM role +vault write auth/aws/role/my-role \ + auth_type=iam \ + bound_iam_principal_arn="arn:aws:iam::123456789:role/my-role" \ + policies=aws-policy +``` + +--- + +## Common Patterns + +### Trusted Broker Pattern + +Securely distribute initial credentials using response wrapping: + +```bash +# Wrap a secret ID for 60 seconds +vault write -wrap-ttl=60s -f auth/approle/role/my-app/secret-id + +# Unwrap on the target machine (single use) +vault unwrap +``` + +### Multi-Method Authentication + +```bash +# Enable multiple methods with mount paths +vault auth enable -path=okta oidc +vault auth enable -path=github-actions jwt + +# Users can authenticate via either +vault login -method=oidc -path=okta +``` + +--- + +## Best Practices + +- **Use AppRole** for machine-to-machine with short-lived secret IDs +- **Use Kubernetes auth** for K8s workloads (avoid mounting service account tokens) +- **Use OIDC** for human users (integrates with existing SSO) +- **Bind to specific identities** - never use wildcards in IAM principal ARNs +- **Set short TTLs** - 1h or less for tokens + +--- + +For detailed configurations including Azure, GCP, LDAP, GitHub, and advanced patterns, see [references/auth-methods.md](references/auth-methods.md). diff --git a/vault/app-access/skills/auth-methods/references/auth-methods.md b/vault/app-access/skills/auth-methods/references/auth-methods.md new file mode 100644 index 0000000..1944734 --- /dev/null +++ b/vault/app-access/skills/auth-methods/references/auth-methods.md @@ -0,0 +1,574 @@ +--- +name: vault-auth-methods +description: Detailed configuration for Vault authentication methods including AppRole, Kubernetes, OIDC, AWS, Azure, GCP, and LDAP +--- + +# Vault Authentication Methods + +This reference provides detailed configuration for Vault's authentication methods. + +--- + +## Overview + +Authentication methods verify user or machine identity before granting access. After successful authentication, Vault issues a **token** tied to policies that define permissions. + +### Authentication Flow + +1. Client presents credentials to an auth method endpoint +2. Vault validates credentials with the identity provider +3. Vault issues a token with attached policies +4. Client uses token for subsequent API calls + +--- + +## AppRole (Recommended for Applications) + +AppRole is designed for machine-to-machine authentication with two-factor security (RoleID + SecretID). + +### Enable and Configure AppRole + +```bash +# Enable AppRole auth +vault auth enable approle + +# Create a role with policies and TTL +vault write auth/approle/role/my-app \ + token_policies="app-policy" \ + token_ttl=1h \ + token_max_ttl=4h \ + secret_id_ttl=10m \ + secret_id_num_uses=1 +``` + +### Get Credentials + +```bash +# Get RoleID (can be embedded in configuration) +vault read auth/approle/role/my-app/role-id + +# Generate SecretID (deliver securely, often via response wrapping) +vault write -f auth/approle/role/my-app/secret-id + +# Response wrapping for secure SecretID delivery +vault write -wrap-ttl=60s -f auth/approle/role/my-app/secret-id +``` + +### AppRole Application Login + +```bash +# CLI login +vault write auth/approle/login \ + role_id="" \ + secret_id="" + +# API login +curl --request POST \ + --data '{"role_id": "", "secret_id": ""}' \ + $VAULT_ADDR/v1/auth/approle/login +``` + +### Best Practices + +- Use `secret_id_num_uses=1` for single-use SecretIDs +- Deliver SecretID via response wrapping +- Use short TTLs and implement token renewal +- Separate RoleID (less sensitive) from SecretID (highly sensitive) + +--- + +## AppRole Trusted Broker Pattern (CI/CD) + +> **Core Principle**: RoleID and SecretID should ONLY ever be together on the end-user system that consumes the secret. + +### Architecture + +```text +┌─────────┐ ┌─────────┐ ┌─────────┐ +│ CI │ 1.Auth ──────────► │ Vault │ ◄──── 8.Auth ─────│ Runner │ +│ Worker │ ◄──── 2.Token ──── │ │ ──── 9.Token ───► │Container│ +│(Broker) │ 3.Wrapped SecretID │ │ ◄── 10.Get Secret │ │ +│ │ ◄──── 4.Return ─── │ │ ──── 11.Secret ──►│ │ +│ │ 5.Spawn+Pass ─────────────────────────────────────► │ +└─────────┘ └─────────┘ 6.Unwrap └─────────┘ + 7.SecretID +``` + +### Workflow Steps + +1. CI Worker authenticates to Vault (using its own identity) +2. Vault returns token with limited policy +3. Worker requests **wrapped** SecretID for the runner role +4. Vault returns wrapped SecretID (single-use wrapping token) +5. Worker spawns runner container, passes wrapped SecretID as env var +6. Runner unwraps the SecretID +7. Runner uses RoleID + SecretID to authenticate +8. Vault returns token with runner-specific policies +9. Runner retrieves secrets + +### Worker Policy (Trusted Broker) + +```hcl +# Worker can only create wrapped SecretIDs, not access secrets directly +path "auth/approle/role/+/secret*" { + capabilities = ["create", "read", "update"] + min_wrapping_ttl = "100s" + max_wrapping_ttl = "300s" +} +``` + +### Runner Policy (Scoped to Specific Secrets) + +```hcl +path "secret/data/{{identity.entity.metadata.app}}/*" { + capabilities = ["read"] +} +``` + +### Jenkins Pipeline Example + +```groovy +pipeline { + environment { + WRAPPED_SID = sh( + returnStdout: true, + script: ''' + curl --silent \ + --header "X-Vault-Token: ${VAULT_TOKEN}" \ + --header "X-Vault-Wrap-TTL: 300s" \ + --request POST \ + ${VAULT_ADDR}/v1/auth/approle/role/${JOB_NAME}/secret-id \ + | jq -r '.wrap_info.token' + ''' + ).trim() + } + stages { + stage('Run') { + steps { + // Pass wrapped SecretID to container + sh 'docker run -e WRAPPED_SID=${WRAPPED_SID} myapp:latest' + } + } + } +} +``` + +### Security Configurations + +| Setting | Recommended Value | Purpose | +| --------- | ------------------- | --------- | +| `secret_id_num_uses` | 1 | Single-use SecretIDs | +| `secret_id_ttl` | 120s | Short-lived SecretIDs | +| `secret_id_bound_cidrs` | Network range | Restrict login location | +| `wrap_ttl` | 100-300s | Response wrapping for delivery | + +### Anti-Patterns to Avoid + +| Anti-Pattern | Risk | Correct Approach | +| -------------- | ------ | ------------------ | +| CI Worker retrieves secrets directly | Worker has access to many secrets | Use trusted broker pattern | +| Passing RoleID AND SecretID together | Full auth credentials exposed | Separate delivery mechanisms | +| Passing Vault tokens to runners | Token can access all permitted secrets | Use AppRole per-runner | +| Storing SecretID in CI/CD config | Credential exposure | Generate per-run with wrapping | + +### Security Monitoring + +Alert on these conditions in audit logs: + +- Wrapped SecretID requested when no job is running +- Unwrap attempt fails (token already used = potential compromise) +- SecretID generated without corresponding job execution + +--- + +## Kubernetes Authentication + +Authenticates Kubernetes pods using their ServiceAccount tokens. + +### Enable and Configure Kubernetes Auth + +```bash +# Enable Kubernetes auth +vault auth enable kubernetes + +# Configure Vault to communicate with Kubernetes API +vault write auth/kubernetes/config \ + kubernetes_host="https://kubernetes.default.svc:443" \ + kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + +# For external Vault accessing K8s cluster +vault write auth/kubernetes/config \ + kubernetes_host="https://cluster-api.example.com:6443" \ + kubernetes_ca_cert=@ca.crt \ + token_reviewer_jwt=@reviewer-jwt.txt +``` + +### Handling Kubernetes 1.21+ Short-Lived Tokens + +Kubernetes 1.21+ uses short-lived bound service account tokens. Configure one of these options: + +```bash +# Option 1: Use local token reviewer JWT (recommended when Vault runs in K8s) +vault write auth/kubernetes/config \ + kubernetes_host="https://kubernetes.default.svc:443" \ + kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + +# Option 2: Disable issuer validation (for cross-cluster auth) +vault write auth/kubernetes/config \ + kubernetes_host="https://kubernetes.example.com:6443" \ + kubernetes_ca_cert=@ca.crt \ + disable_iss_validation=true + +# Option 3: Use explicit issuer (for specific OIDC issuers) +vault write auth/kubernetes/config \ + kubernetes_host="https://kubernetes.example.com:6443" \ + issuer="https://kubernetes.default.svc.cluster.local" +``` + +### Use Annotations as Alias Metadata + +Enable templated policies using ServiceAccount metadata: + +```bash +vault write auth/kubernetes/config \ + kubernetes_host="https://kubernetes.default.svc:443" \ + use_annotations_as_alias_metadata=true +``` + +This allows policies like: + +```hcl +path "secret/data/{{identity.entity.aliases.auth_kubernetes.metadata.service_account_namespace}}/*" { + capabilities = ["read"] +} +``` + +### Create Roles + +```bash +# Bind role to specific ServiceAccount and namespace +vault write auth/kubernetes/role/my-app \ + bound_service_account_names=my-app-sa \ + bound_service_account_namespaces=default,staging \ + policies=app-policy \ + ttl=1h \ + audience=vault + +# Wildcard bindings +vault write auth/kubernetes/role/any-app \ + bound_service_account_names="*" \ + bound_service_account_namespaces=apps \ + policies=read-only +``` + +### Pod Authentication + +Pods authenticate using their mounted ServiceAccount token: + +```bash +# From within pod +JWT=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) +curl --request POST \ + --data "{\"jwt\": \"$JWT\", \"role\": \"my-app\"}" \ + $VAULT_ADDR/v1/auth/kubernetes/login +``` + +### Kubernetes RBAC Requirements + +```yaml +# ClusterRoleBinding for token review +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: vault-tokenreview +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: vault + namespace: vault +``` + +--- + +## JWT/OIDC Authentication + +Authenticate using JSON Web Tokens from OIDC providers (Okta, Auth0, Azure AD, Google). + +### OIDC Configuration (Interactive) + +```bash +# Enable OIDC +vault auth enable oidc + +# Configure with OIDC provider +vault write auth/oidc/config \ + oidc_discovery_url="https://accounts.google.com" \ + oidc_client_id="" \ + oidc_client_secret="" \ + default_role="default" + +# Create role with claims mapping +vault write auth/oidc/role/default \ + allowed_redirect_uris="http://localhost:8250/oidc/callback" \ + allowed_redirect_uris="https://vault.example.com:8200/ui/vault/auth/oidc/oidc/callback" \ + user_claim="email" \ + policies="default" \ + oidc_scopes="openid,email,profile" \ + bound_claims='{"groups": ["engineering"]}' +``` + +### JWT Configuration (Non-Interactive) + +```bash +# For JWT tokens (CI/CD, service accounts) +vault auth enable jwt + +vault write auth/jwt/config \ + oidc_discovery_url="https://token.actions.githubusercontent.com" \ + bound_issuer="https://token.actions.githubusercontent.com" + +# GitHub Actions role +vault write auth/jwt/role/github-actions \ + role_type="jwt" \ + user_claim="actor" \ + bound_claims_type="glob" \ + bound_claims='{"repository": "myorg/*"}' \ + policies="ci-policy" \ + ttl=15m +``` + +### OIDC Login + +```bash +# Interactive browser login +vault login -method=oidc + +# With specific role +vault login -method=oidc role=admin +``` + +--- + +## AWS IAM Authentication + +Authenticate EC2 instances or IAM principals using AWS credentials. + +### Enable and Configure AWS Auth + +```bash +vault auth enable aws + +# Configure AWS credentials for Vault +vault write auth/aws/config/client \ + access_key= \ + secret_key= \ + region=us-east-1 + +# For STS with assumed role +vault write auth/aws/config/sts/account-id \ + sts_role=arn:aws:iam::ACCOUNT:role/VaultVerifyRole +``` + +### IAM Role (Recommended) + +```bash +# Create IAM auth role +vault write auth/aws/role/web-app \ + auth_type=iam \ + bound_iam_principal_arn="arn:aws:iam::ACCOUNT:role/WebAppRole" \ + policies=app-policy \ + ttl=1h +``` + +### EC2 Role + +```bash +vault write auth/aws/role/ec2-app \ + auth_type=ec2 \ + bound_ami_id="ami-12345678" \ + bound_vpc_id="vpc-abcdef12" \ + policies=app-policy +``` + +### AWS Application Login + +```bash +# IAM auth from AWS environment +vault login -method=aws role=web-app + +# Using explicit credentials +vault write auth/aws/login \ + role=web-app \ + iam_http_request_method=POST \ + iam_request_url= \ + iam_request_body= \ + iam_request_headers= +``` + +--- + +## Azure Authentication + +Authenticate Azure VMs and managed identities. + +### Enable and Configure Azure Auth + +```bash +vault auth enable azure + +vault write auth/azure/config \ + tenant_id="" \ + resource="https://management.azure.com/" \ + client_id="" \ + client_secret="" +``` + +### Create Role + +```bash +vault write auth/azure/role/web-app \ + policies="app-policy" \ + bound_subscription_ids="" \ + bound_resource_groups="my-rg" \ + bound_service_principal_ids="" +``` + +--- + +## GCP Authentication + +Authenticate GCP service accounts and compute instances. + +### Enable and Configure GCP Auth + +```bash +vault auth enable gcp + +vault write auth/gcp/config \ + credentials=@gcp-credentials.json +``` + +### IAM Role + +```bash +vault write auth/gcp/role/web-app \ + type="iam" \ + policies="app-policy" \ + bound_service_accounts="sa@project.iam.gserviceaccount.com" +``` + +### GCE Role + +```bash +vault write auth/gcp/role/gce-app \ + type="gce" \ + policies="app-policy" \ + bound_projects="my-project" \ + bound_zones="us-central1-a" \ + bound_labels="env:prod" +``` + +--- + +## LDAP Authentication + +Authenticate against LDAP/Active Directory. + +### Enable and Configure LDAP Auth + +```bash +vault auth enable ldap + +vault write auth/ldap/config \ + url="ldaps://ldap.example.com:636" \ + binddn="cn=vault,ou=services,dc=example,dc=com" \ + bindpass="" \ + userdn="ou=users,dc=example,dc=com" \ + userattr="sAMAccountName" \ + groupdn="ou=groups,dc=example,dc=com" \ + groupattr="cn" \ + insecure_tls=false \ + starttls=false +``` + +### Map Groups to Policies + +```bash +# Map LDAP group to Vault policies +vault write auth/ldap/groups/engineering \ + policies="engineering-policy,read-only" + +vault write auth/ldap/groups/admins \ + policies="admin-policy" +``` + +### Login + +```bash +vault login -method=ldap username=jdoe +# Prompts for password +``` + +--- + +## Token Authentication + +Direct token authentication (often used after other methods issue tokens). + +### Create Tokens + +```bash +# Create token with policies +vault token create -policy=app-policy -ttl=1h + +# Create orphan token (no parent) +vault token create -orphan -policy=app-policy + +# Create periodic token (renewable indefinitely) +vault token create -policy=app-policy -period=24h + +# Create batch token (lightweight, no storage) +vault token create -type=batch -policy=app-policy +``` + +### Token Types + +| Type | Storage | Renewal | Use Case | +| ------ | --------- | --------- | ---------- | +| **Service** | Yes | Yes | Long-running apps | +| **Batch** | No | No | Short-lived, high-volume | +| **Periodic** | Yes | Indefinite | Services needing long uptime | + +--- + +## Comparison Table + +| Method | Use Case | Security Level | Complexity | +| -------- | ---------- | ---------------- | ------------ | +| **AppRole** | Applications, CI/CD | High | Medium | +| **Kubernetes** | K8s pods | High | Medium | +| **JWT/OIDC** | SSO, CI/CD tokens | High | Medium | +| **AWS** | AWS workloads | High | Low | +| **Azure** | Azure workloads | High | Low | +| **GCP** | GCP workloads | High | Low | +| **LDAP** | Enterprise users | Medium | Medium | +| **Token** | Direct auth | Varies | Low | + +--- + +## Additional Resources + +- [Auth Methods Documentation](https://developer.hashicorp.com/vault/docs/auth) +- [AppRole Tutorial](https://developer.hashicorp.com/vault/tutorials/auth-methods/approle) +- [Kubernetes Auth Tutorial](https://developer.hashicorp.com/vault/tutorials/kubernetes/kubernetes-sidecar) + +--- + +## Related + +- [Policies](policies.md) - Define permissions for authenticated identities +- [Kubernetes Integration](kubernetes.md) - K8s-specific auth and secret delivery +- [Vault Agent](vault-agent.md) - Auto-auth configuration for applications diff --git a/vault/app-access/skills/identity-system/SKILL.md b/vault/app-access/skills/identity-system/SKILL.md new file mode 100644 index 0000000..41d95d9 --- /dev/null +++ b/vault/app-access/skills/identity-system/SKILL.md @@ -0,0 +1,278 @@ +--- +name: identity-system +description: Use when working with Vault identity, entities, aliases, groups, identity tokens, or OIDC provider configuration. Covers unified identity management and SSO patterns. +--- + +# Identity System + +## What Are You Trying to Solve? + +### "Users log in via different auth methods but should have same access" +→ Use **entities** to unify identity across auth methods. [Jump to Entities](#entities) + +### "I need to grant policies to teams, not individuals" +→ Use **groups** for team-based access. [Jump to Groups](#groups) + +### "I want Vault to be my OIDC identity provider" +→ Use **OIDC Provider** for SSO integration. [Jump to OIDC Provider](#oidc-provider) + +### "I need to issue JWTs with user claims" +→ Use **identity tokens** with custom templates. [Jump to Identity Tokens](#identity-tokens-oidc) + +### "I have duplicate entities to merge" +→ Use **entity merge**. [Jump to Merge Entities](#merge-entities) + +--- + +## How Vault Identity Works + +1. **Entity** → Represents a single user/machine across all auth methods +2. **Alias** → Maps an auth method login (e.g., alice@ldap) to an entity +3. **Group** → Collection of entities for policy inheritance +4. **Token** → When user authenticates, token inherits entity + group policies + +**Key insight:** Same person logging in via LDAP or GitHub gets same policies if both are aliased to their entity. + +--- + +## Identity Hierarchy + +``` +┌─────────────────────────────────────────────────────────┐ +│ Entity: alice │ +│ policies: [developer] │ +├─────────────────────┬───────────────────────────────────┤ +│ Alias: alice@ldap │ Alias: alice-github │ +│ mount: auth/ldap │ mount: auth/github │ +└─────────────────────┴───────────────────────────────────┘ + │ + ▼ + ┌────────────────────────┐ + │ Group: platform-team │ + │ policies: [platform] │ + └────────────────────────┘ +``` + +--- + +## Reference + +- [Identity Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/identity) +- [Identity Concepts](https://developer.hashicorp.com/vault/docs/concepts/identity) +- [OIDC Provider](https://developer.hashicorp.com/vault/docs/secrets/identity/oidc-provider) +- For complete API examples and advanced patterns, see [references/identity-system.md](references/identity-system.md) + +## Entities + +An entity represents a single person or machine: + +```bash +# Create entity +vault write identity/entity \ + name="alice" \ + policies="developer" \ + metadata=team="platform" + +# Read entity +vault read identity/entity/name/alice + +# List entities +vault list identity/entity/name +``` + +### Entity Aliases + +Map authentication sources to entities: + +```bash +# Create alias linking LDAP login to entity +vault write identity/entity-alias \ + name="alice@corp.com" \ + canonical_id="entity-uuid-here" \ + mount_accessor="auth_ldap_abc123" + +# When alice logs in via LDAP, her token inherits entity policies +``` + +## Groups + +### Internal Groups (Manual Membership) + +```bash +# Create internal group +vault write identity/group \ + name="platform-team" \ + policies="platform-policy" \ + member_entity_ids="entity-uuid-1,entity-uuid-2" + +# Add entity to group +vault write identity/group/name/platform-team \ + member_entity_ids="entity-uuid-1,entity-uuid-2,entity-uuid-3" +``` + +### External Groups (Auth Method Controlled) + +```bash +# Create external group +vault write identity/group \ + name="ldap-admins" \ + type="external" \ + policies="admin-policy" + +# Create group alias mapping LDAP group +vault write identity/group-alias \ + name="cn=admins,ou=groups,dc=corp,dc=com" \ + mount_accessor="auth_ldap_abc123" \ + canonical_id="group-uuid-here" + +# When LDAP user in "admins" group authenticates, they inherit policies +``` + +## Identity Hierarchy + +``` +┌─────────────────────────────────────────────────────────┐ +│ Entity: alice │ +│ policies: [developer] │ +├─────────────────────┬───────────────────────────────────┤ +│ Alias: alice@ldap │ Alias: alice-github │ +│ mount: auth/ldap │ mount: auth/github │ +└─────────────────────┴───────────────────────────────────┘ + │ + ▼ + ┌────────────────────────┐ + │ Group: platform-team │ + │ policies: [platform] │ + └────────────────────────┘ +``` + +## Identity Tokens (OIDC) + +Issue OIDC-compliant identity tokens: + +```bash +# Create OIDC key +vault write identity/oidc/key/my-key \ + algorithm="RS256" \ + rotation_period="24h" + +# Create role +vault write identity/oidc/role/my-role \ + key="my-key" \ + template='{"groups":{{identity.entity.groups.names}}}' + +# Generate token +vault read identity/oidc/token/my-role +``` + +### Token Template + +Customize claims in identity tokens: + +```json +{ + "sub": "{{identity.entity.id}}", + "name": "{{identity.entity.name}}", + "groups": {{identity.entity.groups.names}}, + "email": "{{identity.entity.metadata.email}}" +} +``` + +## OIDC Provider + +Configure Vault as an OIDC identity provider: + +```bash +# Create provider +vault write identity/oidc/provider/my-provider \ + issuer="https://vault.example.com" \ + allowed_client_ids="client-id-1,client-id-2" + +# Create client +vault write identity/oidc/client/my-app \ + redirect_uris="https://app.example.com/callback" \ + assignments="allow_all" + +# Create scope +vault write identity/oidc/scope/profile \ + template='{"name":"{{identity.entity.name}}"}' +``` + +### Discovery Endpoint + +```bash +# OIDC discovery +curl $VAULT_ADDR/v1/identity/oidc/provider/my-provider/.well-known/openid-configuration +``` + +## Lookup Operations + +```bash +# Lookup entity by ID +vault read identity/entity/id/entity-uuid + +# Lookup entity by name +vault read identity/entity/name/alice + +# Lookup entity by alias +vault write identity/lookup/entity \ + alias_name="alice@corp.com" \ + alias_mount_accessor="auth_ldap_abc123" + +# Lookup group by name +vault read identity/group/name/platform-team +``` + +## Merge Entities + +Combine duplicate entities: + +```bash +vault write identity/entity/merge \ + from_entity_ids="entity-uuid-1,entity-uuid-2" \ + to_entity_id="entity-uuid-primary" +``` + +## API Examples + +### Create Entity + +```bash +curl -X POST \ + -H "X-Vault-Token: $VAULT_TOKEN" \ + -d '{"name":"alice","policies":["developer"]}' \ + $VAULT_ADDR/v1/identity/entity +``` + +### List Groups + +```bash +curl -X LIST \ + -H "X-Vault-Token: $VAULT_TOKEN" \ + $VAULT_ADDR/v1/identity/group/name +``` + +## Common Patterns + +### SSO Integration + +1. Configure Vault OIDC provider +2. Register applications as OIDC clients +3. Applications redirect to Vault for authentication +4. Vault issues identity tokens with entity claims + +### Cross-Auth Method Identity + +1. Create entity for each user +2. Create aliases for each auth method (LDAP, GitHub, OIDC, etc.) +3. Assign policies to entities or groups +4. Users get consistent access regardless of login method + +## Troubleshooting + +| Issue | Cause | Resolution | +|-------|-------|------------| +| Entity policies not applied | Alias not linked | Verify entity-alias exists | +| Group policies missing | Entity not in group | Check member_entity_ids | +| OIDC token empty claims | Template syntax error | Validate template JSON | +| External group not working | Mount accessor wrong | Get accessor from auth/method/tune | diff --git a/vault/app-access/skills/identity-system/references/identity-system.md b/vault/app-access/skills/identity-system/references/identity-system.md new file mode 100644 index 0000000..cc082e1 --- /dev/null +++ b/vault/app-access/skills/identity-system/references/identity-system.md @@ -0,0 +1,120 @@ +--- +name: identity-system +description: Reference documentation for Vault identity secrets engine, entities, groups, and OIDC provider. +--- + +# Identity System Reference + +## Core Components + +| Component | Description | +|-----------|-------------| +| Entity | Represents a user or machine across auth methods | +| Alias | Maps auth method login to an entity | +| Group (Internal) | Manual entity membership | +| Group (External) | Auth method controlled membership | +| Identity Token | OIDC-compliant JWT | +| OIDC Provider | Full OIDC IdP functionality | + +## Entity API + +| Method | Path | Description | +|--------|------|-------------| +| POST | `/identity/entity` | Create entity | +| GET | `/identity/entity/id/:id` | Read by ID | +| GET | `/identity/entity/name/:name` | Read by name | +| LIST | `/identity/entity/name` | List entities | +| DELETE | `/identity/entity/id/:id` | Delete entity | +| POST | `/identity/entity/merge` | Merge entities | + +## Alias API + +| Method | Path | Description | +|--------|------|-------------| +| POST | `/identity/entity-alias` | Create alias | +| GET | `/identity/entity-alias/id/:id` | Read alias | +| LIST | `/identity/entity-alias/id` | List aliases | +| DELETE | `/identity/entity-alias/id/:id` | Delete alias | + +## Group API + +| Method | Path | Description | +|--------|------|-------------| +| POST | `/identity/group` | Create group | +| GET | `/identity/group/id/:id` | Read by ID | +| GET | `/identity/group/name/:name` | Read by name | +| LIST | `/identity/group/name` | List groups | + +## Group Types + +### Internal Groups + +- Membership controlled by Vault operators +- Entities added via `member_entity_ids` +- Use for cross-auth-method grouping + +### External Groups + +- Membership controlled by auth method +- Linked via group alias to external group +- Automatically synced on authentication + +## Identity Token (OIDC) Flow + +1. Create OIDC key with signing algorithm +2. Create role with template and key reference +3. Entity authenticates and reads token +4. Token contains claims from template + +## OIDC Key Configuration + +| Option | Description | +|--------|-------------| +| `algorithm` | RS256, RS384, RS512, ES256, ES384, ES512, EdDSA | +| `rotation_period` | How often to rotate signing key | +| `verification_ttl` | How long old keys remain valid | + +## Template Variables + +```json +{ + "sub": "{{identity.entity.id}}", + "name": "{{identity.entity.name}}", + "groups": {{identity.entity.groups.names}}, + "metadata": "{{identity.entity.metadata}}" +} +``` + +Available variables: +- `identity.entity.id` +- `identity.entity.name` +- `identity.entity.metadata.` +- `identity.entity.aliases` +- `identity.entity.groups.ids` +- `identity.entity.groups.names` + +## Lookup API + +| Method | Path | Description | +|--------|------|-------------| +| POST | `/identity/lookup/entity` | Lookup entity by criteria | +| POST | `/identity/lookup/group` | Lookup group by criteria | + +## Mount Accessor + +Required for alias creation: + +```bash +# Get accessor for auth method +vault auth list -detailed +# or +vault read sys/auth/ldap | grep accessor +``` + +## Policy Inheritance + +Entities and groups can have policies attached: +1. Token inherits entity policies +2. Token inherits group policies (all groups entity belongs to) +3. Policies are additive to token's existing policies +4. Computed dynamically at request time diff --git a/vault/app-access/skills/policies/SKILL.md b/vault/app-access/skills/policies/SKILL.md new file mode 100644 index 0000000..8f01e8c --- /dev/null +++ b/vault/app-access/skills/policies/SKILL.md @@ -0,0 +1,239 @@ +--- +name: policies +description: Write Vault HCL policies for access control. Use when asked about ACL policies, policy syntax, capabilities (read, write, list, delete, sudo), templated policies, path patterns, Sentinel policies (Enterprise), or troubleshooting permission denied errors. +--- + +# Vault Policies + +## What Are You Trying to Solve? + +### "My app needs read-only access to specific secrets" +→ Create a **scoped application policy**. [Jump to Application Policy](#application-policy) + +### "I'm getting 'permission denied' errors" +→ Debug using **capabilities check and audit logs**. [Jump to Debugging](#debugging-policies) + +### "Each user/team needs their own secret namespace" +→ Use **templated policies** with identity. [Jump to Templated Policies](#templated-policies) + +### "I need operators to manage Vault without root access" +→ Create an **operator policy** with limited sudo. [Jump to Operator Policy](#operator-policy) + +### "CI/CD needs secrets but shouldn't modify production" +→ Create a **CI/CD policy with deny rules**. [Jump to CI/CD Policy](#cicd-pipeline-policy) + +--- + +## How Vault Policies Work + +1. **Define paths** → Specify API paths the policy controls (`secret/data/myapp/*`) +2. **Grant capabilities** → What operations are allowed (read, create, update, delete, list) +3. **Attach to tokens** → Policies bind to tokens via auth methods or directly +4. **Evaluate on request** → Vault checks all attached policies; any match = allowed (except deny) + +**Key insight:** Policies are *default deny*. If no policy grants access to a path, access is denied. + +--- + +## Capability Reference + +| Capability | Description | Common Use | +|------------|-------------|------------| +| `read` | Read data from path | Apps reading secrets | +| `create` | Create new data | First write to path | +| `update` | Modify existing data | Update secrets | +| `delete` | Delete data | Cleanup, rotation | +| `list` | List paths | Browse secret tree | +| `sudo` | Override deny, root paths | Operators (seal/unseal) | +| `deny` | Explicitly block (overrides all) | Protect sensitive paths | + +--- + +## Reference + +- [Vault Policies Documentation](https://developer.hashicorp.com/vault/docs/concepts/policies) +- For complete policy syntax and advanced templating patterns, see [references/policies.md](references/policies.md) + +--- + +## Quick Reference + +### Basic Policy Structure + +```hcl +# Allow read access to application secrets +path "secret/data/myapp/*" { + capabilities = ["read", "list"] +} + +# Allow dynamic database credentials +path "database/creds/readonly" { + capabilities = ["read"] +} + +# Deny access to admin secrets +path "secret/data/admin/*" { + capabilities = ["deny"] +} +``` + +### KV v2 Policy Paths + +KV v2 requires `/data/` in the path: + +```hcl +# Read secrets (note: /data/ prefix for actual secrets) +path "secret/data/myapp/*" { + capabilities = ["read"] +} + +# List secrets (uses /metadata/ prefix) +path "secret/metadata/myapp/*" { + capabilities = ["list"] +} + +# Full access to KV v2 +path "secret/data/myapp/*" { + capabilities = ["create", "read", "update", "delete"] +} +path "secret/metadata/myapp/*" { + capabilities = ["list", "read", "delete"] +} +``` + +### Templated Policies + +Use identity information for dynamic paths: + +```hcl +# Each user gets their own secret namespace +path "secret/data/users/{{identity.entity.name}}/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +# Team-based access using groups +path "secret/data/teams/{{identity.groups.names}}/*" { + capabilities = ["read", "list"] +} +``` + +--- + +## Common Patterns + +### Application Policy + +```hcl +# Typical application policy +path "secret/data/myapp/config" { + capabilities = ["read"] +} + +path "database/creds/myapp-readonly" { + capabilities = ["read"] +} + +path "auth/token/renew-self" { + capabilities = ["update"] +} + +path "auth/token/lookup-self" { + capabilities = ["read"] +} +``` + +### Operator Policy + +```hcl +# Operations team policy +path "sys/health" { + capabilities = ["read"] +} + +path "sys/policies/*" { + capabilities = ["read", "list"] +} + +path "auth/*" { + capabilities = ["read", "list"] +} + +# Seal/unseal requires sudo +path "sys/seal" { + capabilities = ["sudo", "update"] +} +``` + +### CI/CD Pipeline Policy + +```hcl +# Read secrets for deployment +path "secret/data/deployment/*" { + capabilities = ["read"] +} + +# Generate cloud credentials +path "aws/creds/deploy" { + capabilities = ["read"] +} + +# No write access to production secrets +path "secret/data/production/*" { + capabilities = ["deny"] +} +``` + +--- + +## Policy Management + +```bash +# Create/update policy from file +vault policy write app-policy policy.hcl + +# List policies +vault policy list + +# Read policy +vault policy read app-policy + +# Delete policy +vault policy delete app-policy + +# Check token capabilities +vault token capabilities secret/data/myapp +``` + +--- + +## Debugging Policies + +```bash +# Check current token's policies +vault token lookup + +# Test capabilities for a specific path +vault token capabilities secret/data/myapp/config + +# Enable audit logging to see denied requests +vault audit enable file file_path=/var/log/vault-audit.log +``` + +Common issues: +- **KV v2**: Policy path needs `/data/` but CLI doesn't (`vault kv get secret/myapp`) +- **Missing `list`**: Need `list` capability to see path contents +- **Glob patterns**: `*` matches within a path segment, use explicit paths when possible + +--- + +## Best Practices + +- **Least privilege**: Start with minimal permissions, add as needed +- **Use templated policies** for user/team-specific paths +- **Separate policies by use case** (app, operator, admin) +- **Test policies** before applying to production +- **Enable audit logging** to track access patterns + +--- + +For advanced patterns including Sentinel policies (Enterprise), response wrapping policies, and CI/CD integration, see [references/policies.md](references/policies.md). diff --git a/vault/app-access/skills/policies/references/policies.md b/vault/app-access/skills/policies/references/policies.md new file mode 100644 index 0000000..f73314a --- /dev/null +++ b/vault/app-access/skills/policies/references/policies.md @@ -0,0 +1,609 @@ +--- +name: vault-policies +description: Detailed guidance on writing and managing Vault ACL policies and Sentinel policies +--- + +# Vault Policies + +This reference provides detailed guidance on writing and managing Vault policies. + +--- + +## Overview + +Policies define **what actions** are allowed on **which paths**. They are written in HCL (HashiCorp Configuration Language) and attached to tokens via authentication. + +### Policy Evaluation + +- **Default deny**: If no policy grants access, the operation is denied +- **Additive**: Multiple policies combine permissions (most permissive wins) +- **Root token**: Bypasses all policy checks (avoid in production) + +--- + +## Policy Syntax + +### Basic Structure + +```hcl +# Comment describing the policy +path "" { + capabilities = ["", ...] +} +``` + +### Capabilities + +| Capability | HTTP Verb | Description | +| ------------ | ----------- | ------------- | +| `create` | POST | Create new data | +| `read` | GET | Read data | +| `update` | POST/PUT | Modify existing data | +| `delete` | DELETE | Delete data | +| `list` | LIST | List keys at path | +| `sudo` | - | Access protected endpoints | +| `deny` | - | Explicitly deny (overrides all) | + +--- + +## Path Patterns + +> **Important for KV v2**: Policy paths must include `/data/` for secrets access. +> For example, if your secret is at `secret/myapp/config`, the policy path is `secret/data/myapp/config`. +> The CLI hides this, but policies require the full path. + +### Exact Match + +```hcl +# Only matches exactly secret/data/myapp/config +path "secret/data/myapp/config" { + capabilities = ["read"] +} +``` + +### Glob Patterns + +```hcl +# Matches any immediate child +path "secret/data/myapp/*" { + capabilities = ["read", "list"] +} + +# Matches all descendants (recursive) +path "secret/data/myapp/+" { + capabilities = ["read"] +} +``` + +### Segment Wildcards + +```hcl +# + matches exactly one path segment +path "secret/data/+/config" { + capabilities = ["read"] +} +# Matches: secret/data/app1/config, secret/data/app2/config +# Not: secret/data/app1/nested/config +``` + +--- + +## Common Policy Examples + +### Application Read-Only + +```hcl +# Read application secrets +path "secret/data/myapp/*" { + capabilities = ["read", "list"] +} + +# Allow token self-management +path "auth/token/renew-self" { + capabilities = ["update"] +} + +path "auth/token/lookup-self" { + capabilities = ["read"] +} +``` + +### Application Read-Write + +```hcl +path "secret/data/myapp/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +path "secret/metadata/myapp/*" { + capabilities = ["read", "list", "delete"] +} +``` + +### Database Credentials + +```hcl +# Generate dynamic database credentials +path "database/creds/readonly" { + capabilities = ["read"] +} + +# Manage leases +path "sys/leases/renew" { + capabilities = ["update"] +} + +path "sys/leases/revoke" { + capabilities = ["update"] +} +``` + +### AWS Credentials + +```hcl +path "aws/creds/deploy" { + capabilities = ["read"] +} + +path "aws/sts/deploy" { + capabilities = ["read"] +} +``` + +### PKI Certificate Issuance + +```hcl +# Issue certificates +path "pki_int/issue/web-servers" { + capabilities = ["create", "update"] +} + +# Read CA certificate +path "pki_int/ca/pem" { + capabilities = ["read"] +} + +path "pki_int/cert/ca" { + capabilities = ["read"] +} +``` + +### Transit Encryption + +```hcl +# Encrypt data +path "transit/encrypt/my-key" { + capabilities = ["update"] +} + +# Decrypt data +path "transit/decrypt/my-key" { + capabilities = ["update"] +} +``` + +### Admin Policy + +```hcl +# Full access to secrets +path "secret/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +# Manage policies +path "sys/policies/acl/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +# Manage auth methods +path "sys/auth/*" { + capabilities = ["create", "read", "update", "delete", "list", "sudo"] +} + +# Manage secrets engines +path "sys/mounts/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +# Access audit logs +path "sys/audit/*" { + capabilities = ["create", "read", "update", "delete", "list", "sudo"] +} +``` + +--- + +## Templated Policies + +Use identity information to create dynamic policies. + +### Entity Templates + +```hcl +# Each entity gets their own path +path "secret/data/users/{{identity.entity.id}}/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} + +# Use entity name +path "secret/data/teams/{{identity.entity.name}}/*" { + capabilities = ["read", "list"] +} +``` + +### Entity Metadata + +```hcl +# Use custom metadata +path "secret/data/projects/{{identity.entity.metadata.project}}/*" { + capabilities = ["read"] +} +``` + +### Group Templates + +```hcl +# Group-based access +path "secret/data/groups/{{identity.groups.names}}/*" { + capabilities = ["read", "list"] +} +``` + +### Auth Method Templates + +```hcl +# Access based on auth method alias +path "secret/data/{{identity.entity.aliases.auth_kubernetes.metadata.service_account_namespace}}/*" { + capabilities = ["read"] +} +``` + +--- + +## Required Parameters + +Restrict which keys can be set. + +```hcl +path "secret/data/restricted/*" { + capabilities = ["create", "update"] + required_parameters = ["reason", "requester"] +} +``` + +--- + +## Allowed Parameters + +Limit which keys can be written. + +```hcl +path "secret/data/config/*" { + capabilities = ["create", "update"] + allowed_parameters = { + "data" = ["username", "password", "api_key"] + } +} +``` + +--- + +## Denied Parameters + +Prevent specific keys from being set. + +```hcl +path "secret/data/*" { + capabilities = ["create", "update"] + denied_parameters = { + "data" = ["admin_password", "root_key"] + } +} +``` + +> **Note**: Parameter constraints (`required_parameters`, `allowed_parameters`, `denied_parameters`) +> only apply to `create` and `update` operations. They cannot restrict `read` access to specific fields. + +--- + +## Min/Max Wrapping TTL + +Control response wrapping to ensure secrets are consumed securely. + +```hcl +path "secret/data/sensitive/*" { + capabilities = ["read"] + min_wrapping_ttl = "1m" + max_wrapping_ttl = "10m" +} +``` + +### Response Wrapping Best Practices + +| Setting | Purpose | Recommended Value | +| -------------------- | --------------------------- | ----------------- | +| `min_wrapping_ttl` | Prevent unwrapped responses | 60s or higher | +| `max_wrapping_ttl` | Limit exposure window | 10-15 minutes max | + +```hcl +# Force wrapping for AppRole secret_id retrieval (Trusted Broker pattern) +path "auth/approle/role/+/secret-id" { + capabilities = ["update"] + min_wrapping_ttl = "60s" + max_wrapping_ttl = "300s" +} +``` + +--- + +## CI/CD Pipeline Policies + +### Trusted Broker Pattern Policies + +Based on the AppRole Trusted Broker architecture pattern: + +#### Controller/Orchestrator Policy + +The CI/CD controller (Jenkins master, GitLab coordinator) needs: + +```hcl +# Policy: cicd-controller +# Purpose: Allow CI controller to fetch wrapped secret_ids for jobs + +# Read role-id (public, can be in config) +path "auth/approle/role/+/role-id" { + capabilities = ["read"] +} + +# Generate wrapped secret-id (MUST be wrapped) +path "auth/approle/role/+/secret-id" { + capabilities = ["update"] + min_wrapping_ttl = "60s" + max_wrapping_ttl = "300s" +} + +# Lookup wrapping token info (for validation) +path "sys/wrapping/lookup" { + capabilities = ["update"] +} +``` + +#### Worker/Runner Policy + +Individual build agents get limited, wrapped credentials: + +```hcl +# Policy: cicd-worker +# Purpose: Application-specific access for build jobs + +# Read application secrets +path "secret/data/apps/{{identity.entity.metadata.app_name}}/*" { + capabilities = ["read"] +} + +# Get dynamic database credentials for testing +path "database/creds/ci-readonly" { + capabilities = ["read"] +} + +# Manage own leases +path "sys/leases/renew-self" { + capabilities = ["update"] +} + +path "auth/token/renew-self" { + capabilities = ["update"] +} +``` + +#### Jenkins Integration Example + +```hcl +# Policy: jenkins-master +# Jenkins master distributes credentials to agents + +path "auth/approle/role/jenkins-agent-*/secret-id" { + capabilities = ["update"] + min_wrapping_ttl = "120s" + max_wrapping_ttl = "300s" +} + +path "auth/approle/role/jenkins-agent-*/role-id" { + capabilities = ["read"] +} + +# Token introspection for cleanup +path "auth/token/lookup-accessor" { + capabilities = ["update"] +} + +path "auth/token/revoke-accessor" { + capabilities = ["update"] +} +``` + +### GitHub Actions Integration + +```hcl +# Policy: github-actions +# For GitHub Actions OIDC integration + +# Read secrets for the repository +path "secret/data/github/{{identity.entity.aliases.auth_jwt.metadata.repository}}/*" { + capabilities = ["read"] +} + +# Environment-specific paths +path "secret/data/github/{{identity.entity.aliases.auth_jwt.metadata.repository}}/{{identity.entity.aliases.auth_jwt.metadata.environment}}/*" { + capabilities = ["read"] +} +``` + +### GitLab CI Integration + +```hcl +# Policy: gitlab-ci +# For GitLab CI JWT integration + +path "secret/data/gitlab/{{identity.entity.aliases.auth_jwt.metadata.project_path}}/*" { + capabilities = ["read"] +} + +# Restrict to protected branches only +# (Combine with Sentinel for branch checks) +``` + +--- + +## Policy Anti-Patterns to Avoid + +| Anti-Pattern | Problem | Correct Approach | +| -------------- | --------- | ------------------ | +| `path "*"` | Too broad, security risk | Use specific paths | +| `capabilities = ["sudo"]` everywhere | Bypasses controls | Only for sys/ paths that require it | +| Sharing policies across apps | Violates least privilege | One policy per app/role | +| Hardcoded paths | Doesn't scale | Use templated policies | +| No `min_wrapping_ttl` on secret-id | Secrets in plain text | Always wrap secret-id | + +--- + +## Policy Management Commands + +```bash +# Write policy from file +vault policy write app-policy app-policy.hcl + +# Write policy inline +vault policy write test-policy - < secret/data/myapp/config +``` + +### Lookup Token Policies + +```bash +vault token lookup +# Shows attached policies + +vault token lookup -accessor +``` + +### Common Issues + +**Permission denied on valid path**: + +- Check KV v2 paths include `/data/` segment +- Verify policy uses correct path pattern +- Check for `deny` capability in other policies + +**Can list but not read**: + +- `list` and `read` are separate capabilities +- Add `read` capability to policy + +**Wildcard not matching**: + +- `*` matches immediate children only +- Use `+` for recursive matching + +--- + +## Sentinel Policies (Enterprise) + +Fine-grained policy-as-code using Sentinel language. + +### Endpoint Governing Policies (EGP) + +Applied to specific paths. + +```sentinel +# Require MFA for sensitive paths +import "mfa" + +main = rule { + mfa.methods.totp.valid +} +``` + +### Role Governing Policies (RGP) + +Applied to specific identities. + +```sentinel +# Restrict access by time +import "time" + +main = rule { + time.now.hour >= 9 and time.now.hour < 17 +} +``` + +### Sentinel Policy Management + +```bash +# Write Sentinel policy +vault write sys/policies/egp/business-hours \ + policy=@policy.sentinel \ + paths="secret/data/prod/*" \ + enforcement_level="hard-mandatory" + +# Enforcement levels: advisory, soft-mandatory, hard-mandatory +``` + +--- + +## Best Practices + +1. **Principle of least privilege**: Grant minimum necessary access +2. **Use path patterns**: Avoid overly broad wildcards +3. **Separate policies by function**: Don't combine unrelated permissions +4. **Use templates**: Leverage identity templating for scalability +5. **Test policies**: Verify with `vault token capabilities` +6. **Version control**: Store policies in git +7. **Document policies**: Include comments explaining intent +8. **Regular audits**: Review policies periodically +9. **Use Sentinel**: Add business logic for complex requirements (Enterprise) + +--- + +## Additional Resources + +- [Policies Documentation](https://developer.hashicorp.com/vault/docs/concepts/policies) +- [Policy Tutorial](https://developer.hashicorp.com/vault/tutorials/policies) +- [Sentinel Documentation](https://developer.hashicorp.com/vault/docs/enterprise/sentinel) + +--- + +## Related + +- [Auth Methods](auth-methods.md) - Authentication methods that policies attach to +- [Secrets Engines](secrets-engines.md) - Paths that policies protect +- [Enterprise](enterprise.md) - Sentinel policies and namespaces diff --git a/vault/app-access/skills/response-wrapping/SKILL.md b/vault/app-access/skills/response-wrapping/SKILL.md new file mode 100644 index 0000000..dee2a37 --- /dev/null +++ b/vault/app-access/skills/response-wrapping/SKILL.md @@ -0,0 +1,234 @@ +--- +name: response-wrapping +description: Use when working with Vault response wrapping, cubbyhole secrets, secure secret distribution, wrapped tokens, or bootstrap workflows. Covers wrap/unwrap operations and malfeasance detection. +--- + +# Response Wrapping and Cubbyhole + +## What Are You Trying to Solve? + +### "I need to securely hand off a secret to a new service" +→ Use **response wrapping** with wrapped tokens. [Jump to Bootstrap Workflow](#bootstrap-workflow) + +### "I need single-use, time-limited secret delivery" +→ **Wrap the response** with a short TTL. [Jump to Wrap Any Response](#wrap-any-response) + +### "I need to detect if someone intercepted my secret" +→ Use **malfeasance detection** (second unwrap fails). [Jump to Malfeasance Detection](#malfeasance-detection) + +### "I need private storage scoped to a single token" +→ Use **cubbyhole** for token-scoped secrets. [Jump to Cubbyhole](#cubbyhole-secrets-engine) + +--- + +## How Response Wrapping Works + +1. **Request with wrap** → Add `-wrap-ttl=5m` to any Vault command +2. **Vault stores response** → Response stored in wrapping token's cubbyhole +3. **Wrapped token returned** → You get a single-use token instead of the secret +4. **Recipient unwraps** → Recipient uses token exactly once to retrieve secret +5. **Token destroyed** → After unwrap, token and cubbyhole are gone forever + +**Key insight:** If unwrap fails, someone already used the token—you've detected interception. + +--- + +## Secure Handoff Pattern + +``` +┌──────────┐ wrapped token ┌──────────┐ +│ Operator │ ─────────────────────► │ Service │ +└──────────┘ └────┬─────┘ + │ + │ unwrap (once) + ▼ + ┌──────────┐ + │ Vault │ + └──────────┘ +``` + +--- + +## Wrapping TTL Guidelines + +| Scenario | Recommended TTL | +|----------|-----------------| +| Interactive handoff (human) | 5-15 minutes | +| Automated bootstrap | 1-24 hours | +| Scheduled deployment | Match deployment window | +| Emergency/sensitive access | 30 seconds - 5 minutes | + +--- + +## Reference + +- [Response Wrapping](https://developer.hashicorp.com/vault/docs/concepts/response-wrapping) +- [Cubbyhole Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/cubbyhole) +- For complete wrapping workflows and security patterns, see [references/response-wrapping.md](references/response-wrapping.md) + +## Cubbyhole Secrets Engine + +Every token has its own private cubbyhole storage: + +```bash +# Write to current token's cubbyhole +vault write cubbyhole/my-secret value="sensitive-data" + +# Read from cubbyhole +vault read cubbyhole/my-secret + +# Cubbyhole is destroyed when token expires or is revoked +``` + +**Key Properties:** +- Scoped to the token - no other token can access it +- Not shared across token hierarchies +- Automatically destroyed with the token +- Cannot be listed by other tokens + +## Response Wrapping + +### Wrap Any Response + +```bash +# Wrap a secret read with 5-minute TTL +vault read -wrap-ttl=5m secret/data/myapp + +# Returns wrapped token instead of secret +Key Value +--- ----- +wrapping_token: hvs.CAES... +wrapping_accessor: 8WxD3y... +wrapping_token_ttl: 5m +wrapping_token_creation_time: 2024-01-15T10:30:00Z +wrapping_token_creation_path: secret/data/myapp +``` + +### Unwrap a Wrapped Token + +```bash +# Recipient unwraps to get the original response +vault unwrap hvs.CAES... + +# Or using the environment +VAULT_TOKEN=hvs.CAES... vault unwrap +``` + +### Wrap Arbitrary Data + +```bash +# Wrap arbitrary JSON data +vault write -wrap-ttl=1h sys/wrapping/wrap data='{"api_key":"secret123"}' +``` + +## API Examples + +### Create Wrapped Response + +```bash +curl -X GET \ + -H "X-Vault-Token: $VAULT_TOKEN" \ + -H "X-Vault-Wrap-TTL: 300" \ + $VAULT_ADDR/v1/secret/data/myapp +``` + +### Unwrap Token + +```bash +curl -X POST \ + -H "X-Vault-Token: hvs.wrapped_token" \ + $VAULT_ADDR/v1/sys/wrapping/unwrap +``` + +### Look Up Wrapped Token Properties + +```bash +curl -X POST \ + -H "X-Vault-Token: $VAULT_TOKEN" \ + -d '{"token": "hvs.wrapped_token"}' \ + $VAULT_ADDR/v1/sys/wrapping/lookup +``` + +## Malfeasance Detection + +If someone intercepts and unwraps a token before the intended recipient: + +```bash +# Second unwrap attempt fails with clear indication +vault unwrap hvs.previously_unwrapped + +Error: wrapping token is not valid or does not exist +``` + +The original sender can verify delivery by: +1. Storing the wrapping accessor +2. Checking if the token was unwrapped by the expected entity +3. Detecting if unwrap happened from unexpected source + +## Bootstrap Workflow + +### Service Bootstrap with Wrapped Token + +```bash +# 1. Operator creates wrapped approle credentials +vault write -wrap-ttl=24h -f auth/approle/role/myapp/secret-id + +# 2. Deliver wrapped token to new service (secure channel) +# 3. Service unwraps on first boot +vault unwrap hvs.wrapped_secretid + +# 4. Service authenticates with unwrapped secret-id +vault write auth/approle/login \ + role_id="role-id" \ + secret_id="unwrapped-secret-id" +``` + +### Secure Handoff Pattern + +``` +┌──────────┐ wrapped token ┌──────────┐ +│ Operator │ ─────────────────────► │ Service │ +└──────────┘ └────┬─────┘ + │ + │ unwrap (once) + ▼ + ┌──────────┐ + │ Vault │ + └──────────┘ +``` + +## Wrapping TTL Best Practices + +| Use Case | Recommended TTL | +|----------|-----------------| +| Interactive handoff | 5-15 minutes | +| Automated bootstrap | 1-24 hours | +| Scheduled deployment | Match deployment window | +| Emergency access | 30 seconds - 5 minutes | + +## Common Patterns + +### Wrap Token Creation + +```bash +# Create wrapped token for another service +vault token create \ + -wrap-ttl=1h \ + -policy=app-policy \ + -ttl=4h +``` + +### Rewrap for Extended Delivery + +```bash +# Rewrap an existing wrapped token with new TTL +vault write sys/wrapping/rewrap token="hvs.old_wrapped" +``` + +## Troubleshooting + +| Issue | Cause | Resolution | +|-------|-------|------------| +| "wrapping token is not valid" | Already unwrapped or expired | Generate new wrapped response | +| "permission denied" | Token lacks unwrap permission | Use token with appropriate policy | +| Empty response on unwrap | Original secret was empty | Verify source secret exists | diff --git a/vault/app-access/skills/response-wrapping/references/response-wrapping.md b/vault/app-access/skills/response-wrapping/references/response-wrapping.md new file mode 100644 index 0000000..8a1ae82 --- /dev/null +++ b/vault/app-access/skills/response-wrapping/references/response-wrapping.md @@ -0,0 +1,73 @@ +--- +name: response-wrapping +description: Reference documentation for Vault response wrapping, cubbyhole secrets, and secure secret distribution patterns. +--- + +# Response Wrapping Reference + +## Core Concepts + +### Cubbyhole Secrets Engine + +The cubbyhole secrets engine provides private, token-scoped secret storage: + +- **Token Isolation**: Each token has its own cubbyhole that no other token can access +- **Automatic Cleanup**: Cubbyhole is destroyed when the token expires or is revoked +- **No Hierarchy**: Child tokens cannot access parent's cubbyhole +- **Default Enabled**: Mounted at `cubbyhole/` by default, cannot be disabled + +### Response Wrapping Mechanism + +1. Client requests wrapped response with `X-Vault-Wrap-TTL` header +2. Vault generates a single-use wrapping token +3. Original response is stored in the wrapping token's cubbyhole +4. Client receives wrapping token instead of original response +5. Recipient unwraps token to retrieve original response +6. Wrapping token is immediately invalidated after unwrap + +## CLI Reference + +| Command | Description | +|---------|-------------| +| `vault read -wrap-ttl= ` | Read and wrap response | +| `vault write -wrap-ttl= ` | Write and wrap response | +| `vault unwrap [token]` | Unwrap wrapped token | +| `vault token create -wrap-ttl=` | Create and wrap new token | + +## API Endpoints + +| Method | Path | Description | +|--------|------|-------------| +| POST | `/sys/wrapping/wrap` | Wrap arbitrary data | +| POST | `/sys/wrapping/unwrap` | Unwrap wrapped token | +| POST | `/sys/wrapping/lookup` | Look up wrapping token properties | +| POST | `/sys/wrapping/rewrap` | Rewrap with new wrapping token | + +## Wrapping Token Properties + +```json +{ + "wrapping_token": "hvs.CAESIFhP...", + "wrapping_accessor": "abc123...", + "wrapping_token_ttl": 300, + "wrapping_token_creation_time": "2024-01-15T10:00:00Z", + "wrapping_token_creation_path": "secret/data/myapp" +} +``` + +## Security Considerations + +1. **Single Use**: Wrapped tokens can only be unwrapped once +2. **TTL Limits**: Set appropriate TTL based on delivery time +3. **Malfeasance Detection**: Failed unwrap indicates interception +4. **Creation Path**: Stored for audit purposes, reveals original request path +5. **No Renewal**: Wrapping tokens cannot be renewed + +## Use Cases + +| Scenario | Recommended TTL | +|----------|-----------------| +| Interactive handoff | 5-15 minutes | +| Service bootstrap | 30 minutes - 24 hours | +| Automated deployment | Match deployment window | +| Emergency credential | 1-5 minutes | diff --git a/vault/app-access/skills/token-management/SKILL.md b/vault/app-access/skills/token-management/SKILL.md new file mode 100644 index 0000000..ac2ccf4 --- /dev/null +++ b/vault/app-access/skills/token-management/SKILL.md @@ -0,0 +1,268 @@ +--- +name: token-management +description: Use when working with Vault token types, creating periodic or batch tokens, managing token accessors, orphan tokens, or token lifecycle. Covers service vs batch tokens and renewal strategies. +--- + +# Token Management + +## What Are You Trying to Solve? + +### "My app needs a simple, renewable token" +→ Use **service tokens** (default). [Jump to Service Tokens](#service-tokens) + +### "I have high-scale ephemeral workloads (serverless, short-lived pods)" +→ Use **batch tokens** for minimal overhead. [Jump to Batch Tokens](#batch-tokens) + +### "My service runs indefinitely and must not lose access" +→ Use **periodic tokens** that never expire if renewed. [Jump to Periodic Tokens](#periodic-tokens) + +### "I need token to survive parent revocation" +→ Use **orphan tokens** for independent lifecycle. [Jump to Orphan Tokens](#orphan-tokens) + +### "I need to revoke a token without exposing its value" +→ Use **token accessors** for safe revocation. [Jump to Token Accessors](#token-accessors) + +--- + +## How Vault Tokens Work + +1. **Authentication** → Client authenticates via auth method +2. **Token issued** → Vault returns token with policies and TTL +3. **Token usage** → Client uses token for API requests +4. **Renewal/Expiry** → Token must be renewed before TTL or it expires +5. **Revocation** → Token and all children revoked (unless orphan) + +--- + +## Token Type Selection + +| Your Workload | Token Type | Why | +|---------------|------------|-----| +| Standard app, needs renewal | Service | Full features, stored in Vault | +| Serverless, short-lived pods | Batch | Lightweight, no storage overhead | +| Long-running daemon | Periodic | Renewable forever if renewed in time | +| Independent of parent | Orphan | Won't be revoked with parent | +| Pre-approved parameters | Role-based | Enforce TTL, policies, orphan status | + +--- + +## Token Prefixes + +``` +hvs. - Service token +hvb. - Batch token +hvr. - Recovery token +``` + +--- + +## Reference + +- [Token Concepts](https://developer.hashicorp.com/vault/docs/concepts/tokens) +- [Token Auth Method](https://developer.hashicorp.com/vault/docs/auth/token) +- For complete token lifecycle patterns and accessor management, see [references/token-management.md](references/token-management.md) + +## Service Tokens + +Standard tokens with full features: + +```bash +# Create service token (default) +vault token create -policy=myapp -ttl=4h + +# Create with explicit type +vault token create -type=service -policy=myapp + +# Renew before expiration +vault token renew hvs.token_value + +# Or self-renew +vault token renew +``` + +## Batch Tokens + +Lightweight, no storage overhead: + +```bash +# Create batch token +vault token create -type=batch -policy=myapp -ttl=1h + +# Batch tokens cannot be renewed +# They expire at TTL, period + +# Best for: +# - Serverless functions +# - Kubernetes pods with short lifespans +# - High-throughput automation +``` + +## Periodic Tokens + +Never expire if renewed within period: + +```bash +# Create periodic token (requires sudo/root) +vault token create -period=24h -policy=myapp + +# Token TTL resets to period on each renewal +vault token renew hvs.periodic_token + +# Use for: +# - Long-running services +# - Database connection pools +# - Background workers +``` + +## Orphan Tokens + +Independent of parent token lifecycle: + +```bash +# Create orphan token +vault token create -orphan -policy=myapp + +# Or via token store role +vault write auth/token/roles/orphan-role orphan=true +vault token create -role=orphan-role + +# Orphan tokens are NOT revoked when parent is revoked +``` + +## Token Accessors + +Reference tokens without exposing values: + +```bash +# Get accessor when creating token +vault token create -policy=myapp +# Key Value +# token_accessor abc123xyz + +# Lookup token by accessor +vault token lookup -accessor abc123xyz + +# Revoke by accessor (safer for automation) +vault token revoke -accessor abc123xyz + +# List all accessors (requires root/sudo) +vault list auth/token/accessors +``` + +## Token Capabilities + +Check what a token can do: + +```bash +# Check current token's capabilities on a path +vault token capabilities secret/data/myapp + +# Check specific token's capabilities +vault token capabilities -accessor abc123 secret/data/myapp + +# Self-check +vault token lookup +``` + +## Token Renewal Strategies + +### Manual Renewal + +```bash +# Renew with default increment +vault token renew + +# Renew with specific increment +vault token renew -increment=1h + +# Renew another token +vault token renew hvs.other_token +``` + +### Programmatic Renewal + +```go +// Go example with vault client +client.Auth().Token().RenewSelf(3600) +``` + +### Renewal Considerations + +``` +┌─────────────────────────────────────────────────────────┐ +│ Token Lifetime │ +├──────────────┬──────────────────────────────────────────┤ +│ Created │ Max TTL │ +│ │ │ │ │ +│ ▼ │ ▼ │ +│ [────TTL────]───renew──[────TTL────]───renew──[──] │ +│ │ │ +│ Token │ │ +│ Expires │ +└─────────────────────────────────────────────────────────┘ +``` + +## Token Store Roles + +Pre-define token configurations: + +```bash +# Create role for CI/CD tokens +vault write auth/token/roles/cicd \ + allowed_policies="deploy-policy" \ + orphan=true \ + renewable=true \ + token_period=1h \ + token_explicit_max_ttl=24h + +# Create token from role +vault token create -role=cicd +``` + +## Decision Matrix + +| Requirement | Token Type | +|-------------|------------| +| Standard app with renewal | Service | +| High-scale, short-lived | Batch | +| Long-running, must not expire | Periodic | +| Independent lifecycle | Orphan | +| Pre-approved parameters | Role-based | + +## API Examples + +### Create Token + +```bash +curl -X POST \ + -H "X-Vault-Token: $VAULT_TOKEN" \ + -d '{"policies":["myapp"],"ttl":"1h"}' \ + $VAULT_ADDR/v1/auth/token/create +``` + +### Lookup Token + +```bash +curl -X POST \ + -H "X-Vault-Token: $VAULT_TOKEN" \ + -d '{"token":"hvs.target_token"}' \ + $VAULT_ADDR/v1/auth/token/lookup +``` + +### Revoke Token + +```bash +curl -X POST \ + -H "X-Vault-Token: $VAULT_TOKEN" \ + -d '{"token":"hvs.target_token"}' \ + $VAULT_ADDR/v1/auth/token/revoke +``` + +## Troubleshooting + +| Issue | Cause | Resolution | +|-------|-------|------------| +| Token expired unexpectedly | Didn't renew before TTL | Implement renewal loop | +| Cannot renew batch token | Batch tokens are non-renewable | Use service token instead | +| Max TTL prevents renewal | System or mount max_ttl hit | Re-authenticate for new token | +| Orphan token still revoked | Explicit revocation, not parent | Check audit logs | diff --git a/vault/app-access/skills/token-management/references/token-management.md b/vault/app-access/skills/token-management/references/token-management.md new file mode 100644 index 0000000..88a9083 --- /dev/null +++ b/vault/app-access/skills/token-management/references/token-management.md @@ -0,0 +1,116 @@ +--- +name: token-management +description: Reference documentation for Vault token types, lifecycle, and management patterns. +--- + +# Token Management Reference + +## Token Types + +| Type | Prefix | Storage | Renewable | Parent Revocation | +|------|--------|---------|-----------|-------------------| +| Service | `hvs.` | Yes | Yes | Revokes children | +| Batch | `hvb.` | No | No | Stops working | +| Periodic | `hvs.` | Yes | Yes (indefinite) | Revokes children | +| Orphan | `hvs.` | Yes | Yes | Not affected | +| Root | `hvs.` | Yes | Optional | N/A | + +## Token Capabilities + +Service tokens support all capabilities: +- Create child tokens +- Have cubbyholes +- Be renewed +- Be explicitly revoked +- Have explicit max TTL +- Be periodic + +Batch tokens are lightweight but limited: +- No storage overhead +- Cannot create children +- Cannot be renewed +- No cubbyhole +- Scale with standbys + +## CLI Reference + +| Command | Description | +|---------|-------------| +| `vault token create` | Create new token | +| `vault token lookup [token]` | View token details | +| `vault token renew [token]` | Renew token lease | +| `vault token revoke [token]` | Revoke token and children | +| `vault token capabilities ` | Check token permissions | +| `vault list auth/token/accessors` | List all token accessors | + +## Token Creation Flags + +| Flag | Description | +|------|-------------| +| `-type=` | service or batch | +| `-policy=` | Attach policy (repeatable) | +| `-ttl=` | Initial TTL | +| `-explicit-max-ttl=` | Hard limit on lifetime | +| `-period=` | Create periodic token | +| `-orphan` | Create without parent | +| `-renewable=` | Allow renewal (default: true) | +| `-no-parent` | Create orphan (requires sudo) | + +## API Endpoints + +| Method | Path | Description | +|--------|------|-------------| +| POST | `/auth/token/create` | Create token | +| POST | `/auth/token/create-orphan` | Create orphan token | +| POST | `/auth/token/lookup` | Lookup token | +| POST | `/auth/token/lookup-accessor` | Lookup by accessor | +| POST | `/auth/token/renew` | Renew token | +| POST | `/auth/token/revoke` | Revoke token | +| POST | `/auth/token/revoke-orphan` | Revoke, orphan children | +| POST | `/auth/token/revoke-accessor` | Revoke by accessor | +| LIST | `/auth/token/accessors` | List all accessors | + +## Token Store Roles + +Pre-define token parameters: + +```bash +vault write auth/token/roles/cicd \ + allowed_policies="deploy,read" \ + disallowed_policies="admin" \ + orphan=true \ + renewable=true \ + token_period=1h \ + token_explicit_max_ttl=24h \ + token_type=service \ + token_num_uses=0 \ + token_bound_cidrs="10.0.0.0/8" +``` + +## TTL Hierarchy + +1. **System max TTL**: 32 days (default), configurable +2. **Mount max TTL**: Per auth method tuning +3. **Role/Auth max TTL**: Configured on role or auth method +4. **Request TTL**: Requested at token creation +5. **Explicit max TTL**: Hard cap if set + +## Accessor Usage + +Accessors provide safe token references: + +- Lookup token metadata +- Check token capabilities +- Renew token +- Revoke token +- Audit logging + +**Cannot**: Read token value, use token for authentication + +## Root Token Best Practices + +1. Generate only for initial setup or emergencies +2. Use `vault operator generate-root` with quorum +3. Revoke immediately after use +4. Prefer limited tokens for daily operations +5. Multiple witnesses when using root tokens diff --git a/vault/credential-generation/.claude-plugin/plugin.json b/vault/credential-generation/.claude-plugin/plugin.json new file mode 100644 index 0000000..0ccb048 --- /dev/null +++ b/vault/credential-generation/.claude-plugin/plugin.json @@ -0,0 +1,39 @@ +{ + "name": "vault-credential-generation", + "version": "0.2.0", + "description": "Generate dynamic credentials for databases, cloud providers, and encryption keys. Covers KV secrets, database credentials, AWS/Azure/GCP credentials, Transit encryption, PKI certificates, and Vault Agent delivery.", + "author": "HashiCorp", + "homepage": "https://developer.hashicorp.com/vault/docs/secrets", + "repository": "https://github.com/hashicorp/agent-skills", + "license": "MPL-2.0", + "keywords": [ + "vault", + "secrets", + "credentials", + "dynamic-credentials", + "database", + "transit", + "pki", + "vault-agent", + "hashicorp" + ], + "mcpServers": { + "vault": { + "command": "docker", + "args": [ + "run", + "-i", + "--rm", + "-e", + "VAULT_ADDR", + "-e", + "VAULT_TOKEN", + "hashicorp/vault-mcp-server" + ], + "env": { + "VAULT_ADDR": "${VAULT_ADDR}", + "VAULT_TOKEN": "${VAULT_TOKEN}" + } + } + } +} diff --git a/vault/credential-generation/SPEC.md b/vault/credential-generation/SPEC.md new file mode 100644 index 0000000..5c4ef0d --- /dev/null +++ b/vault/credential-generation/SPEC.md @@ -0,0 +1,107 @@ +# Specification: vault-credential-generation + +**Status**: Published +**Version**: 0.2.0 + +--- + +## Overview + +This plugin helps you **generate dynamic credentials** for your applications. Covers database credentials (PostgreSQL, MySQL, MongoDB), cloud credentials (AWS, Azure, GCP), encryption keys (Transit), certificates (PKI), and secret delivery via Vault Agent. + +--- + +## User Stories + +### US-1: Developer Needs Dynamic Database Credentials (P1) + +A developer building an application needs to connect to a PostgreSQL database without hardcoding credentials. They want Vault to generate short-lived database credentials automatically. + +**Why this priority**: Dynamic secrets are Vault's core value proposition. This is the most common enterprise use case. + +**Acceptance Criteria**: +1. Given a user asks about database credential management, when the skill is invoked, then it provides Database secrets engine setup with role configuration and lease/TTL guidance. +2. Given a developer wants to integrate Vault with their app, when they ask for code examples, then the skill provides CLI commands and SDK patterns. +3. Given a user mentions "dynamic secrets," when the skill is invoked, then it explains the concept and lists available dynamic secrets engines. + +### US-2: Security Engineer Needs Encryption Without Key Management (P1) + +A security engineer needs to encrypt sensitive data at rest but doesn't want the application to have access to encryption keys. + +**Acceptance Criteria**: +1. Given a user asks about encryption, when the skill is invoked, then it provides Transit engine setup and encryption/decryption patterns. +2. Given a request for key rotation, when queried, then the skill explains key versioning and rotation procedures. +3. Given a BYOK question, when asked about importing keys, then the skill explains Transit BYOK process. + +### US-3: Platform Engineer Needs PKI for Internal Services (P2) + +A platform engineer needs to issue TLS certificates for internal services from an internal CA. + +**Acceptance Criteria**: +1. Given a user asks about internal CA, when the skill is invoked, then it provides PKI secrets engine setup with root/intermediate CA configuration. +2. Given a certificate automation question, when queried, then the skill explains cert-manager integration and renewal patterns. +3. Given a cross-namespace PKI question, when asked about shared CAs, then the skill explains Enterprise patterns. + +### US-4: Developer Needs Vault Agent for Secret Injection (P1) + +A developer needs to inject secrets into application config files without modifying application code. + +**Acceptance Criteria**: +1. Given a user asks about secret file templating, when the skill is invoked, then it provides Vault Agent configuration with template examples. +2. Given a sidecar question, when queried, then the skill explains Kubernetes sidecar patterns. +3. Given a process supervisor question, when asked about exec mode, then the skill explains process supervisor and env_template. +4. Given a PKI template question, when asked about certificates, then the skill explains the pkiCert template function. + +### US-5: Security Team Enabling SSH Access (P3) + +A security team needs to manage SSH access to infrastructure using Vault's SSH secrets engine. + +**Acceptance Criteria**: +1. Given an SSH access question, when the skill is invoked, then it explains SSH secrets engine modes (OTP, CA, Dynamic Keys). +2. Given a CA mode request, when queried, then the skill provides SSH CA configuration with user and host certificate signing. +3. Given a post-implementation question, when asked, then the skill explains removing authorized_keys and configuring sshd trust. + +--- + +## Functional Requirements + +| ID | Requirement | +|----|-------------| +| FR-001 | Skill MUST cover KV v1 and v2 secrets engine with versioning | +| FR-002 | Skill MUST cover Database secrets engine for PostgreSQL, MySQL, MongoDB | +| FR-003 | Skill MUST explain dynamic roles vs static roles | +| FR-004 | Skill MUST cover Transit encryption with key rotation | +| FR-005 | Skill MUST cover PKI secrets engine with root/intermediate CA | +| FR-006 | Skill MUST cover SSH secrets engine (OTP, CA modes) | +| FR-007 | Skill MUST explain lease management and renewal | +| FR-008 | Skill MUST cover AWS, Azure, GCP credential generation | +| FR-009 | Skill MUST cover Vault Agent auto-auth, caching, templating | +| FR-010 | Skill MUST explain process supervisor mode and env_template | +| FR-011 | Skill MUST cover pkiCert template function | +| FR-012 | Skill MUST cover Secrets Sync (Enterprise) | + +--- + +## Skills Included + +| Skill | Description | +|-------|-------------| +| `secrets-engines` | Configure KV, Database, AWS, Transit, PKI, SSH secrets engines | +| `vault-agent` | Set up auto-auth, caching, templating, and process supervisor | + +--- + +## Content Sources + +- HashiCorp Vault Documentation +- Vault Tutorials +- CSA Enterprise Patterns (genericized) + +--- + +## References + +- [Vault Secrets Engines](https://developer.hashicorp.com/vault/docs/secrets) +- [Vault Agent](https://developer.hashicorp.com/vault/docs/agent-and-proxy/agent) +- [Database Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/databases) +- [Transit Secrets Engine](https://developer.hashicorp.com/vault/docs/secrets/transit) diff --git a/vault/credential-generation/skills/secrets-engines/SKILL.md b/vault/credential-generation/skills/secrets-engines/SKILL.md new file mode 100644 index 0000000..1c8e8d7 --- /dev/null +++ b/vault/credential-generation/skills/secrets-engines/SKILL.md @@ -0,0 +1,171 @@ +--- +name: secrets-engines +description: Configure and use Vault secrets engines. Use when asked about KV secrets, database dynamic credentials, AWS/Azure/GCP credentials, Transit encryption, PKI certificates, SSH secrets, or TOTP. Covers static secrets, dynamic credentials, encryption-as-a-service, and secrets engine lifecycle. +--- + +# Vault Secrets Engines + +## What Are You Trying to Solve? + +### "I need to store API keys and passwords" +→ Use **KV v2** for versioned static secrets. [Jump to KV](#kv-secrets-v2) + +### "I need short-lived database credentials" +→ Use **Database** secrets engine for dynamic credentials. [Jump to Database](#database-dynamic-credentials) + +### "I need to encrypt data without storing secrets in Vault" +→ Use **Transit** for encryption-as-a-service. [Jump to Transit](#transit-encryption) + +### "I need to issue TLS certificates" +→ Use **PKI** for internal certificate authority. [Jump to PKI](#pki-certificates) + +### "I need AWS/Azure/GCP credentials for my app" +→ Use cloud secrets engines for dynamic credentials. [Jump to Cloud Credentials](#cloud-credentials) + +### "I'm not sure which secrets engine to use" +→ See the [selection guide](#secrets-engine-selection) below. + +--- + +## How Secrets Engines Work + +1. **Mount** → Enable secrets engine at a path (`vault secrets enable -path=myengine database`) +2. **Configure** → Set up backend connection (database URL, cloud credentials, CA) +3. **Create roles** → Define templates for credential generation +4. **Read credentials** → Applications request secrets, get leased credentials +5. **Renew/Revoke** → Vault manages lifecycle automatically + +--- + +## Secrets Engine Selection + +| What You Need | Engine | Key Benefit | +|---------------|--------|-------------| +| Store API keys, passwords | KV v2 | Versioning, soft-delete | +| Database credentials | Database | Short-lived, auto-revoked | +| AWS IAM credentials | AWS | Assume roles, STS tokens | +| Azure credentials | Azure | Service principal creds | +| GCP credentials | GCP | Service account keys, tokens | +| Encrypt/decrypt data | Transit | Keys never leave Vault | +| TLS certificates | PKI | Internal CA, auto-renewal | +| SSH access | SSH | Signed certificates | + +--- + +## Reference + +- [Vault Secrets Engines Documentation](https://developer.hashicorp.com/vault/docs/secrets) +- [Detailed Secrets Engines Reference](references/secrets-engines.md) + +--- + +## Quick Reference + +### KV Secrets (v2) + +```bash +# Enable KV v2 +vault secrets enable -version=2 kv + +# Write and read secrets +vault kv put secret/myapp key=value password=secret +vault kv get secret/myapp +vault kv get -field=password secret/myapp + +# List and delete +vault kv list secret/ +vault kv delete secret/myapp +vault kv undelete -versions=1 secret/myapp +``` + +### Database Dynamic Credentials + +```bash +# Enable database secrets engine +vault secrets enable database + +# Configure PostgreSQL connection +vault write database/config/postgres \ + plugin_name=postgresql-database-plugin \ + connection_url="postgresql://{{username}}:{{password}}@db:5432/mydb" \ + username="vault" password="vault-password" + +# Create role for read-only access +vault write database/roles/readonly \ + db_name=postgres \ + creation_statements="CREATE ROLE \"{{name}}\" LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \ + default_ttl=1h max_ttl=24h + +# Get dynamic credentials +vault read database/creds/readonly +``` + +### Transit Encryption + +```bash +# Enable Transit +vault secrets enable transit +vault write -f transit/keys/my-key + +# Encrypt data +vault write transit/encrypt/my-key plaintext=$(echo "secret data" | base64) +# Returns: ciphertext="vault:v1:..." + +# Decrypt data +vault write transit/decrypt/my-key ciphertext="vault:v1:..." +``` + +### PKI Certificates + +```bash +# Enable and configure PKI +vault secrets enable pki +vault write pki/root/generate/internal \ + common_name="Internal Root CA" ttl=87600h + +# Create role for issuing certs +vault write pki/roles/web-servers \ + allowed_domains="example.com" \ + allow_subdomains=true max_ttl=72h + +# Issue certificate +vault write pki/issue/web-servers common_name="app.example.com" +``` + +--- + +## Common Patterns + +### Lease Management + +All dynamic secrets have leases that control their lifetime: + +```bash +vault lease lookup # Check lease status +vault lease renew # Extend lease +vault lease revoke # Revoke immediately +``` + +### Credential Rotation + +```bash +# Rotate root credentials (database) +vault write -f database/rotate-root/postgres + +# Rotate Transit key +vault write -f transit/keys/my-key/rotate +``` + +--- + +## Best Practices + +- **Use dynamic secrets** over static KV when possible +- **Set appropriate TTLs** - short for sensitive credentials (1h or less) +- **Enable KV v2** for versioning and soft-delete capabilities +- **Use Transit** for encryption without secret storage +- **Rotate regularly** - root credentials, encryption keys + +--- + +For detailed configuration examples including AWS, Azure, GCP, SSH, and TOTP engines, see [references/secrets-engines.md](references/secrets-engines.md). diff --git a/vault/credential-generation/skills/secrets-engines/references/secrets-engines.md b/vault/credential-generation/skills/secrets-engines/references/secrets-engines.md new file mode 100644 index 0000000..059a9a5 --- /dev/null +++ b/vault/credential-generation/skills/secrets-engines/references/secrets-engines.md @@ -0,0 +1,762 @@ +--- +name: vault-secrets-engines +description: Detailed configuration for Vault secrets engines including KV, Database, AWS, Transit, PKI, and SSH +--- + +# Vault Secrets Engines + +This reference provides detailed configuration for Vault's secrets engines. + +--- + +## Overview + +Secrets engines are components that store, generate, or encrypt data. They are enabled at **paths** and all operations are relative to that path. + +### Types of Secrets Engines + +- **Static secrets**: Store arbitrary data (KV engine) +- **Dynamic secrets**: Generate credentials on-demand with automatic revocation +- **Encryption**: Encrypt/decrypt without storing data (Transit) +- **Certificates**: Issue PKI certificates + +--- + +## KV (Key-Value) Secrets Engine + +Store arbitrary static secrets. + +### KV Version 2 (Recommended) + +Supports versioning, metadata, and check-and-set operations. + +```bash +# Enable KV v2 +vault secrets enable -path=secret kv-v2 + +# Write secret +vault kv put secret/myapp/config \ + username="admin" \ + password="secret123" \ + api_key="abc123" + +# Read secret +vault kv get secret/myapp/config +vault kv get -field=password secret/myapp/config +vault kv get -format=json secret/myapp/config + +# Read specific version +vault kv get -version=2 secret/myapp/config + +# List secrets +vault kv list secret/ +vault kv list secret/myapp/ + +# Update (creates new version) +vault kv put secret/myapp/config password="newpassword" + +# Patch (update specific fields) +vault kv patch secret/myapp/config api_key="xyz789" + +# Delete (soft delete current version) +vault kv delete secret/myapp/config + +# Undelete +vault kv undelete -versions=3 secret/myapp/config + +# Destroy (permanent) +vault kv destroy -versions=1,2 secret/myapp/config + +# Metadata +vault kv metadata get secret/myapp/config +vault kv metadata put -max-versions=5 secret/myapp/config +vault kv metadata delete secret/myapp/config +``` + +### KV Version 1 + +Simple key-value without versioning. + +```bash +vault secrets enable -path=kv -version=1 kv + +vault write kv/myapp/config key=value +vault read kv/myapp/config +vault delete kv/myapp/config +``` + +--- + +## Database Secrets Engine + +Generate dynamic database credentials with automatic expiration. + +### Supported Databases + +- PostgreSQL, MySQL, MariaDB, MongoDB +- Microsoft SQL Server, Oracle +- Cassandra, Couchbase, Elasticsearch +- Redis, Snowflake, InfluxDB + +### PostgreSQL Configuration + +```bash +# Enable database engine +vault secrets enable database + +# Configure PostgreSQL connection +vault write database/config/my-postgres \ + plugin_name=postgresql-database-plugin \ + allowed_roles="readonly,readwrite" \ + connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/mydb?sslmode=require" \ + username="vault_admin" \ + password="vault_password" + +# Rotate root credentials (recommended) +vault write -f database/rotate-root/my-postgres +``` + +### Create Roles + +```bash +# Read-only role +vault write database/roles/readonly \ + db_name=my-postgres \ + creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \ + revocation_statements="DROP ROLE IF EXISTS \"{{name}}\";" \ + default_ttl="1h" \ + max_ttl="24h" + +# Read-write role +vault write database/roles/readwrite \ + db_name=my-postgres \ + creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \ + default_ttl="1h" \ + max_ttl="24h" +``` + +### Generate Credentials + +```bash +# Get dynamic credentials (new user created) +vault read database/creds/readonly + +# Output: +# Key Value +# --- ----- +# lease_id database/creds/readonly/abcd1234 +# lease_duration 1h +# username v-token-readonly-xyz123 +# password A1b2C3d4E5f6G7h8 +``` + +### MySQL Configuration + +```bash +vault write database/config/my-mysql \ + plugin_name=mysql-database-plugin \ + allowed_roles="app" \ + connection_url="{{username}}:{{password}}@tcp(mysql.example.com:3306)/" \ + username="vault" \ + password="password" + +vault write database/roles/app \ + db_name=my-mysql \ + creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; GRANT SELECT, INSERT, UPDATE ON mydb.* TO '{{name}}'@'%';" \ + default_ttl="1h" \ + max_ttl="24h" +``` + +### MongoDB Configuration + +```bash +vault write database/config/my-mongodb \ + plugin_name=mongodb-database-plugin \ + allowed_roles="app" \ + connection_url="mongodb://{{username}}:{{password}}@mongo.example.com:27017/admin" \ + username="vault" \ + password="password" + +vault write database/roles/app \ + db_name=my-mongodb \ + creation_statements='{"db": "mydb", "roles": [{"role": "readWrite"}]}' \ + default_ttl="1h" +``` + +### Database Engine Best Practices + +Based on production deployments across enterprises: + +| Practice | Recommendation | Why | +| ---------- | --------------- | ----- | +| Root Rotation | Always rotate after configuration | Vault owns only credential | +| Dedicated Users | One Vault user per database connection | Isolation and audit trail | +| TTL Strategy | 1h default, 24h max for applications | Balance security vs. overhead | +| Static Roles | Use for legacy apps that can't handle dynamic | Only when necessary | +| Connection Pooling | Configure pool size based on expected load | Prevent connection exhaustion | + +#### Dedicated Vault User Setup (PostgreSQL) + +```sql +-- Create a dedicated Vault admin user (NEVER use DBA account) +CREATE ROLE vault_admin WITH LOGIN PASSWORD 'initial_password'; + +-- Grant minimum required permissions +GRANT CREATE ROLE TO vault_admin; +GRANT CONNECT ON DATABASE mydb TO vault_admin; + +-- For revoking dynamic users +ALTER DEFAULT PRIVILEGES IN SCHEMA public + GRANT ALL ON TABLES TO vault_admin; +``` + +#### Static Roles (When Dynamic Not Possible) + +```bash +# For legacy applications that cache connections +vault write database/static-roles/legacy-app \ + db_name=my-postgres \ + username="legacy_app_user" \ + rotation_period="24h" + +# Vault rotates password on schedule +# Application must reconnect after rotation +``` + +#### Dynamic vs Static Role Decision + +| Factor | Dynamic Roles | Static Roles | +| -------- | -------------- | -------------- | +| Application Type | Modern, cloud-native | Legacy, long-lived connections | +| Rotation Frequency | Per-connection | Scheduled interval | +| Audit Granularity | Per-request attribution | Shared user attribution | +| Complexity | Requires lease management | Simpler, less secure | + +--- + +## AWS Secrets Engine + +Generate dynamic AWS credentials. + +### Configuration + +```bash +vault secrets enable aws + +# Configure root credentials +vault write aws/config/root \ + access_key= \ + secret_key= \ + region=us-east-1 + +# Configure lease settings +vault write aws/config/lease \ + lease=30m \ + lease_max=1h +``` + +### IAM User Credentials + +```bash +vault write aws/roles/deploy \ + credential_type=iam_user \ + policy_document=-< \ + tenant_id= \ + client_id= \ + client_secret= + +vault write azure/roles/contributor \ + azure_roles=-</resourceGroups/myRG" +}] +EOF + +vault read azure/creds/contributor +``` + +--- + +## GCP Secrets Engine + +Generate dynamic GCP credentials. + +```bash +vault secrets enable gcp + +vault write gcp/config credentials=@gcp-credentials.json + +# Service account key +vault write gcp/roleset/my-app \ + project="my-project" \ + secret_type="service_account_key" \ + bindings=-<" | base64 -d +``` + +### Key Rotation + +```bash +# Rotate key (new version for encryption) +vault write -f transit/keys/my-key/rotate + +# Set minimum decryption version +vault write transit/keys/my-key/config \ + min_decryption_version=2 + +# Rewrap ciphertext with latest key version +vault write transit/rewrap/my-key \ + ciphertext="vault:v1:xyz..." +``` + +### Bring Your Own Key (BYOK) + +Import existing keys into Transit: + +```bash +# Get wrapping key from Vault +vault read -field=public_key transit/wrapping_key > wrapping_key.pem + +# Wrap your key material (external process) +# Then import the wrapped key +vault write transit/keys/imported-key/import \ + ciphertext=@wrapped_key.txt \ + type=aes256-gcm96 + +# Import plaintext key (not recommended for production) +vault write transit/keys/imported-key/import \ + key="base64-encoded-key" \ + type=aes256-gcm96 +``` + +### Additional Operations + +```bash +# Sign data +vault write transit/sign/my-key \ + input=$(echo "data to sign" | base64) + +# Verify signature +vault write transit/verify/my-key \ + input=$(echo "data to sign" | base64) \ + signature="vault:v1:xyz..." + +# Generate random bytes +vault write -f transit/random/32 + +# Hash data +vault write transit/hash/sha2-256 \ + input=$(echo "data to hash" | base64) +``` + +--- + +## PKI Secrets Engine (Certificate Authority) + +Issue TLS certificates. + +### Root CA Setup + +```bash +vault secrets enable pki + +# Set max TTL +vault secrets tune -max-lease-ttl=87600h pki + +# Generate root CA +vault write pki/root/generate/internal \ + common_name="My Root CA" \ + issuer_name="root-2024" \ + ttl=87600h + +# Configure URLs +vault write pki/config/urls \ + issuing_certificates="https://vault.example.com:8200/v1/pki/ca" \ + crl_distribution_points="https://vault.example.com:8200/v1/pki/crl" +``` + +### Intermediate CA Setup + +```bash +vault secrets enable -path=pki_int pki +vault secrets tune -max-lease-ttl=43800h pki_int + +# Generate CSR +vault write -format=json pki_int/intermediate/generate/internal \ + common_name="My Intermediate CA" \ + issuer_name="intermediate-2024" \ + | jq -r '.data.csr' > pki_int.csr + +# Sign with root +vault write -format=json pki/root/sign-intermediate \ + csr=@pki_int.csr \ + format=pem_bundle \ + ttl=43800h \ + | jq -r '.data.certificate' > signed_int.pem + +# Import signed certificate +vault write pki_int/intermediate/set-signed \ + certificate=@signed_int.pem +``` + +### Create Roles and Issue Certificates + +```bash +# Create role +vault write pki_int/roles/web-servers \ + allowed_domains="example.com" \ + allow_subdomains=true \ + allow_bare_domains=false \ + max_ttl=720h + +# Issue certificate +vault write pki_int/issue/web-servers \ + common_name="web.example.com" \ + alt_names="www.example.com" \ + ttl=72h + +# Output includes: certificate, issuing_ca, private_key +``` + +### PKI Performance & Storage Optimization + +Based on production deployments issuing millions of certificates: + +| Setting | Value | Impact | +| --------- | ------- | -------- | +| `no_store` | true | Don't store issued certs (massive storage savings) | +| `generate_lease` | false | Skip lease tracking for certs (performance) | +| TTL Strategy | Short (24-72h) | Reduces CRL size, forces rotation | + +#### High-Volume PKI Configuration + +```bash +# Role optimized for high-volume issuance +vault write pki_int/roles/high-volume \ + allowed_domains="example.com" \ + allow_subdomains=true \ + max_ttl=72h \ + no_store=true \ + generate_lease=false + +# When NOT to use no_store=true: +# - Need to list/revoke individual certificates +# - Compliance requires certificate inventory +# - Using CRL-based revocation +``` + +#### Certificate Revocation Strategies + +| Strategy | When to Use | Configuration | +| ---------- | ------------- | --------------- | +| Short TTLs | Modern microservices | TTL < 24h, no revocation needed | +| OCSP | Standard PKI requirements | Enable OCSP responder | +| CRL | Legacy systems | Keep CRLs small with short TTLs | +| Delta CRL | Large deployments | Reduces CRL transfer size | + +```bash +# Configure OCSP responder +vault write pki_int/config/urls \ + ocsp_servers="https://vault.example.com:8200/v1/pki_int/ocsp" + +# Configure CRL settings +vault write pki_int/config/crl \ + expiry="72h" \ + disable=false +``` + +--- + +## SSH Secrets Engine + +Manage SSH access using OTP or signed certificates. + +### Signed Certificates (Recommended) + +```bash +vault secrets enable ssh + +# Generate CA key pair +vault write ssh/config/ca generate_signing_key=true + +# Get public key (add to target servers) +vault read -field=public_key ssh/config/ca > vault-ssh-ca.pub + +# On target servers, add to /etc/ssh/sshd_config: +# TrustedUserCAKeys /etc/ssh/vault-ssh-ca.pub + +# Create role +vault write ssh/roles/admin \ + key_type=ca \ + allowed_users="ubuntu,admin" \ + default_user=ubuntu \ + allowed_extensions="permit-pty,permit-agent-forwarding" \ + ttl=30m \ + max_ttl=4h + +# Sign user's public key +vault write ssh/sign/admin \ + public_key=@~/.ssh/id_rsa.pub + +# SSH with signed certificate +ssh -i ~/.ssh/id_rsa -i ~/.ssh/id_rsa-cert.pub user@host +``` + +### One-Time Password (OTP) + +```bash +vault write ssh/roles/otp-role \ + key_type=otp \ + default_user=ubuntu \ + cidr_list="10.0.0.0/8" + +# Generate OTP +vault write ssh/creds/otp-role ip=10.0.0.5 + +# Use vault ssh helper +vault ssh -role=otp-role -mode=otp user@10.0.0.5 +``` + +### SSH CA Migration Best Practices + +When migrating to Vault SSH CA, follow this approach: + +#### Phase 1: Parallel Operation + +```bash +# 1. Configure Vault CA on target servers (alongside existing auth) +echo "TrustedUserCAKeys /etc/ssh/vault-ssh-ca.pub" >> /etc/ssh/sshd_config + +# 2. Keep authorized_keys files temporarily +# Both methods will work during transition + +# 3. Create Vault roles matching existing access patterns +vault write ssh/roles/admin \ + key_type=ca \ + allowed_users="ubuntu,admin,deploy" \ + default_user=ubuntu \ + ttl=30m \ + max_ttl=4h +``` + +#### Phase 2: Remove Static Keys + +```bash +# CRITICAL: Only after verifying Vault SSH CA works + +# Remove authorized_keys files +rm /home/*/.ssh/authorized_keys +rm /root/.ssh/authorized_keys + +# Prevent new authorized_keys files +echo "AuthorizedKeysFile none" >> /etc/ssh/sshd_config + +# Restart SSH +systemctl restart sshd +``` + +#### SSH CA Role Security Settings + +| Setting | Recommended | Why | +| --------- | ------------- | ----- | +| `ttl` | 30m | Short-lived certificates | +| `max_ttl` | 4h | Limit maximum extension | +| `allowed_users` | Explicit list | No wildcards in production | +| `allowed_extensions` | Minimal set | Only required features | +| `default_extensions` | Empty or minimal | Security by default | + +--- + +## TOTP Secrets Engine + +Generate time-based one-time passwords. + +```bash +vault secrets enable totp + +# Create key (returns QR code URL) +vault write totp/keys/my-app \ + url="otpauth://totp/Vault:myuser@example.com?secret=BASE32SECRET&issuer=Vault" + +# Or generate a new key +vault write totp/keys/my-app \ + generate=true \ + issuer="MyApp" \ + account_name="user@example.com" + +# Generate code +vault read totp/code/my-app + +# Validate code +vault write totp/code/my-app code=123456 +``` + +--- + +## Comparison Table + +| Engine | Type | Use Case | Rotation | +| -------- | ------ | ---------- | ---------- | +| **KV** | Static | Arbitrary secrets | Manual | +| **Database** | Dynamic | DB credentials | Automatic | +| **AWS** | Dynamic | AWS access | Automatic | +| **Azure** | Dynamic | Azure access | Automatic | +| **GCP** | Dynamic | GCP access | Automatic | +| **Transit** | Encryption | Encrypt/decrypt | Key versioning | +| **PKI** | Certificates | TLS certs | By TTL | +| **SSH** | Access | SSH credentials | Automatic | + +--- + +## Additional Resources + +- [Secrets Engines Documentation](https://developer.hashicorp.com/vault/docs/secrets) +- [Dynamic Secrets Tutorial](https://developer.hashicorp.com/vault/tutorials/db-credentials) +- [PKI Tutorial](https://developer.hashicorp.com/vault/tutorials/secrets-management/pki-engine) + +--- + +## Related + +- [Policies](policies.md) - Control access to secrets engines +- [Production Operations](production-operations.md) - Monitoring and performance tuning +- [Enterprise](enterprise.md) - Namespace isolation for secrets diff --git a/vault/credential-generation/skills/vault-agent/SKILL.md b/vault/credential-generation/skills/vault-agent/SKILL.md new file mode 100644 index 0000000..fe9ccad --- /dev/null +++ b/vault/credential-generation/skills/vault-agent/SKILL.md @@ -0,0 +1,187 @@ +--- +name: vault-agent +description: Configure Vault Agent for automatic authentication, caching, and secret templating. Use when asked about sidecar patterns, auto-auth, token caching, secret file templating, or integrating applications with Vault without SDK changes. +--- + +# Vault Agent + +## What Are You Trying to Solve? + +### "My app can't implement Vault SDK integration" +→ Use Vault Agent for **automatic authentication** and token management. [Jump to Basic Config](#basic-configuration) + +### "I need secrets rendered to config files" +→ Use **templating** to render secrets to files your app reads. [Jump to Templating](#template-configuration) + +### "I want to reduce load on my Vault server" +→ Enable **caching** to store tokens and secrets locally. [Jump to Caching](#caching-configuration) + +### "I need secrets injected into Kubernetes pods" +→ Use Agent as a **sidecar** in your pod spec. [Jump to Kubernetes Sidecar](#kubernetes-sidecar) + +### "I need to bootstrap an app with secrets once" +→ Use **exec mode** for one-shot injection at startup. [Jump to Best Practices](#best-practices) + +--- + +## How Vault Agent Works + +1. **Auto-Auth** → Agent authenticates to Vault using configured method (K8s, AppRole, AWS) +2. **Token Management** → Agent renews token automatically, writes to sink file +3. **Caching** → Agent caches tokens and lease responses locally +4. **Templating** → Agent renders secrets to config files, reloads app when secrets change + +**Key insight:** Your app reads files or environment variables—no Vault SDK needed. + +--- + +## Agent Feature Selection + +| What You Need | Feature | Configuration | +|---------------|---------|---------------| +| Automatic Vault login | Auto-Auth | `method "kubernetes"` block | +| Token for app to use | Sink | `sink "file"` block | +| Reduce Vault requests | Cache | `cache {}` block | +| Render secrets to files | Template | `template {}` block | +| Proxy API requests | Listener | `listener "tcp"` block | + +--- + +## Reference + +- [Vault Agent Documentation](https://developer.hashicorp.com/vault/docs/agent-and-proxy/agent) +- [Detailed Vault Agent Reference](references/vault-agent.md) + +--- + +## Quick Reference + +### Basic Configuration + +```hcl +# vault-agent.hcl +vault { + address = "https://vault.example.com:8200" +} + +auto_auth { + method "kubernetes" { + mount_path = "auth/kubernetes" + config = { + role = "my-app" + } + } + + sink "file" { + config = { + path = "/home/vault/.vault-token" + } + } +} + +cache { + use_auto_auth_token = true +} +``` + +### Template Configuration + +```hcl +template { + source = "/etc/vault/templates/config.ctmpl" + destination = "/app/config.txt" + command = "systemctl reload myapp" +} +``` + +### Template Syntax + +```text +{{- with secret "secret/data/myapp/config" -}} +DB_HOST={{ .Data.data.host }} +DB_USER={{ .Data.data.username }} +DB_PASS={{ .Data.data.password }} +{{- end }} +``` + +--- + +## Common Patterns + +### Kubernetes Sidecar + +```yaml +# Pod spec with Vault Agent sidecar +containers: + - name: vault-agent + image: hashicorp/vault:latest + args: + - agent + - -config=/etc/vault/agent.hcl + volumeMounts: + - name: vault-agent-config + mountPath: /etc/vault + - name: shared-data + mountPath: /vault/secrets + - name: app + image: myapp:latest + volumeMounts: + - name: shared-data + mountPath: /vault/secrets + readOnly: true +``` + +### Auto-Auth Methods + +```hcl +# Kubernetes (most common for K8s) +method "kubernetes" { + mount_path = "auth/kubernetes" + config = { role = "my-app" } +} + +# AppRole (for non-K8s automation) +method "approle" { + config = { + role_id_file_path = "/etc/vault/role-id" + secret_id_file_path = "/etc/vault/secret-id" + remove_secret_id_file_after_reading = true + } +} + +# AWS (for EC2/Lambda) +method "aws" { + config = { role = "aws-role" } +} +``` + +### Caching Configuration + +```hcl +cache { + use_auto_auth_token = true + persist { + type = "kubernetes" + path = "/vault/cache" + } +} + +listener "tcp" { + address = "127.0.0.1:8200" + tls_disable = true +} +``` + +--- + +## Best Practices + +- **Use file sinks** to write tokens where applications expect them +- **Enable caching** to reduce Vault server load +- **Set template `command`** to reload apps when secrets change +- **Use `exec` mode** for one-shot secret injection at startup +- **Run as sidecar** in Kubernetes for pod-level isolation + +--- + +For complete auto-auth method configurations, advanced templating, and production deployment patterns, see [references/vault-agent.md](references/vault-agent.md). diff --git a/vault/credential-generation/skills/vault-agent/references/vault-agent.md b/vault/credential-generation/skills/vault-agent/references/vault-agent.md new file mode 100644 index 0000000..04205d4 --- /dev/null +++ b/vault/credential-generation/skills/vault-agent/references/vault-agent.md @@ -0,0 +1,814 @@ +--- +name: vault-agent +description: Comprehensive guidance on Vault Agent configuration including auto-auth, caching, and templating +--- + +# Vault Agent + +This reference provides comprehensive guidance on Vault Agent configuration for automatic authentication, secret caching, and secret templating. + +--- + +## Overview + +Vault Agent is a client daemon that provides: + +- **Auto-Auth**: Automatic authentication to Vault +- **Caching**: Local caching of tokens and secrets +- **Templating**: Render secrets to files using templates +- **Process Management**: Run applications with secrets injected + +### When to Use Vault Agent + +| Scenario | Vault Agent? | Alternative | +| ---------- | -------------- | ------------- | +| Legacy apps can't integrate Vault SDK | ✅ Yes | - | +| Kubernetes pods needing secrets | ✅ Yes | VSO, CSI Provider | +| Token renewal management | ✅ Yes | SDK auto-renewal | +| Local secret caching | ✅ Yes | - | +| Sidecar pattern | ✅ Yes | - | +| High-frequency secret access | ✅ Yes (with cache) | Direct API | + +--- + +## Basic Configuration + +### Minimal Configuration + +```hcl +# vault-agent.hcl +vault { + address = "https://vault.example.com:8200" + retry { + num_retries = 5 + } +} + +auto_auth { + method "kubernetes" { + mount_path = "auth/kubernetes" + config = { + role = "my-app" + } + } + + sink "file" { + config = { + path = "/home/app/.vault-token" + } + } +} +``` + +### Run Vault Agent + +```bash +# Run in foreground +vault agent -config=vault-agent.hcl + +# Run as daemon +vault agent -config=vault-agent.hcl & + +# Systemd service +sudo systemctl start vault-agent +``` + +--- + +## Auto-Auth Methods + +### Kubernetes Auto-Auth + +```hcl +auto_auth { + method "kubernetes" { + mount_path = "auth/kubernetes" + config = { + role = "my-app" + + # Optional: specify service account token path + token_path = "/var/run/secrets/kubernetes.io/serviceaccount/token" + } + } + + sink "file" { + config = { + path = "/home/app/.vault-token" + mode = 0640 + } + } +} +``` + +### AppRole Auto-Auth + +```hcl +auto_auth { + method "approle" { + mount_path = "auth/approle" + config = { + role_id_file_path = "/etc/vault.d/role-id" + secret_id_file_path = "/etc/vault.d/secret-id" + + # Remove secret-id file after reading + remove_secret_id_file_after_reading = true + } + } + + sink "file" { + config = { + path = "/home/app/.vault-token" + } + } +} +``` + +### AWS Auto-Auth + +```hcl +auto_auth { + method "aws" { + mount_path = "auth/aws" + config = { + type = "iam" + role = "my-app" + + # Optional: for cross-account + # header_value = "vault.example.com" + } + } + + sink "file" { + config = { + path = "/home/app/.vault-token" + } + } +} +``` + +### Azure Auto-Auth + +```hcl +auto_auth { + method "azure" { + mount_path = "auth/azure" + config = { + role = "my-app" + resource = "https://management.azure.com/" + } + } + + sink "file" { + config = { + path = "/home/app/.vault-token" + } + } +} +``` + +### GCP Auto-Auth + +```hcl +auto_auth { + method "gcp" { + mount_path = "auth/gcp" + config = { + type = "gce" + role = "my-app" + } + } + + sink "file" { + config = { + path = "/home/app/.vault-token" + } + } +} +``` + +### JWT Auto-Auth (for OIDC/CI-CD) + +```hcl +auto_auth { + method "jwt" { + mount_path = "auth/jwt" + config = { + role = "ci-runner" + path = "/var/run/secrets/jwt/token" + } + } + + sink "file" { + config = { + path = "/home/app/.vault-token" + } + } +} +``` + +--- + +## Token Sinks + +### File Sink + +```hcl +sink "file" { + config = { + path = "/home/app/.vault-token" + mode = 0640 + } + + # Wrap token before writing + wrap_ttl = "5m" +} +``` + +### Multiple Sinks + +```hcl +auto_auth { + method "kubernetes" { + config = { + role = "my-app" + } + } + + # Main token file + sink "file" { + config = { + path = "/home/app/.vault-token" + } + } + + # Wrapped token for handoff + sink "file" { + wrap_ttl = "5m" + config = { + path = "/tmp/wrapped-token" + } + } +} +``` + +--- + +## Caching + +### Enable Caching + +```hcl +cache { + use_auto_auth_token = true + + # Persist cache across restarts + persist = { + type = "kubernetes" + path = "/vault/agent-cache" + keep_after_import = true + exit_on_err = true + } +} + +listener "tcp" { + address = "127.0.0.1:8200" + tls_disable = true +} +``` + +### Caching Configuration Options + +```hcl +cache { + # Use token from auto_auth + use_auto_auth_token = true + + # Force use of auto-auth token (ignore VAULT_TOKEN) + use_auto_auth_token_strict = true + + # Cache static secrets (not just tokens) + cache_static_secrets = true + + # Persist cache to disk + persist = { + type = "kubernetes" + path = "/vault/agent-cache" + keep_after_import = true + exit_on_err = true + } +} + +# Local listener for cached requests +listener "tcp" { + address = "127.0.0.1:8200" + tls_disable = true + + # Optional: require role for access + # require_request_header = true +} + +listener "unix" { + address = "/var/run/vault-agent.sock" + tls_disable = true +} +``` + +### Cache Benefits + +| Benefit | Description | +| --------- | ------------- | +| Reduced latency | Local cache eliminates network round-trip | +| Reduced Vault load | Fewer requests to Vault cluster | +| Offline resilience | Cached secrets available if Vault temporarily unavailable | +| Token management | Agent handles renewal automatically | + +--- + +## Templating + +### Basic Template Configuration + +```hcl +template { + source = "/etc/vault-templates/app.ctmpl" + destination = "/etc/app/config.json" + + # File permissions + perms = 0640 + + # Run command after render + command = "systemctl reload app" +} + +template { + # Inline template (no source file) + contents = <: "" + vault.hashicorp.com/agent-inject-template-: "