Keys and policy
What an API key can do, and how sub-keys narrow it.
API keys are bq_live_… for real machines and bq_test_… for the mock provider. They are
SHA-256 hashed at rest; only the prefix is stored in clear for lookup. A key belongs to a team and
carries a policy that is checked before any provider call.
The policy
{
"maxConcurrentBriqs": 5,
"dailySpendCapCents": 1000,
"allowedSizes": ["nano", "small"],
"allowedRegistries": ["docker.io", "ghcr.io"],
"egress": "allow",
"egressAllowlist": [],
"maxTtlMinutes": 1440,
"expiresAt": null
}| Field | Effect |
|---|---|
maxConcurrentBriqs | briq_run fails with policy_violation when this many briqs are already running or creating under the key |
dailySpendCapCents | Checked before create; the reconciler also stops the key's briqs when the day's spend crosses it |
allowedSizes | Sizes the key may request. medium and large also require the Pro plan |
allowedRegistries | Image references must start with one of these hosts (docker.io covers unqualified images) |
egress | allow, deny, or allowlist (then egressAllowlist lists permitted hosts). Enforced by a per-stack egress proxy from v1; SMTP ports are always blocked |
maxTtlMinutes | Upper bound for ttl_minutes on run and extend, up to 10080 |
expiresAt | ISO timestamp after which the key is rejected |
The values above are the defaults for a new key on the free plan.
Sub-keys
POST /v1/keys with a parent mints a sub-key. A sub-key inherits its parent's policy and may
only narrow it: a lower cap, fewer sizes, fewer registries, a shorter TTL, deny instead of
allow. Any field that widens the parent is rejected with
policy_violation: sub-key widens parent policy: dailySpendCapCents.
This is how you hand an agent a budget without handing it your account: keep the parent key on
your machine, give the agent a sub-key with dailySpendCapCents: 200 and maxConcurrentBriqs: 2.
See Budgets and sub-keys.
Errors
Policy failures return HTTP 402 with { "error": { "code": "policy_violation", "message": "…" } }
over REST, and a tool error with the same message over MCP. briq_quota (or GET /v1/quota)
reports remaining spend, remaining concurrency and allowed sizes so a model can plan instead of
retrying.