Back to all articles
JWT API Authentication

Using jose to validate a Firebase JWT token

Josh Twist
ยท
April 5, 2023
ยท
1 min read

Firebase JWT tokens are a little unusual because they don't use secrets or JWKS but have public X509 certs

April 5, 2023

We're working on adding support for Firebase auth to Zuplo (as we did with Supabase) and in doing so came across their JWT signing approach which is one of the more unusual. They sign their tokens with certs and they publish these certs at a well-known URL: https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com.

It took us a while to work out how to validate these JWT tokens using our preferred library: Jose.

Hopefully this will save you some time if you're trying to do the same thing. Note that we cache the certs in memory since they do not change often (hopefully!).

TypeScriptts
let publicKeys: any;

const getPublicKeys = async () => {
  if (publicKeys) {
    return publicKeys;
  }
  const res = await fetch(
    `https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com`,
  );
  publicKeys = await res.json();
  return publicKeys;
};

// This goes
// inside your auth function or middleware

const authHeader = request.headers.get("authorization");
const token = authHeader.substring("bearer ".length);

const firebaseProjectId = "your-project-id";

const verifyFirebaseJwt = async (firebaseJwt) => {
  const publicKeys = await getPublicKeys();
  const decodedToken = await jwtVerify(
    firebaseJwt,
    async (header, _alg) => {
      const x509Cert = publicKeys[header.kid];
      const publicKey = await importX509(x509Cert, "RS256");
      return publicKey;
    },
    {
      issuer: `https://securetoken.google.com/${firebaseProjectId}`,
      audience: firebaseProjectId,
      algorithms: ["RS256"],
    },
  );
  return decodedToken.payload;
};

try {
  // This will throw an error if the token is invalid
  const tokenData = await verifyFirebaseJwt(token);
  console.log(`We got a valid token`, tokenData);
} catch (err) {
  console.error(`Invalid Token`, err);
}

Hope you find that useful. Of course, you could always sign up for a free Zuplo account at portal.zuplo.com and get Firebase JWT auth as easy as configuring a policy ๐Ÿ‘ ๐Ÿ‘ ๐Ÿ‘

Related Articles

Continue reading from the Zuplo blog.

API Monetization 101

API Monetization 101: Your Guide to Charging for Your API

A three-part series on API monetization: what to count, how to structure plans, and how to decide what to charge. Start here for the full picture.

4 min read
API Monetization 101

Use AI to Plan Your API Pricing Strategy

Get clear tiers, a comparison table, and reasoning so you can price your API with confidence and move on to implementation faster.

3 min read

Scale your APIs with
confidence.

Start for free or book a demo with our team.
Book a demoStart for Free
SOC 2 TYPE 2High Performer Spring 2025Momentum Leader Spring 2025Best Estimated ROI Spring 2025Easiest To Use Spring 2025Fastest Implementation Spring 2025

Get Updates From Zuplo

Zuplo logo
ยฉ 2026 zuplo. All rights reserved.
Products & Features
API ManagementAI GatewayMCP ServersMCP GatewayDeveloper PortalRate LimitingOpenAPI NativeGitOpsProgrammableAPI Key ManagementMulti-cloudAPI GovernanceMonetizationSelf-Serve DevX
Developers
DocumentationBlogLearning CenterCommunityChangelogIntegrations
Product
PricingSupportSign InCustomer Stories
Company
About UsMedia KitCareersStatusTrust & Compliance
Privacy PolicySecurity PoliciesTerms of ServiceTrust & Compliance
Docs
Pricing
Sign Up
Login
ContactBook a demoFAQ
Zuplo logo
DocsPricingSign Up
Login