> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shiftlabs.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Policies

> Define access control rules for Vault resources

Vault Policies define who can access what secrets and with which operations. Policies are written in HashiCorp Configuration Language (HCL) and provide fine-grained access control over Vault paths.

## Key Concepts

<CardGroup cols={2}>
  <Card title="Path-Based Rules" icon="route">
    Policies grant capabilities on specific paths. Use wildcards to match multiple paths.
  </Card>

  <Card title="Capabilities" icon="list-check">
    Define allowed operations: create, read, update, delete, list, sudo, deny.
  </Card>

  <Card title="Deny by Default" icon="ban">
    Users have no access unless explicitly granted by a policy.
  </Card>

  <Card title="Multiple Policies" icon="layer-group">
    Users can have multiple policies. Permissions are additive (union of all policies).
  </Card>
</CardGroup>

## Required Permissions

| Action                 | Permission                      |
| ---------------------- | ------------------------------- |
| View policies          | `iam:project:cicd:vault:read`   |
| Create/Update policies | `iam:project:cicd:vault:write`  |
| Delete policies        | `iam:project:cicd:vault:delete` |

## Capabilities Reference

| Capability | Description                 | Use Case                       |
| ---------- | --------------------------- | ------------------------------ |
| `create`   | Create new data at a path   | Writing new secrets            |
| `read`     | Read data from a path       | Viewing secret values          |
| `update`   | Modify existing data        | Changing secret values         |
| `delete`   | Remove data from a path     | Deleting secrets               |
| `list`     | List keys at a path         | Browsing folders               |
| `sudo`     | Access root-protected paths | Admin operations               |
| `deny`     | Explicitly deny access      | Override inherited permissions |

## How to Create a Policy

<Steps>
  <Step title="Select Vault Instance">
    Choose the target Vault instance from the dropdown if you have multiple.
  </Step>

  <Step title="Click Create Policy">
    Click the **Create Policy** button.
  </Step>

  <Step title="Enter Policy Name">
    Provide a unique, descriptive name:

    * Use lowercase with hyphens (e.g., `app-read-only`)
    * Only alphanumeric, hyphens, and underscores allowed
  </Step>

  <Step title="Write Policy Rules">
    Define access rules in HCL format. Click **Insert Example** to start with a template.
  </Step>

  <Step title="Create">
    Click **Create Policy** to save.
  </Step>
</Steps>

## Policy Syntax

Policies use HCL (HashiCorp Configuration Language) syntax:

```hcl theme={null}
# Grant full access to app secrets
path "secret/data/app/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Read-only access to shared config
path "secret/data/shared/config" {
  capabilities = ["read"]
}

# List folders only (no secret access)
path "secret/metadata/*" {
  capabilities = ["list"]
}
```

### Path Patterns

| Pattern                    | Matches               |
| -------------------------- | --------------------- |
| `secret/data/app`          | Exact path only       |
| `secret/data/app/*`        | All direct children   |
| `secret/data/app/+/config` | Single-level wildcard |
| `secret/+/*`               | Combination patterns  |

<Info>
  For KV v2 secrets engine, use `secret/data/*` for reading/writing secrets and `secret/metadata/*` for listing and metadata operations.
</Info>

## Common Policy Examples

### Read-Only Policy

```hcl theme={null}
# Read and list secrets, no modifications
path "secret/data/*" {
  capabilities = ["read", "list"]
}

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

### Application-Specific Policy

```hcl theme={null}
# Full access to app's own secrets
path "secret/data/myapp/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

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

