diff --git a/artifacts/api-server/src/lib/relay-accounts.ts b/artifacts/api-server/src/lib/relay-accounts.ts index aac1c7a..88e0a96 100644 --- a/artifacts/api-server/src/lib/relay-accounts.ts +++ b/artifacts/api-server/src/lib/relay-accounts.ts @@ -2,19 +2,24 @@ * relay-accounts.ts — Relay account whitelist + access management. * * Trust tier → access level defaults (env-overridable): - * new → none (RELAY_ACCESS_NEW, default "none") + * new → read (RELAY_ACCESS_NEW, default "read") * established → write (RELAY_ACCESS_ESTABLISHED, default "write") * trusted → write (RELAY_ACCESS_TRUSTED, default "write") * elite → write (RELAY_ACCESS_ELITE, default "write") * - * Only "write" access generates an "accept" from the relay policy. - * "read" is reserved for future read-gated relays. - * "none" = default deny. + * Access semantics: + * "write" → relay policy returns "accept" (active write access) + * "read" → relay policy returns "reject" (read-only; no write permitted) + * "none" → relay policy returns "reject" (default deny; no access) * - * Revocation: - * revoke() sets grantedBy = "manual-revoked". syncFromTrustTier() respects - * this marker and will never auto-reinstate a manually revoked account. - * Only an explicit admin grant() call can restore access after revocation. + * Revocation — grantedBy sentinel "manual-revoked": + * The base contract for grantedBy is "manual" | "auto-tier". + * revoke() additionally writes "manual-revoked" as a sentinel to prevent + * syncFromTrustTier() from auto-reinstating the account on the next trust + * update. This is intentional: admin revocation must be permanent until + * an explicit grant() call restores access. The sentinel is an internal + * implementation detail; callers should treat "manual-revoked" rows as + * revoked and must not try to grant access by reusing the sentinel value. */ import { db, nostrIdentities, relayAccounts } from "@workspace/db"; @@ -33,7 +38,7 @@ function envAccess(name: string, fallback: RelayAccessLevel): RelayAccessLevel { } const TIER_ACCESS: Record = { - new: envAccess("RELAY_ACCESS_NEW", "none"), + new: envAccess("RELAY_ACCESS_NEW", "read"), established: envAccess("RELAY_ACCESS_ESTABLISHED", "write"), trusted: envAccess("RELAY_ACCESS_TRUSTED", "write"), elite: envAccess("RELAY_ACCESS_ELITE", "write"),