Chuyển đến nội dung chính

Lesson 14: Policies - ACL, Sentinel and RBAC

Vault Policy system, HCL policy syntax, Path-based policies, Capabilities, Policy templates, Fine-grained control, Sentinel policies (Enterprise), EGP, RGP, testing.

🔒 DevSecOps — Lesson 14 Lesson 14: Policies - ACL, Sentinel and RBAC

HashiCorp Vault from Basic to Advanced

Part 3: Auth Methods - Authentication and Authorization

xdev.asia

1. Vault Policy System

Vault uses policy-based access control to control access. Every operation on Vault must be allowed by a policy. Policies are written in HCL (HashiCorp Configuration Language) or JSON.

Fundamentals

  • Default deny — default everything denied unless policy allows

  • Path-based — policies associated with API paths

  • Additive — many policies combined (union), highest authority wins

  • deny wins — if any policy deny → deny (except root)

Built-in Policies

PolicyDescriptionCan be deleted?
rootFull permission, skip all checksNo
defaultAssigned to all tokens, basic operations allowedNo (can be edited)

2. HCL Policy Syntax

Capabilities

CapabilityHTTP VerbDescription
createPOSTCreate new data
readGETRead data
updatePOST/PUTUpdate data
deleteDELETEDelete data
listLISTList keys
sudo—Allow operations on root-protected paths
deny—Deny all access (always wins)
patchPATCHPartial update (KV v2)

Basic Policy Example

# policy-dev-team.hcl

# Đọc secrets trong KV cho team dev
path "secret/data/dev/*" {
  capabilities = ["create", "read", "update", "delete", "list", "patch"]
}

path "secret/metadata/dev/*" {
  capabilities = ["list", "read", "delete"]
}

# Chỉ đọc secrets production
path "secret/data/production/*" {
  capabilities = ["read"]
}

# Sinh database credentials
path "database/creds/dev-readonly" {
  capabilities = ["read"]
}

# Không được truy cập admin paths
path "sys/*" {
  capabilities = ["deny"]
}

# Cho phép đọc health status
path "sys/health" {
  capabilities = ["read"]
}

# Self-management token
path "auth/token/lookup-self" {
  capabilities = ["read"]
}

path "auth/token/renew-self" {
  capabilities = ["update"]
}

Glob Patterns

# * khớp mọi ký tự trong một segment
path "secret/data/team-*" {
  capabilities = ["read"]
}
# Khớp: secret/data/team-alpha, secret/data/team-beta
# Không khớp: secret/data/team-alpha/sub

# + khớp ít nhất một segment (bao gồm /)
path "secret/data/team-alpha/+" {
  capabilities = ["read"]
}
# Khớp: secret/data/team-alpha/db, secret/data/team-alpha/api/keys

Fine-grained Control

# Cho phép tạo nhưng chỉ với parameters cụ thể
path "secret/data/production/db" {
  capabilities = ["create", "update"]
  allowed_parameters = {
    "data" = []   # Mọi giá trị
  }
  denied_parameters = {
    "data" = ["*root*", "*admin*"]  # Không cho key chứa root/admin
  }
}

# TTL constraints
path "database/creds/production" {
  capabilities = ["read"]
  min_wrapping_ttl = "5m"
  max_wrapping_ttl = "30m"
}

# Required parameters
path "auth/approle/role/*" {
  capabilities = ["create", "update"]
  required_parameters = ["token_policies", "secret_id_ttl"]
}

3. Policy Templates

Policy templates allow creating dynamic policies using identity information:

# Mỗi user chỉ truy cập được KV path của mình
path "secret/data/users/{{identity.entity.name}}/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Dựa trên metadata
path "secret/data/teams/{{identity.entity.metadata.team}}/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Dựa trên group
path "secret/data/groups/{{identity.groups.names.*.id}}/*" {
  capabilities = ["read", "list"]
}

# Dựa trên auth method alias
path "secret/data/k8s/{{identity.entity.aliases.auth_kubernetes_abc123.metadata.service_account_namespace}}/*" {
  capabilities = ["read"]
}

4. Managing Policies

# Tạo/cập nhật policy từ file
vault policy write dev-team policy-dev-team.hcl

# Tạo policy từ stdin
vault policy write admin-policy - <<EOF
path "sys/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
path "secret/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
EOF

# Liệt kê policies
vault policy list

# Đọc policy
vault policy read dev-team

# Xóa policy
vault policy delete dev-team

# Format/validate policy file
vault policy fmt policy-dev-team.hcl

