Completes the lifecycle family from #25 — usage caps were the third sibling (after expiry #24 and revoke), written-but-never-enforced. Model: - PolicyRule gains windowSeconds; drops the never-enforced mutable currentUsageCount. A cap = (maxUsageCount, windowSeconds): at most N signings of this (method,kind) per rolling window. windowSeconds NULL = lifetime; maxUsageCount NULL = uncapped. - New SigningLog: durable append-only record of allowed signings — the source of truth caps count against (derive-don't-count; no counter to drift). Enforcement (checkIfPubkeyAllowed step 4): among the live token's matching rules, every capped rule must have remaining budget in its window (COUNT(SigningLog) < maxUsageCount), counted live. Stacked caps all bind — 20/hr AND 200/day enforced together. recordSigning() writes a SigningLog row from the permit callback when a consequential request (sign_event / encrypt / decrypt) is allowed. Retune live: new update_policy_rule admin RPC patches maxUsageCount/ windowSeconds/method/kind in place; takes effect next request, no re-pairing (a payoff of the #27 Option D design). get_policies now returns each rule's id + window_seconds so callers can target it. Retention/pruning of SigningLog is a follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| migrations | ||
| nsecbunker.db | ||
| schema.prisma | ||