Description
When attempting to verify a LiveKit API token (signed with HS256) using auth.NewSimpleKeyProvider and providing the API secret as a standard Go string, the token.Verify() method returns a go-jose: unsupported key type/format error.
The API key and secret are loaded from environment variables and appear to be correctly read as strings with the expected values and length (32 characters for the secret).
This issue persists even after updating to the latest version of the livekit-server-sdk-go/v2.
According to the livekit/protocol/auth documentation, NewSimpleKeyProvider expects the API secret as a string, suggesting this is the intended usage. The error indicates that the underlying go-jose library, used by the SDK for verification, is unable to process the secret provided by the SimpleKeyProvider in the format it receives it for HS256 verification.
Steps to Reproduce:
- Configure LiveKit API key and secret in your environment or configuration, ensuring the secret is a string (e.g., 32 characters).
- In a Go application using livekit-server-sdk-go/v2 and livekit/protocol/auth, create an auth.SimpleKeyProvider using your API key and secret strings: provider := auth.NewSimpleKeyProvider(apiKeyString, apiSecretString)
- Obtain a valid LiveKit API token signed with the same API key and secret (either generated by the LiveKit server or using auth.NewAccessToken).
- Parse the token using auth.ParseAPIToken: token, err := auth.ParseAPIToken(rawTokenString) if err != nil { // handle error }
Attempt to verify the token using the provider: livekitClaims, err := token.Verify(provider)
Expected Behavior:
The token.Verify(provider) method should successfully verify the token using the provided string secret and return the claims without error.
Actual Behavior:
The token.Verify(provider) method returns an error: go-jose/go-jose: unsupported key type/format.
Code Snippet:
// Assuming h.auth.ApiKey and h.auth.ApiSecret are loaded from config/env
// and contain the LiveKit API Key and Secret as strings.
// ... (previous code to read request body and bind JSON) ...
// parse request body
var request types.UpdateLessonMetadataRequest // Assuming types.UpdateLessonMetadataRequest has a Token field string
if err := c.ShouldBindJSON(&request); err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if request.Token == "" {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "token is an empty string"})
return
}
// This is where the error occurs
provider := auth.NewSimpleKeyProvider(h.auth.ApiKey, h.auth.ApiSecret) // Passing strings as expected by documentation
token, err := auth.ParseAPIToken(request.Token)
if err != nil {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()}) // Assuming ParseAPIToken doesn't return the go-jose error
return
}
log.Printf("Using LiveKit API Key: '%s', Secret length: %d bytes", h.auth.ApiKey, len(h.auth.ApiSecret))
livekitClaims, err := token.Verify(provider) // Error happens here
if err != nil {
println("token verification error: " + err.Error()) // This prints the go-jose error
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// ... (rest of the function logic using livekitClaims) ...
Environment:
- Go Version: go1.24.2 linux/amd64
- LiveKit Server SDK Go Version: github.com/livekit/server-sdk-go/v2 v2.6.0
- Operating System: Linux Mint 22.1
- LiveKit Server Version: v1.8.4
Configuration:
livekit.yaml
keys:
"devkey": "this-is-a-32-character-secret-12"
.env
export LIVEKIT_API_KEY=devkey
export LIVEKIT_API_SECRET=this-is-a-32-character-secret-12