Tuesday, November 18, 2025

HashiCorp Vault Policies

HashiCorp Vault Policies - Complete Access Control Guide

HashiCorp Vault Policies - Complete Access Control Guide

🎯 Prerequisites: HashiCorp Vault FundamentalsAuthentication Methods
📚 What You'll Master:
Complete policy implementation from HCL syntax to real-world access control scenarios with authentication method integration

Vault Policy Overview

Once you authenticate to Vault, it assigns policies to your token, and these policies define what you can actually do in Vault. Understanding policies is crucial for implementing secure access controls.

What Are Vault Policies?

At a high level, policies in Vault are used to define permissions. In the UI, they're called Policy ACLs (Access Control Lists) - essentially lists of controls that define access within Vault.

Policy Assignment Options

  • Direct Token Assignment - Assign policy directly to a token during creation
  • Authentication Method Integration - Map policies to users, groups, or roles in auth methods
  • Identity Secrets Engine - Assign policies to entities and groups

Critical Policy Rules

🎯 Key Policy Principles:
  • More Specific Rule Wins - Specific paths override general paths
  • No Internal Versioning - Updates overwrite previous versions completely
  • Immediate Effect - Policy updates apply instantly to all tokens using that policy

Special Policies

Default Policy:

  • Created when Vault server starts
  • Assigned to new tokens automatically
  • Can be modified but cannot be deleted
  • Allows basic token self-management operations

Root Policy:

  • Automatically associated with root tokens
  • Full control over everything in Vault
  • Cannot be changed or deleted
  • Can be assigned to other tokens (use carefully!)

Default Policy Contents

The default policy enables essential token operations:

  • Token Self-Lookup - Check own properties and TTL
  • Token Self-Renewal - Extend token lifetime before expiration
  • Token Self-Revocation - Revoke own token when no longer needed
  • Capability Lookup - Check what permissions the token has
  • Entity Lookup - Look up own entity by ID or name

Policy Syntax & Path Matching

Policy Format

Vault policies are defined using HCL (HashiCorp Configuration Language) or JSON. HCL is preferred for human readability.

Basic Policy Structure

Every policy rule contains two essential elements:

  • Path - Defines WHERE in Vault to assign permissions
  • Capabilities - Defines WHAT actions are allowed at that path
# Basic policy structure
path "secrets/example" {
  capabilities = ["read", "list"]
}

Path Wildcards & Dynamic Matching

1. Glob Wildcard (*)

Matches any extension of a path (used at the end):

# Matches: secrets/globo/web1/ AND secrets/globo/webapp/apikeys
path "secrets/globo/web*" {
  capabilities = ["read"]
}

2. Path Segment Match (+)

Placeholder for a single path segment:

# Matches: secrets/globo/webapp1/apikeys AND secrets/globo/webapp2/apikeys
path "secrets/globo/+/apikeys" {
  capabilities = ["read"]
}

3. Parameters (Identity Engine Integration)

Dynamic resolution using Identity secrets engine:

# Allows token to access its own entity information
path "identity/entity/id/{{identity.entity.id}}" {
  capabilities = ["read"]
}

path "identity/entity/name/{{identity.entity.name}}" {
  capabilities = ["read"]
}

Capabilities & Permissions

Standard CRUD Capabilities

  • create - Create new keys/values
  • read - Read data from existing keys
  • update - Modify data in existing keys
  • delete - Remove keys and their data

Additional Capabilities

list - Enumerate keys at a path

  • Shows key names without revealing content
  • Does NOT imply read permission
  • Useful for discovery without access to sensitive data

sudo - Special permissions for root-protected paths

  • Required for certain administrative operations
  • Does NOT imply other capabilities
  • Must be combined with other permissions (create, update, etc.)

deny - Explicitly disable access

  • Overrides any other capability
  • Applies to full path and all extensions
  • Used for implementing least-privilege access

Capability Examples

Read-Only Access:

path "secrets/globo/webapp/apikey" {
  capabilities = ["read"]
}

Read and List Access:

path "secrets/globo/webapp/*" {
  capabilities = ["read", "list"]
}

Full Access with Path Segment:

path "secrets/globo/+/apikey" {
  capabilities = ["create", "read", "update", "delete"]
}

Selective Deny with Override:

# Grant general access
path "secrets/globo/webapp/*" {
  capabilities = ["create", "read", "list", "update", "delete"]
}

# Deny specific privileged path (more specific rule wins)
path "secrets/globo/webapp/privileged/*" {
  capabilities = ["deny"]
}

Policy Design Scenarios

Scenario 1: Junior Administrator Access

Requirements:
  • Junior admins can manage secrets engines
  • Follow principle of least privilege
  • No access to secrets content
  • Can enable, disable, and tune secrets engines
Solution: Secrets Engine Management Policy
# Allow secrets engine management
path "sys/mounts/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Allow listing existing secrets engines
path "sys/mounts" {
  capabilities = ["read"]
}
⚠️ Important: sudo capability is required because sys/mounts is a root-protected path.

Scenario 2: Accounting Department Access

Requirements:
  • Access to accounting secrets engine (KV v2)
  • Privileged area exists within accounting engine
  • Regular accountants denied privileged access
  • Allow metadata management
Solution: Accounting Policy with Selective Deny
# General accounting data access
path "accounting/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Metadata access for KV v2
path "accounting/metadata/*" {
  capabilities = ["list"]
}

# Deny privileged data access (more specific rule)
path "accounting/data/apitokens/privileged" {
  capabilities = ["deny"]
}

# Deny privileged metadata access
path "accounting/metadata/apitokens/privileged*" {
  capabilities = ["deny"]
}

Policy Management & Assignment

Policy Lifecycle Commands

List Existing Policies:

vault policy list

Read Policy Contents:

