Skip to content

Bug: go-jose: unsupported key type/format error when verifying token with SimpleKeyProvider and string secret #647

Description

@andrzejstepien

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:

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 

Activity

  1. changed the title [-]go-jose: unsupported key type/format error when verifying token with SimpleKeyProvider and string secret[/-] [+]Bug: go-jose: unsupported key type/format error when verifying token with SimpleKeyProvider and string secret[/+] on May 4, 2025
  2. andrzejstepien commented on May 18, 2025

    @andrzejstepien
    Author

    Hello again,

    We have upgraded to github.com/livekit/server-sdk-go/v2 v2.8.2 which pulls in github.com/go-jose/go-jose/v3 v3.0.4 indirectly, but the problem persists, so, to unblock development while awaiting a resolution, we have implemented a temporary workaround by performing the LiveKit JWT verification manually using the github.com/golang-jwt/jwt/v5 library.

    This manual verification bypasses the livekit-server-sdk-go/v2's built-in verification flow for this specific step but performs the essential cryptographic signature validation and standard claims checks (like expiry) using the provided API Secret.

    Since this manual verification works while the SDK's built-in method (auth.NewSimpleKeyProvider + token.Verify) fails with a key format error, it strongly indicates that the issue lies specifically within the SDK's implementation of token verification or its interaction with the go-jose library when using SimpleKeyProvider and a string secret in our environment.

    Hopefully this info will help someone else while we await a resolution to this issue.

    Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions