Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,7 @@ future metadata site can attach enrichment without reshaping the schema. The
and forgets the row (`UnpairBridge`). **The bridge token is narrow**: routes opt in to token kinds and only
the Bridge's own list `auth.KindBridge` (`requireBridge` = `authenticate` with `bridgeKinds`,
`/api/v1/bridge/*`, Authorization header only, never `?token=`; only a missing or refused token is a 401,
which makes the Bridge forget its token, so a failure to check one is a 503); `resolve` refuses it once its admin is
which stops the Bridge calling in until its 5-minute retry, so a failure to check one is a 503); `resolve` refuses it once its admin is
demoted (lookupToken already refuses a disabled one); it is never a device, and never touched (its calls
are not its admin's activity, the newest `last_seen` of their tokens). "Paired" has ONE statement,
`auth.BridgeLiveSQL` (a live bridge token of an enabled admin, partial index `idx_tokens_bridge`), which
Expand Down
4 changes: 2 additions & 2 deletions internal/api/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,8 +672,8 @@ func TestServerInfoWithoutBridge(t *testing.T) {
}
}

// Security-critical: the Bridge forgets its token at the first 401, so only a
// refused token is one; a token the server can't check (its database failing)
// Security-critical: a 401 stops the Bridge calling in (it retries every few
// minutes), so only a refused token is one; a token the server can't check (its database failing)
// is a 503 the Bridge retries.
func TestBridgeTokenCheckFailureIsNotUnauthorized(t *testing.T) {
t.Parallel()
Expand Down
Loading