Commit graph

17 commits

Author SHA1 Message Date
6929f42115 feat(acl)(#28): per-rule windowed usage caps enforced live at sign time
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>
2026-06-21 12:29:51 +02:00
6397c7988d feat(schema)(#25): Request.keyUserId + SigningCondition lifecycle for live grant eval
Additive, non-breaking schema prep for the Option D live-evaluation ACL:

- Request gains keyUserId (FK) + @@index([keyUserId, method]) so token
  usage caps can be derived live by COUNTing allowed Requests, replacing
  the never-enforced mutable PolicyRule.currentUsageCount (derive-don't-count,
  per lnbits/nostr_bunker prior art).
- SigningCondition gains createdAt/expiresAt/revokedAt so the manual-override
  layer carries its own lifecycle and runs through the same grantIsLive(now)
  predicate as token grants (D1: two typed sources, one shared rule).

No behavior change yet; the ACL hot path and applyToken de-materialization
follow in subsequent commits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 15:00:33 +02:00
eb6c86a4d1 chore(schema): add Token.revokedAt for surgical token revocation (#11)
Pre-requisite for the live-policy auth rewrite in #11. The new
revoke_token admin RPC needs a way to mark a single Token as
revoked without nuking the whole KeyUser (revoke_user) or
conflating with future expiry cleanup (deletedAt).

Nullable DateTime — existing rows default to NULL (active), no
data migration needed.

refs: #11
2026-05-30 13:24:14 +02:00
Nour
33fb9703f7
feat: use dynamic DATABASE_URL for Prisma db 2024-01-26 15:13:26 +00:00
Nour
e40fafa3b5
feat: multiple fixes
- Define binaryTargets for schema.prisma so it works inside alpine
- Log adminNpubs
- Set default for config `domains`
2024-01-23 17:44:38 +00:00
Pablo Fernandez
70e009ddf7 user table 2024-01-02 11:12:23 +00:00
Pablo Fernandez
0a5682d1e4 create_account work 2023-12-20 10:21:24 +00:00
Pablo Fernandez
e5febb3345 wip 2023-12-01 11:18:39 +00:00
Pablo Fernandez
3d9aa4f459 store requests 2023-11-05 18:29:57 +09:00
pablof7z
6f16cafd41 lots of things that I forgot to commit 😂 2023-07-06 22:29:31 +02:00
pablof7z
59556e673b follow 2023-06-29 16:55:23 +02:00
pablof7z
db0c9ae3fb minor improvements 2023-06-28 21:44:39 +02:00
pablof7z
f949c116db write to a file the connection string 2023-06-27 01:59:39 +02:00
pablof7z
c43f1cc95e Policies and single-use tokens 2023-06-04 10:03:02 +02:00
pablof7z
28f4788aec updates 2023-05-31 20:27:33 +02:00
pablof7z
74cd9715ac updates 2023-05-31 20:26:29 +02:00
pablof7z
54de9cfa8e initial commit 2023-05-15 20:05:55 +02:00