fix(auth): log captured owner membership failures

Signed-off-by: seiler <seiler@squareup.com>
Co-authored-by: Codex <noreply@openai.com>
Signed-off-by: Brad Seiler <seiler@squareup.com>
This commit is contained in:
seiler
2026-10-12 02:45:26 +00:00
committed by Brad Seiler
parent 2d404097fb
commit 75d28073f2
2 changed files with 23 additions and 6 deletions

View File

@@ -312,10 +312,12 @@ also revokes that session. On open relays, an owner who was already a nonmember
at admission does not become a membership requirement. Moderation timeouts are
not read by this worker because they restrict writes, not an established
socket. All membership, ownership, and ban predicates include the bound
community. Admission reads the captured owner's membership from the writer
when the delegation check did not already establish it; that bounded point
lookup records the baseline needed to distinguish a later membership removal
from pre-existing open-relay nonmembership.
community. When the delegation check did not already establish the captured
owner's membership, admission makes a bounded writer-authoritative membership
read to record whether that owner was already a relay member. This adds a writer
dependency to admission; a failed point read refuses the socket with an
authorization-unavailable AUTH response. The baseline distinguishes a later
membership removal from pre-existing open-relay nonmembership.
Each batch snapshot is the revalidation ordering point. A removal or ban
committed before that snapshot closes the session; a re-add or unban committed

View File

@@ -233,6 +233,16 @@ pub(crate) struct FinalAdmissionCheck {
pub(crate) owner_was_relay_member_at_admission: bool,
}
fn admission_db_error_class(error: &buzz_db::DbError) -> &'static str {
match error {
buzz_db::DbError::Sqlx(sqlx::Error::PoolTimedOut) => "pool_timeout",
buzz_db::DbError::Sqlx(sqlx::Error::PoolClosed) => "pool_closed",
buzz_db::DbError::Sqlx(sqlx::Error::Io(_)) => "io_error",
error if error.is_statement_cancelled() => "statement_cancelled",
_ => "database_error",
}
}
/// Final ban and relay-membership verdict for an authenticating socket.
///
/// Callers bind the socket to `pubkey` first (the registry a ban's or
@@ -294,8 +304,13 @@ pub(crate) async fn final_admission_check(
.await
{
Ok(is_member) => is_member,
Err(_) => {
warn!("captured-owner membership snapshot failed at admission; denying");
Err(error) => {
warn!(
community = %community,
pubkey = %pubkey.to_hex(),
error_class = admission_db_error_class(&error),
"captured-owner membership writer check failed at admission; denying"
);
final_check.denial = Some(AdmissionDenial {
metric: "owner_membership_check_error",
reason: "error: internal error checking relay membership",