fix(mediorum): case-insensitive access authority check#203
fix(mediorum): case-insensitive access authority check#203rickyrombo wants to merge 4 commits intomainfrom
Conversation
Ethereum addresses can vary in casing (checksummed vs lowercase). Use LOWER() on both sides of the management_keys address comparison so streaming auth matches regardless of case, consistent with the existing EqualFold check for validator/peer wallets. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes gated streaming authorization failures caused by mixed-case Ethereum addresses by making management_keys address checks case-insensitive across Mediorum’s HTTP middleware, dev HTTP track streaming, and dev gRPC streaming paths.
Changes:
- Update
management_keysauthorization queries to compareaddresscase-insensitively viaLOWER(address) = LOWER(?). - Apply the same logic consistently across
requireRegisteredSignature,serveTrack, andstreamTrackGRPC.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| pkg/mediorum/server/serve_blob.go | Makes access-authority (management_keys) checks case-insensitive in HTTP streaming auth + dev track streaming. |
| pkg/mediorum/server/serve_blob_grpc.go | Makes access-authority (management_keys) checks case-insensitive in the dev gRPC streaming path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if trackID != "" && managementKeyCount > 0 { | ||
| var count int | ||
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND address = ?", trackID, sig.SignerWallet).Scan(&count) | ||
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND LOWER(address) = LOWER(?)", trackID, sig.SignerWallet).Scan(&count) |
There was a problem hiding this comment.
Using LOWER(address) in the WHERE clause will generally prevent Postgres from using the existing btree index on (track_id, address) (see migration adding idx_management_keys_track_id_address). Since this check runs on the streaming auth path, consider normalizing addresses on write (store lowercase) and compare with address = LOWER(?) OR add a functional/composite index on (track_id, LOWER(address)) to avoid scanning all keys for a track.
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND LOWER(address) = LOWER(?)", trackID, sig.SignerWallet).Scan(&count) | |
| normalizedSignerWallet := strings.ToLower(sig.SignerWallet) | |
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND address = ?", trackID, normalizedSignerWallet).Scan(&count) |
|
|
||
| var count int | ||
| ss.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND address = ?", trackId, sig.SignerWallet).Scan(&count) | ||
| ss.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND LOWER(address) = LOWER(?)", trackId, sig.SignerWallet).Scan(&count) |
There was a problem hiding this comment.
Same index-usage concern here: LOWER(address) likely bypasses the existing (track_id, address) index, which can increase per-request DB work on this endpoint. Consider normalizing stored addresses to lowercase and comparing directly, or adding an index on (track_id, LOWER(address)).
| ss.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND LOWER(address) = LOWER(?)", trackId, sig.SignerWallet).Scan(&count) | |
| normalizedSignerWallet := strings.ToLower(sig.SignerWallet) | |
| ss.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND address = ?", trackId, normalizedSignerWallet).Scan(&count) |
|
|
||
| var count int | ||
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND address = ?", trackId, ethAddress).Scan(&count) | ||
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND LOWER(address) = LOWER(?)", trackId, ethAddress).Scan(&count) |
There was a problem hiding this comment.
This query change to LOWER(address) is likely to bypass the existing (track_id, address) index in Postgres. Because gRPC streaming can be high-volume, consider normalizing stored addresses (lowercase) and comparing directly, or adding a functional/composite index on (track_id, LOWER(address)) to keep auth checks efficient.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Applied in dceccd0. All three locations now normalize the address to lowercase in Go (strings.ToLower) before passing it to the SQL query, so the existing (track_id, address) index is preserved.
| // If track has access_authorities (management_keys), ONLY those signers may authorize - not validator keys | ||
| if trackID != "" && managementKeyCount > 0 { | ||
| var count int | ||
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND address = ?", trackID, sig.SignerWallet).Scan(&count) | ||
| s.crud.DB.Raw("SELECT COUNT(*) FROM management_keys WHERE track_id = ? AND LOWER(address) = LOWER(?)", trackID, sig.SignerWallet).Scan(&count) | ||
| if count == 0 { |
There was a problem hiding this comment.
There are existing unit tests for requireRegisteredSignature, but none cover the access_authorities/management_keys path with mixed-case addresses. Add a test where the stored management_keys.address casing differs from the signer wallet (checksummed vs lowercase) to ensure this regression stays fixed.
…ndex usage Agent-Logs-Url: https://github.com/OpenAudio/go-openaudio/sessions/4323f5ff-0b33-47bb-911c-7cb6e682029c Co-authored-by: rickyrombo <3690498+rickyrombo@users.noreply.github.com>
…dex usage Agent-Logs-Url: https://github.com/OpenAudio/go-openaudio/sessions/4323f5ff-0b33-47bb-911c-7cb6e682029c Co-authored-by: rickyrombo <3690498+rickyrombo@users.noreply.github.com>
Ensures management_keys.address is always stored lowercase so streaming auth comparisons match regardless of the casing in the original tx. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
management_keysto fail when casing doesn't match exactly.requireRegisteredSignature,serveTrack,streamTrackGRPC) to useLOWER(address) = LOWER(?)for case-insensitive comparison.strings.EqualFoldused for validator/peer wallet checks.Test plan
make test-mediorum🤖 Generated with Claude Code