-
Notifications
You must be signed in to change notification settings - Fork 268
Open
Labels
Description
Description
When verifying a Firebase ID token generated by a Flutter Firebase Auth SDK, the Go Admin SDK consistently returns:
InvalidArgument desc = failed to verify token signature
Even though:
- The token header contains a valid
kidpresent in the keys fetched from
https://www.googleapis.com/robot/v1/metadata/x509/[email protected] - The
issandaudin the payload match the Firebase project (demo-project-123456) - The token has a valid
iat/expand is not expired - The Admin SDK is initialized with the correct service account and
ProjectID - System clock is correct
- No emulator is used (
FIREBASE_AUTH_EMULATOR_HOSTunset)
Environment
- SDK:
firebase.google.com/go/v4 - Go version:
go1.25 - OS/Env: (windows)
- Project ID:
demo-project-123456
Steps to reproduce
-
Sign in to Firebase Auth from a Flutter mobile client using Google provider:
final user = await FirebaseAuth.instance.signInWithCredential(credential); final token = await user.user?.getIdToken();
2. Send the idToken to the backend.
3. On the backend, verify with Go Admin SDK:
```go
package main
import (
"context"
"fmt"
"log"
firebase "firebase.google.com/go/v4"
"google.golang.org/api/option"
)
func main() {
ctx := context.Background()
app, err := firebase.NewApp(ctx, &firebase.Config{ProjectID: "demo-project-123456"},
option.WithCredentialsFile("service-account.json"))
if err != nil {
log.Fatal(err)
}
auth, err := app.Auth(ctx)
if err != nil {
log.Fatal(err)
}
token := "<PASTE_ID_TOKEN_HERE>"
t, err := auth.VerifyIDToken(ctx, token)
if err != nil {
log.Fatalf("verify failed: %v", err)
}
fmt.Println("UID:", t.UID)
}
- Observe error:
failed to verify token signature
Sample Token
Header
{
"alg": "RS256",
"kid": "e3ee7e028e3885a345ce07055f846862255a7046",
"typ": "JWT"
}Payload
{
"name": "Mr Robot",
"picture": "https://lh3.googl....",
"iss": "https://securetoken.google.com/demo-project-123456",
"aud": "demo-project-123456",
"auth_time": 1757591071,
"user_id": "demoUser12345",
"sub": "demoUser12345",
"iat": 1757591071,
"exp": 1757594671,
"email": "[email protected]",
"email_verified": true,
"firebase": {
"identities": {
"google.com": [
"123456789..."
],
"email": [
"[email protected]"
]
},
"sign_in_provider": "google.com"
}
}Expected behavior
VerifyIDToken should successfully verify and return a parsed auth.Token struct with UID/email claims.
Actual behavior
Verification fails with: "INVALID_ARGUMENT" "failed to verify token signature"
Additional notes
- We validated the token manually: base64-decoding header/payload shows correct structure.
- The kid matches one of the keys in Google’s x509 JWKS endpoint.
- No emulator is used, and project IDs match.
- Same error reproduces in a minimal standalone program outside of our service.
and the execution hit
auth/token_verifier.go: 310
func (tv *tokenVerifier) verifySignatureWithKeys(ctx context.Context, token string, keys []*publicKey) bool {
segments := strings.Split(token, ".")
var h jwtHeader
decode(segments[0], &h)
verified := false
for _, k := range keys {
if h.KeyID == "" || h.KeyID == k.Kid {
if verifyJWTSignature(segments, k) == nil {
verified = true
break
}
}
}
return verified
}