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

# Lease lifetime

> Every credential KnoxCall mints is tracked as a lease that auto-expires. Learn how TTLs are resolved, capped, and revoked.

# Lease lifetime

Every database credential KnoxCall mints is tracked as a **lease**. The lease records who got the credential, what role it was minted from, when it was issued, and — most importantly — **when it expires**.

When the lease expires, KnoxCall automatically runs the role's `revocation_sql` against the database and drops the user. The customer doesn't have to remember to clean up.

## Two TTL fields

Each connection (and each role) has two TTL settings:

* **Default TTL** — the duration applied when the caller doesn't ask for a specific TTL. Most "give me a credential" calls don't specify, so this is the typical case.
* **Max TTL** — the absolute ceiling. A caller can ask for less, but never more.

```text theme={"dark"}
default_ttl_seconds: 3600   # 1 hour — the default
max_ttl_seconds:    86400   # 24 hours — the ceiling
```

A request like `POST /v1/dyn-db-credentials/{name}/creds/{role}` with no `ttl_seconds` mints a 1-hour credential. A request asking for `ttl_seconds=43200` (12h) mints a 12-hour credential. A request asking for `ttl_seconds=172800` (48h) is silently clamped to the 24h ceiling — it doesn't fail.

## Resolution order

When a credential is minted, the TTL is resolved in this order:

1. **Caller-requested** TTL (if provided and > 0).
2. **Role-level** default (overrides connection default, if set).
3. **Connection-level** default (the fallback).

Then the result is clamped to `min(role.max_ttl, connection.max_ttl)`.

So if you have `connection.max_ttl=86400` and `role.max_ttl=7200`, the role-level cap wins — that role can never mint a credential longer than 2 hours, no matter what the caller asks for.

This lets you define a strict role for prod (`max_ttl=900` — 15 minutes) sitting on a connection with a more generous default (`max_ttl=86400`) used by other roles.

## How revoke works

There are two paths to credential revocation:

### 1. Automatic (on expiry)

A background **lease worker** scans for expired leases on a regular tick. When it finds an expired lease, it calls the executor's `revoke()` — which runs the role's `revocation_sql` template substituted with the username — and flips the lease's status to `expired`.

You can see expired leases in the audit log: action `db_credential.revoke` with `executor_ok: true`.

### 2. Explicit (manual)

`POST /v1/dyn-db-credentials/leases/{lease_id}/revoke` (or click **Revoke** in the admin UI) does the same thing on demand. The lease ends up in `revoked` status rather than `expired` — useful for distinguishing "this was killed because someone leaked it" from "this aged out normally."

## IAM mode is special

For [IAM mode](/essentials/dyn-db-credentials/auth-modes#iam-aws-rds-aurora), KnoxCall doesn't create a dynamic DB user — it mints a 15-minute AWS auth token for an existing IAM-enabled user. There's no `DROP USER` to run on revoke; the token simply stops working.

Implications:

* **Lease TTL is capped at 15 minutes** regardless of your `default_ttl_seconds` / `max_ttl_seconds` settings.
* The lease worker still flips state at expiry for audit-trail completeness, but `executor.revoke()` is a no-op.
* Explicit revoke also flips state but doesn't actively kill the token — you can't kill an AWS-signed token mid-flight; you wait for it to expire.

If you need fast kill-switch behaviour on RDS, layer on a security-group revoke or AWS IAM policy detach. KnoxCall's lease state isn't a substitute for those.

## Recommended values

| Use case                   | Default TTL           | Max TTL      |
| -------------------------- | --------------------- | ------------ |
| Engineer ad-hoc query      | 1h (`3600`)           | 8h (`28800`) |
| CI / scheduled job         | 15m (`900`)           | 1h (`3600`)  |
| Long-running migration     | 4h (`14400`)          | 8h (`28800`) |
| Contractor offboarding     | duration = engagement | same         |
| High-trust prod read-write | 5m (`300`)            | 15m (`900`)  |

Shorter is always safer. The friction cost of re-issuing is one API call.

## Reading lease state in the UI

Open a connection on the **Dynamic DB Credentials** page to see its **Active leases** panel. Each row shows:

* The minted username (also the lease's subject ID — useful for grepping audit logs).
* The role it came from.
* When it expires.
* A **Revoke** button.

The list shows only `active` and `renewing` leases; once a lease moves to `expired` / `revoked` / `errored` it falls off this view but remains in audit history.
