feat(pairing): optional token TTL + revoke endpoint (#9/#12, #22) #23
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/pairing-revoke-ttl"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Stacked on #21 (base =
feat/seed-url-pairing). Retarget tomainonce #21 merges. The follow-up scoped out of #21 per discussion: adds the two additive pieces unblocked byaiolabs/lnbits#55.(b) Optional token TTL
PairMachineData.duration_hours(validated> 0, optional) threads throughpair_spire→create_new_token(..., duration_hours=…)(lnbits#55 item 2). The bunker stampsexpiresAtand rejects the token once it lapses, forcing a re-pair.None(default) = non-expiring; revoke is then the only invalidation path.(c) Revoke endpoint —
POST /machines/{id}/revokerevoke_spire→admin_client.revoke_key_user(spire-<id>)→set_machine_unpaired(clearspaired_at, keepsmachine_npub+bunker_spire_key_namefor audit / re-pair). ReturnsRevokeResult{revoked_count}(>= 1= access cut,0= nothing was bound).Why
revoke_key_user, not token revoke (the load-bearing detail,spirekeeper#22): lnbits eager-binds (redeems) the connect token at provision time (lnbits#32), so nsecbunkerd has already materialised the token's policy into standing per-KeyUserSigningConditiongrants. Its sign-time ACL checks those grants before theToken.revokedAtfilter — so revoking the token is a silent no-op and the spire keeps signing. OnlyKeyUser.revokedAt(viarevoke_user/revoke_key_user) actually cuts it off. Verified live againstnsecbunkerd@dev. A unit test asserts revoke routes torevoke_key_userand never token-revoke.Tests
7 new (210 green): duration threading + default-None;
revoke_spire→revoke_key_user(+ never token-revoke) + bunker-error mapping; endpoint wiring (revoke happy / zero-bound / 502). New code black + ruff clean.Notes
b5fba561) forrevoke_key_user+create_new_token(duration_hours=…).aiolabs/bitspire#52(spire-side consumer).🤖 Generated with Claude Code