Skip to content

Commit d7b08a3

Browse files
committed
fix: accept EOA-subject admin keys in legacy VerifyJwtKeyForUser
GetKey (the API key exchange handler used by SDK authWithAPIKey) calls VerifyJwtKeyForUser, which had two bugs that combined to reject every key generated by the modern create-api-key CLI: 1. It only treated the literal string "apikey" as an admin subject, but PR #509 changed CreateAdminKey to require an EOA address as the JWT subject — so admin keys never matched the role-based path. 2. For EOA-subject JWTs, even when claimAddress == userWallet, the function fell through to "Malform JWT Key Claim" because the address-match branch was missing a `return true, nil`. Add an EOA-subject branch that mirrors the modern verifyAuth contract: admin-role keys may manage any wallet; non-admin keys are valid only when subject == userWallet. Discovered while debugging AvaProtocol/ava-sdk-js#209 CI failures.
1 parent 0b07f28 commit d7b08a3

1 file changed

Lines changed: 15 additions & 0 deletions

File tree

core/auth/user.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,25 @@ func VerifyJwtKeyForUser(secret []byte, key string, userWallet common.Address) (
8585
return true, nil
8686
}
8787

88+
// EOA-subject JWTs (issued by `create-api-key` since #509). Two valid cases:
89+
// 1. The JWT carries an admin role → it can manage any wallet.
90+
// 2. The JWT subject equals the requesting userWallet → per-wallet key.
8891
claimAddress := common.HexToAddress(sub)
92+
93+
if rolesVal, hasRoles := claims["roles"]; hasRoles {
94+
if rolesArray, ok := rolesVal.([]any); ok {
95+
for _, v := range rolesArray {
96+
if roleStr, ok := v.(string); ok && ApiRole(roleStr) == "admin" {
97+
return true, nil
98+
}
99+
}
100+
}
101+
}
102+
89103
if claimAddress != userWallet {
90104
return false, fmt.Errorf("Invalid Subject")
91105
}
106+
return true, nil
92107
}
93108

94109
return false, fmt.Errorf("Malform JWT Key Claim")

0 commit comments

Comments
 (0)