# Read shared configuration
path "secret/data/shared/*" {
  capabilities = ["read"]
}
```

### Team Lead Policy

```hcl theme={null}
# Manage team secrets
path "secret/data/team-alpha/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Read other teams' public configs
path "secret/data/+/public/*" {
  capabilities = ["read"]
}
```

### Deny Specific Paths

```hcl theme={null}
# Grant broad access
path "secret/data/app/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# But deny access to production credentials
path "secret/data/app/production/credentials" {
  capabilities = ["deny"]
}
```

## How to Edit a Policy

<Steps>
  <Step title="Find the Policy">
    Use the search bar to locate the policy by name.
  </Step>

  <Step title="Click Edit">
    Click the edit (pencil) icon on the policy row.
  </Step>

  <Step title="Modify Rules">
    Update the HCL content in the editor.
  </Step>

  <Step title="Save">
    Click **Update Policy** to apply changes.
  </Step>
</Steps>

<Warning>
  Policy changes take effect immediately. Users with active sessions may need to re-authenticate to see updated permissions.
</Warning>

## How to Delete a Policy

<Steps>
  <Step title="Find the Policy">
    Locate the policy in the list.
  </Step>

  <Step title="Click Delete">
    Click the trash icon on the policy row.
  </Step>

  <Step title="Confirm">
    Confirm the deletion. This action cannot be undone.
  </Step>
</Steps>

<Warning>
  Deleting a policy immediately revokes access for all users who depend on it. Ensure no critical workflows rely on this policy before deletion.
</Warning>

## Best Practices

### Naming Conventions

```
{app}-{access-level}          # myapp-read-only
{team}-{resource}-{access}    # platform-secrets-admin
{environment}-{role}          # production-deployer
```

### Principle of Least Privilege

Grant minimum necessary permissions:

```hcl theme={null}
# Bad: Too broad
path "secret/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

# Good: Specific and minimal
path "secret/data/myapp/config" {
  capabilities = ["read"]
}
```

### Use Comments

Document the purpose of each rule:

```hcl theme={null}
# Allow CI/CD pipeline to read deployment secrets
path "secret/data/deploy/*" {
  capabilities = ["read"]
}

# Allow rotation of API keys only
path "secret/data/api-keys/*" {
  capabilities = ["read", "update"]
}
```

### Separate by Environment

Create environment-specific policies:

```hcl theme={null}
# production-app policy
path "secret/data/production/app/*" {
  capabilities = ["read"]
}

# staging-app policy
path "secret/data/staging/app/*" {
  capabilities = ["create", "read", "update", "delete"]
}
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Policy not taking effect" icon="circle-question">
    * Users may need to log out and back in
    * Token may be cached with old permissions
    * Verify the policy is attached to the user/group
  </Accordion>

  <Accordion title="Permission denied errors" icon="circle-question">
    * Check the exact path being accessed matches policy
    * For KV v2, ensure using `secret/data/` prefix
    * Verify required capability is included
    * Check for explicit `deny` rules that may override
  </Accordion>

  <Accordion title="Cannot list secrets but can read" icon="circle-question">
    * `list` capability must be on the `metadata` path
    * Add: `path "secret/metadata/*" { capabilities = ["list"] }`
  </Accordion>

  <Accordion title="Syntax error when saving" icon="circle-question">
    * Check for missing closing braces `}`
    * Ensure capabilities are in array format `["read", "list"]`
    * Verify no trailing commas in capability arrays
    * Use the Insert Example button to compare syntax
  </Accordion>

  <Accordion title="Cannot delete policy" icon="circle-question">
    * You need delete permission for Vault policies
    * Built-in policies (root, default) cannot be deleted
    * Check with administrator for policy management permissions
  </Accordion>
</AccordionGroup>

## FAQ

<AccordionGroup>
  <Accordion title="What happens when a user has multiple policies?">
    Permissions are additive. If policy A grants read and policy B grants write, the user has both read and write access. However, explicit `deny` always wins.
  </Accordion>

  <Accordion title="Can I test a policy before applying?">
    Use the Vault CLI `vault token capabilities` command to test what operations are allowed for a token on a specific path.
  </Accordion>

  <Accordion title="What's the difference between secret/data and secret/metadata?">
    For KV v2 secrets engine:

    * `secret/data/*` - Read/write actual secret values
    * `secret/metadata/*` - List paths, read/write metadata, delete versions
  </Accordion>

  <Accordion title="Can policies reference environment variables?">
    No. Policies are static HCL documents. Use templated policies with Vault Enterprise, or create separate policies per environment.
  </Accordion>

  <Accordion title="How do I grant admin access?">
    For full administrative access, attach the `root` policy. Use sparingly and prefer scoped policies for day-to-day operations.
  </Accordion>

  <Accordion title="Are policy names case-sensitive?">
    Yes. `MyPolicy` and `mypolicy` are different policies. Use consistent lowercase naming.
  </Accordion>
</AccordionGroup>
