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

# Connect HashiCorp Vault

> Bind every grant to a short-lived database credential issued by Vault.

Vault binding is the Ultraviolet-tier credential brokering path. Once
configured, every approved grant causes Vault to mint a
short-lived database credential whose TTL is bounded by the intent
token's TTL — so the credential expires when the work is done, not
when an operator remembers to rotate it.

<Note>
  Vault binding requires the **Ultraviolet** tier and the
  HashiCorp Vault Database secrets engine. See
  [Tier comparison](/tiers/overview) for what each tier unlocks.
</Note>

## Why it matters

Without Vault binding, your application holds a long-lived database
password. Every leaked password = forever-valid access. With Vault
binding, the password's lifetime is the grant's lifetime —
typically 5 minutes — and is scoped to the columns the intention
declared.

## 1. Enable the database engine in Vault

```bash theme={"dark"}
vault secrets enable -path=database database

vault write database/config/inviolet-postgres \
  plugin_name=postgresql-database-plugin \
  allowed_roles="inviolet-*" \
  connection_url="postgresql://{{username}}:{{password}}@db.example.com:5432/postgres" \
  username="vault_admin" \
  password="${VAULT_DB_ADMIN_PASSWORD}"
```

## 2. Create a role per intention

Each intention Inviolet manages gets a Vault role. The role's SQL grants
match the intention's `elements` allowlist.

```bash theme={"dark"}
vault write database/roles/inviolet-customer-support-lookup \
  db_name=inviolet-postgres \
  creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
    GRANT SELECT (id, name, email) ON customers TO \"{{name}}\";" \
  default_ttl="5m" \
  max_ttl="15m"
```

## 3. Wire Inviolet → Vault

App dashboard → **Settings → Credential Brokers → Add Vault**.
Provide:

* Vault address (e.g., `https://vault.example.com:8200`)
* AppRole role\_id + secret\_id
* Path prefix (`database/creds/inviolet-*`)

Inviolet performs a test mint and confirms the credential is revocable.

## 4. Bind to an intention

For each intention, **Settings → Intentions → pick → Credentials → Bind to
Vault role**. Pick the matching Vault role.

## 5. Verify

Trigger a tool call that matches the intention. The decision-feed entry
will now include a `credential.vault_lease_id` field. Run
`vault read database/creds/...` to confirm it's a fresh short-lived
credential, not the long-lived one your app used to hold.

## Read next

* **[Mandates](/concepts/mandates)** — the lifetime contract
  Vault credentials inherit
* **[Six enforcement layers](/concepts/six-enforcement-layers)** —
  where Vault binding fits in the stack