vault policy read secrets-mgmt

Create/Update Policy:

# From file
vault policy write secrets-mgmt secrets-mgmt.hcl

# From stdin
vault policy write secrets-mgmt -

Delete Policy:

vault policy delete secrets-mgmt

Format Policy File:

vault policy fmt secrets-mgmt.hcl

Policy Assignment Methods

1. Direct Token Assignment:

vault token create -policy=accounting -policy=secrets-mgmt

2. Authentication Method Assignment:

# Assign to userpass user
vault write auth/userpass/users/alice \
    password=secret123 \
    token_policies="accounting,default"

3. Identity Secrets Engine Assignment:

vault write identity/entity/name/alice \
    policies="accounting,secrets-mgmt"

Hands-On Implementation

Complete Scenario Walkthrough

Step 1: Environment Setup

# Start Vault dev server
vault server -dev

# Set environment and login
export VAULT_ADDR="http://127.0.0.1:8200"
vault login [root-token]

# Enable userpass auth method
vault auth enable userpass

# Create test user
vault write auth/userpass/users/alice password=secret123

Step 2: Create Secrets Engine Management Policy

Create secrets-mgmt.hcl:

# Allow secrets engine management
path "sys/mounts/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Allow listing secrets engines
path "sys/mounts" {
  capabilities = ["read"]
}
# Upload policy
vault policy write secrets-mgmt secrets-mgmt.hcl

Step 3: Create Accounting Environment

# Enable KV v2 secrets engine
vault secrets enable -path=accounting kv-v2

# Add test data
vault kv put accounting/apitokens d101=token1 d102=token2 d103=token3
vault kv put accounting/apitokens/privileged p101=privileged-token

Step 4: Create Accounting Policy

Create accounting.hcl:

# General accounting data access
path "accounting/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Metadata access
path "accounting/metadata/*" {
  capabilities = ["list"]
}

# Deny privileged access
path "accounting/data/apitokens/privileged" {
  capabilities = ["deny"]
}

path "accounting/metadata/apitokens/privileged*" {
  capabilities = ["deny"]
}
# Upload policy
vault policy write accounting accounting.hcl

Step 5: Test Token-Based Assignment

# Create token with accounting policy
vault token create -policy=accounting

# Login with new token
vault login [token-from-above]

# Test access - should work
vault kv list accounting
vault kv get accounting/apitokens

# Test denied access - should fail
vault kv get accounting/apitokens/privileged

Step 6: Test Authentication Method Assignment

# Login as root
vault login [root-token]

# Assign policy to user
vault write auth/userpass/users/alice \
    token_policies="secrets-mgmt"

# Test user login
vault login -method=userpass username=alice
# Password: secret123

# Test secrets engine management
vault secrets enable -path=testing kv
vault secrets list
vault secrets disable testing

Policy Update and Testing

Common Issue: Typos in Policy Files

⚠️ Real-World Example:
If you misspell "privileged" as "priviliged" in your policy, the deny rule won't work! Always double-check spelling and test thoroughly.
# Fix policy file and update
vault policy write accounting accounting-fixed.hcl

# Policy updates are immediate - test again
vault kv get accounting/apitokens/privileged
# Should now be denied

Policy Cleanup

# Clean up secrets engine
vault secrets disable accounting

# Delete policies
vault policy delete accounting
vault policy delete secrets-mgmt

# Verify cleanup
vault policy list

Advanced Policy Patterns

Template Policies

Use Identity engine parameters for dynamic policies:

# User can only access their own data
path "secrets/users/{{identity.entity.name}}/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Group-based access
path "secrets/groups/{{identity.groups.names}}/*" {
  capabilities = ["read", "list"]
}

Layered Security Model

# Base policy for all users
path "secrets/common/*" {
  capabilities = ["read", "list"]
}

# Department-specific access
path "secrets/{{identity.groups.names}}/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Admin override
path "secrets/admin/*" {
  capabilities = ["deny"]
}

Key Takeaways & Best Practices

Essential Concepts

  • Policy Association - Policies are associated with tokens through direct assignment, auth methods, or Identity engine
  • Permission Hierarchy - More specific paths override general paths
  • Immediate Updates - Policy changes apply instantly to all tokens using that policy
  • Special Policies - Root policy (immutable, full access) vs Default policy (modifiable, basic token operations)

Policy Design Best Practices

🎯 Best Practices:
  • Principle of Least Privilege - Grant minimum necessary permissions
  • Specific Deny Rules - Use specific paths to deny sensitive areas
  • Test Thoroughly - Always test policies with actual tokens
  • Version Control - Store policy files in version control (Vault doesn't version them)
  • Meaningful Names - Use descriptive policy names that indicate purpose
  • Documentation - Comment complex policies for future maintenance

Command Summary

Policy Management: vault policy [list|read|write|delete|fmt]
Token Assignment: vault token create -policy=[policy-name]
Auth Method Assignment: vault write auth/[method]/users/[user] token_policies=[policy]
Identity Assignment: vault write identity/entity/name/[entity] policies=[policy]

What's Next?

Now that you understand authentication and policies, the next crucial component is token management. Tokens are the core of Vault's security model - understanding their lifecycle, renewal, revocation, and advanced features like token hierarchies and accessor tokens is essential for production deployments.

🎯 Practice Challenge:
Create a complete access control scenario:
  1. Design policies for different user roles (admin, developer, auditor)
  2. Implement selective access with deny rules
  3. Test policy assignment through multiple methods
  4. Update policies and verify immediate effect
  5. Use wildcards and path parameters for dynamic access

Ready to advance? With authentication methods and policies mastered, you're prepared to dive deep into token management and explore Vault's secrets engines for comprehensive secrets lifecycle management in production environments.

No comments:

Post a Comment