mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 12:05:07 +00:00
Vaults.add_keys and kv add skip null content keys instead of failing the batch; is_null_key moves to core.vault. A manifest snapshot restore has one 32 MiB inflate budget. Tests reset the speed limiter and config between runs.
65 lines
3.2 KiB
Markdown
65 lines
3.2 KiB
Markdown
# Key vaults { #key-vaults }
|
|
|
|
The full guide is at [Vaults](../../guide/vaults.md). Two keys configure them.
|
|
|
|
## `key_vaults`
|
|
|
|
- **Type:** `list[dict]` · **Default:** `[]`
|
|
|
|
An ordered list of key-vault backends. unshackle queries them in order and reuses the
|
|
content keys instead of licensing them again. Each entry needs a `type` (the backend module
|
|
name) and a `name`, plus backend-specific keys.
|
|
|
|
| `type` | Purpose | Required keys | Notes |
|
|
|--------|---------|--------------|-------|
|
|
| `SQLite` | Local SQLite database | `name`, `path` | Loaded **critically**; a failure aborts the run. |
|
|
| `MySQL` | Remote MySQL database | `name`, `host`, `database`, `username` | Extra keys (e.g. `password`, `port`) forwarded to pymysql. `connect_timeout` defaults to `vault_timeout`. |
|
|
| `API` | RESTful JSON API | `name`, `uri`, `token` | Optional `headers` map is sent with every request. Honours `vault_timeout`. |
|
|
| `HTTP` | HTTP API with modes | `name`, `host`, one of `password`/`api_key`, and `username` in query mode | `api_mode`: `query` (default), `json`, `decrypt_labs`. Honours `vault_timeout`. |
|
|
|
|
```yaml
|
|
key_vaults:
|
|
- type: SQLite
|
|
name: Local
|
|
path: ~/.unshackle/keys.db
|
|
- type: MySQL
|
|
name: Team
|
|
host: db.example.com
|
|
database: keys
|
|
username: unshackle
|
|
password: hunter2
|
|
no_push: false
|
|
```
|
|
|
|
!!! note "Per-entry options"
|
|
- `no_push: true` makes a vault read-only (unshackle fetches content keys from it but never writes to it).
|
|
- A vault of `type: API` whose `name` contains `decrypt_labs` auto-fills its `token` from
|
|
[`decrypt_labs_api_key`](misc.md#external-api-keys) when not set inline. Vault `type` values are
|
|
case-sensitive module names.
|
|
- unshackle treats an empty or all-zero content key, of any length, as "no key" everywhere
|
|
and never stores it.
|
|
|
|
!!! note "Bad content keys"
|
|
A content key from a vault is proven by short FFmpeg decodes of the decrypted output,
|
|
with windows inside the fragments of each KID in a fragmented MP4. A content key that
|
|
fails the decode is written to the `bad_keys` table of every `SQLite` vault with the name
|
|
of the vault that supplied it, and every vault lookup skips a flagged pair from then on. A `SQLite` vault also refuses to
|
|
store a flagged pair again. Only the `SQLite` backend stores flags; an `API` vault that
|
|
supplied the pair gets a report. A `serve` instance with
|
|
`server_cdm` flags a pair the same way when a remote client reports it, so a server whose
|
|
`key_vaults` hold no `SQLite` entry cannot remember a bad content key.
|
|
|
|
## `vault_timeout`
|
|
|
|
- **Type:** `float` · **Default:** `10.0`
|
|
|
|
Timeout in seconds for vault operations. Injected automatically into any backend whose
|
|
constructor accepts a `timeout` parameter (a per-vault `timeout` still wins). The `MySQL` backend
|
|
uses it as the default `connect_timeout`.
|
|
|
|
The `API` and `HTTP` backends send a request again up to 3 times when the vault answers
|
|
`429 Too Many Requests`. They wait the `Retry-After` time, but never longer than this timeout.
|
|
A connection failure or a timeout is not tried again. The run does not use a vault again after a
|
|
connection failure, a timeout, or a `429` that continues after the retries, so a vault that is
|
|
down costs one timeout per run.
|