Best approach for dealing with expired Firebase tokens on Tapkey - firebase

I am authenticating my users with Firebase, and using the token exchange API to retrieve a tapkey token.
The issue I am having is that the Firebase certificate to authenticate the token expires regularly, as explained on the Firebase website:
Finally, ensure that the ID token was signed by the private key corresponding to the token's kid claim. Grab the public key from https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com and use a JWT library to verify the signature. Use the value of max-age in the Cache-Control header of the response from that endpoint to know when to refresh the public keys.
The max age for the current Firebase certificates is 22963 seconds (as I am writing this, just over 6 hours) and the process to upload a new public key to Tapkey is a manual one.
I'm considering writing a script to download a new certificate when the old ones expires, and extract the public key. Does Tapkey have an API endpoint I could use to post my updated public key to, or is there another approach I can take here?
Thanks

Currently there is no public api for updating a public key, but Tapkey is able to use a Firebase oidc discovery document url instead of public keys. If configured, Tapkey would automatically handle such key rollovers.
Firebase discovery document urls usually looks like https://securetoken.google.com/[firebase-project-id]/.well-known/openid-configuration.
However, this feature is not publicly available at this time. Send a request for activating the feature to Tapkey Support and they will enable it for you.

Related

Firebase token verification on server

I am trying to implement an authentication/authorization system using firebase and I am struggling with the last part of the authorization flow, which is, enabling my server to verify the validity of a token.
There are two ways to perform this:
Validate the token using the Admin SDK of firebase, where essentially a server communicates with Firebase and validates a token (safe option)
Validate the token using a third-party JWT library.
My question has to do with option (2), which according to documentation is perfectly feasible. The question is, how is this safe? Everything included in the token-validation process is public according to this:
Finally, ensure that the ID token was signed by the private key corresponding to the token's kid claim. Grab the public key from https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com and use a JWT library to verify the signature. Use
If the token is public, and the key for validating it is public, who guarantees that the token is genuine?
Probably there is something related to JWTs that I am missing?
PS. I have already implemented option (1) with remote validation, but this will significantly affect the application performance.
You can verify validity of a token with the public key, but you can only create tokens with the private key.
As their names imply:
Your private key should only be used in trusted environments, such as your development machine, a server you control, or Cloud Functions. So those are the only places where you can generate auth tokens.
The public key however can be shared with others, which means that they can use it to ensure that the token is valid.

Security issue with verifying firebase token on server side?

I am using firebase mobile otp authentication. After successful authentication my android app receives a token which I have to verify on my django server. But while I was reading the docs of verifying this token, it comes out that if someone knows my firebase project-id, they can generate valid tokens anytime they want.
To get contec, look at the last method to verify firebase token at link
Isn't this quite risky, as once your firebase project id is known to someone, they can create fake tokens??
Also does custom authentication token help overcome this problem?
Thanks. Let me know if I have incorrectly understood the firebase token validation and it is not possible to create fake tokens once we know the firebase project-id.
ID tokens are signed by a private key owned by Firebase Auth. They cannot be forged. Note that the doc you've referenced also states:
Finally, ensure that the ID token was signed by the private key corresponding to the token's kid claim. Grab the public key from https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com and use a JWT library to verify the signature.
A forged ID token will not pass the signature check.

Where do I find a key that JWT is signed with?

I develop phoenix app that uses Firebase as an external authentication service. I use Joken library. It requires me to use function with_signer that needs a cryptographic key. I suppose this is the key that JWT was signed with by Firebase. The question is - am I right in my assumptions? And more importantly - where do I find this key?
Firebase should publish a public key at a well known address that you can use to validate the JWTs.
The docs suggest:
Finally, ensure that the ID token was signed by the private key
corresponding to the token's kid claim. Grab the public key from
https://www.googleapis.com/robot/v1/metadata/x509/securetoken#system.gserviceaccount.com
and use a JWT library to verify the signature. Use the value of
max-age in the Cache-Control header of the response from that endpoint
to know when to refresh the public keys.

Using firebase jwt to authenticate users to external server\service?

Okay so in my iOS app I log the user into firebase, then get the jwt token. So now I have my server with an api which accepts an idtoken in the header of the GET.
What do I do here? Certainly I wouldn't be validating the JWT againt firebase on every single API call right? I mean its fast, but that adds latency with a second external check, no? How does one simply just decode that guy in C#? I have an Auth0 layer already and that decodes the JWT with my server-stored secret, but that same code doesn't work for the Firebase token.
Could it just be decoded then extract the user details from that, maybe just check expiry and if expiry > X months it's still okay?
In order to verify Firebase ID tokens and JWTs in general, you only make a network call on your server to get the public certs which are usually not updated for several hours. You could cache that and try to verify with an ID token and if it fails, only then, load the new public certs.
And yes, you must verify the ID token on each call especially since Firebase ID tokens expire after typically an hour and need to be refreshed continuously.

What does Firebase server side verifyIdToken() do under the hood?

I'm considering to use Firebase to perform identity verification. I am new to JWT, so my apologies if this is an obvious question, but I don't understand how the verification is actually done. It seems that FirebaseAuth.getInstance().verifyIdToken(idToken) works asynchronously, as the result is obtained via a listener. I understand that some certificates are used as described here, and that those certificates are rotated regularly. Does it mean that networking is required between my back-end server and Firebase server's each time I will call verifyIdToken()? Isn't it a problem ?
In order to verify Firebase ID tokens, the Firebase Auth public certs need to be retrieved (network request) and these are rotated on a regular basis. These are needed to ensure the Id token has not been tampered with. The JWT is first parsed, the algorithm to encrypt the token is checked to see if it matches the expected one, the signature is then verified using the public key obtained, finally the JWT claims are validated ensuring the token has not expired.

Resources