Skip to content

feat(auth): add a directly provisioned read-only channel observer #7462

Description

@100-eyes

Use case

A service needs to verify that one exact server event was delivered to an expected private channel without acquiring any mutation authority. The observer is provisioned by an operator, authenticates with its own Nostr key, and is explicitly present in only the channels it may observe.

This is narrower than #2475 / #3673: it needs no public link, self-service claim, desktop UI, guest writes, or new data plane.

Current gap

On a membership-gated relay, direct NIP-42 members receive every known scope. NIP-98 event submission similarly reconstructs the full scope set after checking membership. Several HTTP paths treat membership alone as mutation authority, and WebSocket COUNT does not enforce the MessagesRead scope used by REQ. Adding a cosmetic observer label would therefore still permit writes, joins/leaves, uploads, Git, huddle, GIF, and workflow operations.

Proposed minimal contract

  • Add one operator-provisioned relay principal class for a read-only observer.
  • Resolve the effective direct-member role once at the shared membership boundary.
  • Grant an explicit non-empty read-only scope set; initially MessagesRead only.
  • Continue to use existing channel membership for exact private-channel visibility.
  • Permit only WebSocket REQ/COUNT and HTTP query/count reads that pass the existing channel and community gates.
  • Deny event submission and every other HTTP surface by default, including media, Git, huddle, GIF, workflow, membership, join, and leave mutations.
  • Do not allow NIP-OA delegation from an observer principal in the initial version.
  • Preserve existing owner/admin/member behavior.
  • Cover direct read, write denial, cross-channel denial, cross-community denial, and NIP-OA denial through production seams.

Non-goals

No new observer endpoint, event store, token format, public guest flow, UI, reconciliation service, or changes to event payloads.

Would maintainers accept this narrow role-aware principal boundary independently of the broader scoped-guest work in #3673?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions