upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/docs/explanation/inline-authorization.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/explanation/inline-authorization.md')
-rw-r--r--docs/explanation/inline-authorization.md93
1 files changed, 93 insertions, 0 deletions
diff --git a/docs/explanation/inline-authorization.md b/docs/explanation/inline-authorization.md
index a71a217..7081f63 100644
--- a/docs/explanation/inline-authorization.md
+++ b/docs/explanation/inline-authorization.md
@@ -352,6 +352,99 @@ pub async fn authorize_push(
352 - If no event found, create placeholder (git-data-first scenario) 352 - If no event found, create placeholder (git-data-first scenario)
353 - Collect PR events from purgatory for post-push processing 353 - Collect PR events from purgatory for post-push processing
354 354
355## State Event Authorization
356
357State events (kind 30618) undergo authorization checks at three points (defense-in-depth):
358
359### 1. On Arrival (StatePolicy)
360
361When a state event arrives via WebSocket or sync:
362
363```rust
364// src/nostr/policy/state.rs
365impl StatePolicy {
366 async fn admit_event(&self, event: &Event) -> Result<Decision, Error> {
367 // Check 1: Does announcement exist for this repository?
368 let announcements = query_announcements(pubkey, identifier);
369 if announcements.is_empty() {
370 return Reject("No announcement exists for repository");
371 }
372
373 // Check 2: Is author in maintainer set?
374 let maintainers = build_maintainer_set(announcements);
375 if !maintainers.contains(&event.author) {
376 return Reject("Author not in maintainer set");
377 }
378
379 // If git data doesn't exist yet, goes to purgatory
380 // Otherwise, accepted to database
381 }
382}
383```
384
385### 2. On Announcement Acceptance (Purgatory Re-evaluation)
386
387When a repository announcement is accepted, waiting state events are re-evaluated:
388
389```rust
390// After announcement is saved to database
391for state_event in purgatory.get_state_events(identifier) {
392 // Re-check authorization now that announcement exists
393 if author_in_maintainer_set(state_event.author, identifier) {
394 // If git data now exists, save to database
395 // Otherwise, keep in purgatory
396 } else {
397 // Remove from purgatory - not authorized
398 }
399}
400```
401
402### 3. On Git Data Arrival (Purgatory Sync)
403
404When git data is pushed, purgatory state events are validated before saving:
405
406```rust
407// src/git/handlers.rs - after successful git push
408for state_event in purgatory.get_matching_state_events(identifier) {
409 // Final authorization check before database save
410 if author_in_maintainer_set(state_event.author, identifier) {
411 database.save(state_event);
412 purgatory.remove(state_event);
413 } else {
414 purgatory.remove(state_event); // Not authorized
415 }
416}
417```
418
419### Why Three Checkpoints?
420
421**Defense-in-depth** ensures authorization is always validated:
422
4231. **On arrival**: Prevents unauthorized events from entering the system
4242. **On announcement acceptance**: Handles race condition where state arrives before announcement
4253. **On git data arrival**: Final check before committing to database
426
427This prevents scenarios where:
428- Unauthorized state events are saved after maintainer changes
429- Race conditions bypass authorization
430- Purgatory holds events that will never be authorized
431
432### Rejection Tracking
433
434State events rejected during authorization are tracked in the rejected events index:
435
436- **Reason: MaintainerNotYetValid** - Author not in maintainer set (may become valid later)
437- **Reason: Other** - Other validation failures
438
439When a repository announcement is accepted, rejected state events for that repository are:
4401. **Invalidated** from cold index (removed from negentropy exclusion)
4412. **Retrieved** from hot cache (if still available within 2 minutes)
4423. **Re-processed** immediately with new maintainer set
443
444This enables rapid recovery from race conditions where state events arrive before maintainer announcements.
445
446See [work/rejected-events-index-summary.md](../../work/rejected-events-index-summary.md) for complete details on rejection tracking and re-processing.
447
355--- 448---
356 449
357## Comparison with Reference Implementation 450## Comparison with Reference Implementation