# Test capabilities
vault token capabilities <token> secret/data/dev/app1
# create, delete, list, read, update

# Test capabilities của token hiện tại
vault token capabilities -self secret/data/dev/app1

5. RBAC Pattern with Vault Policies

RBAC design for the organization

# === Role: vault-admin ===
# policy-vault-admin.hcl
path "sys/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
path "auth/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# === Role: secrets-admin ===
# policy-secrets-admin.hcl
path "secret/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
path "database/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
path "pki/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# === Role: developer ===
# policy-developer.hcl
path "secret/data/dev/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}
path "database/creds/dev-*" {
  capabilities = ["read"]
}
path "pki/issue/dev-cert" {
  capabilities = ["create", "update"]
}

# === Role: operator ===
# policy-operator.hcl
path "secret/data/production/*" {
  capabilities = ["read"]
}
path "database/creds/prod-readonly" {
  capabilities = ["read"]
}
path "sys/health" {
  capabilities = ["read"]
}
path "sys/metrics" {
  capabilities = ["read"]
}

Assign policies to Identity Groups

# Tạo internal group
vault write identity/group \
  name="platform-team" \
  policies="secrets-admin,vault-admin" \
  member_entity_ids="entity-uuid-1,entity-uuid-2"

# Tạo external group (map từ LDAP/OIDC)
vault write identity/group \
  name="developers" \
  type="external" \
  policies="developer"

# Map external group → LDAP group
vault write identity/group-alias \
  name="CN=Developers,OU=Groups,DC=company,DC=com" \
  mount_accessor="auth_ldap_abc123" \
  canonical_id="<group-id>"

6. Sentinel Policies (Enterprise)

Sentinel is HashiCorp's policy-as-code framework, which allows creating more complex policies than ACLs using the Sentinel language. Sentinel policies can check request context, time-of-day, IP address, and many other factors.

Two types of Sentinel Policies

TypeDescriptionScope
EGP (Endpoint Governing)Attach to specific API pathAll requests to that path
RGP (Role Governing)Attached to token / identityAll requests from that identity

EGP Example — Business Hours Only

# Chỉ cho phép truy cập production secrets trong giờ làm việc
import "time"
import "strings"

# Lấy thời gian hiện tại (UTC+7 cho Việt Nam)
current_hour = time.now.hour + 7
if current_hour >= 24 {
  current_hour = current_hour - 24
}

# Kiểm tra ngày trong tuần (1=Monday, 7=Sunday)
current_day = time.now.weekday

# Business hours: Mon-Fri, 7:00-19:00 ICT
is_business_hours = current_day >= 1 and current_day <= 5 and
                    current_hour >= 7 and current_hour < 19

# Cho phép nếu trong business hours hoặc là emergency path
main = rule {
  is_business_hours or
  strings.has_prefix(request.path, "secret/data/emergency/")
}
# Tạo EGP
vault write sys/policies/egp/business-hours \
  policy="$(cat business-hours.sentinel)" \
  enforcement_level="soft-mandatory" \
  paths="secret/data/production/*"

RGP Example — Request Validation

# Yêu cầu MFA cho operations trên production
import "mfa"
import "strings"

# Kiểm tra nếu path là production
is_production = strings.has_prefix(request.path, "secret/data/production/")

# Production operations cần MFA
main = rule when is_production {
  mfa.methods.totp.valid
}

Enforcement Levels

LevelFail behavior
advisoryLog warning, still allowed
soft-mandatoryDeny, but can be overridden with sudo
hard-mandatoryDeny, cannot override

7. Policy Testing and Debugging

# Kiểm tra capabilities cụ thể
vault token capabilities -self secret/data/dev/app1

# Tạo test token với policy
vault token create -policy=dev-team -ttl=5m

# Test operations
VAULT_TOKEN="test-token" vault kv get secret/dev/app1
VAULT_TOKEN="test-token" vault kv put secret/dev/app1 key=value
VAULT_TOKEN="test-token" vault kv get secret/production/db  # Expect: permission denied

# Validate policy syntax
vault policy fmt -check policy-file.hcl

8. Summary

  • ACL Policies — path-based, capabilities, glob patterns, fine-grained control

  • Policy Templates — dynamic policies using identity data

  • RBAC Pattern — group-based policy assignment cho organizational structure

  • Sentinel Policies (Enterprise) — policy-as-code cho complex business rules

The next article will explore Identity Secrets Engine, Entities, Groups and Multi-Factor Authentication — completing the picture of identity management in Vault.