fschuindt/firebase_id_token

Auto-update certificates

ababich opened this issue ยท 6 comments

Imagine, you do not want to deal with cron and other periodic schedulers

What about automatically update certificates during single request if ttl <= configured_threshold

To prevent multiple instances to update in parallel it is simple to introduce some Redis-based lock

Great idea!

Even tho I think it's more likely to be chosen by the users.
You can use this technique by yourself in some kind of before_action, should work fine.

Probably I will add a section into README telling about this approach, what do you think?

Do you really think it's worth to implement it in the gem itself?

Thank you!
Best regards,

before_action is a good idea and can be also implemented in a gem as predefined action which you only need to activate when needed

From your practice what is more stable:

FirebaseIdToken::Certificates.request unless FirebaseIdToken::Certificates.present?

or

FirebaseIdToken::Certificates.request_anyway if FirebaseIdToken::Certificates.ttl < SOME_THRESHOLD

?

Cert request operation takes some time, what is happening with new incoming requests when certs are being update? In this case 2 looks better for me

About implementing the predefined action, I am still thinking. Need to decide if it's indeed a gem's responsibility to do so. But you have good points.

And about the two request options you showed, both will work. But in the second you will need to set SOME_THRESHOLD somewhere.

A good option might be creating a ActiveJob to request certs in background and using it like:

RequestCertificates.perform_now if low_threshold

def low_threshold
  FirebaseIdToken::Certificates.ttl < 1800
end

That way the current user won't be affected by the certs request, it will be processed in background and the the code can continue to execute even without the request have finished, 'cause we still have some Certificates.ttl left.

Note that I hard coded 1800 (30 minutes), but it's up to you.

What do you think?

EDIT:

what is happening with new incoming requests when certs are being update?

Yes, making certs update like so may lead to failures, it was not tested. I'm not sure.

I personally think you should stick with the cron tasks approach.

This is indeed a valuable and important discussion.

The gem uses Redis to store Google's x509 certificates and manage their expiration time, so you don't need to request Google's API in every execution and can access it as fast as reading from memory.

I think the design started off with a good intention. It was meant to improve the performance.

Correct me if I am wrong,
I think there are several inadequacies in the set of rules:

  1. Since the certificates expiration time is around 4 to 6 hours, what happens when the certificate is refreshed just before it is expired. Does it mean within the next interval/ threshold duration, all of the queries will fail due to the invalid certificate?

  2. I am not so worried about multiples instances update in parallel as it will still capture the valid and latest certificate. It is more on the redundant operations and performance issue.

@johnson-yeap You're right. That's the main idea behind the gem, you quoted well.

About your points:

  1. The certificates won't change very often after the TTL. Google's servers just renew it in most of the cases. But every time you request, you will get valid certificates with a long TTL. In other words: They won't serve you with a almost dying cert by the time you just made a HTTP request to them.

  2. Having stuff running in parallel (and probably messing up with Redis) is the major reason why you don't want to request certs during your application common flow. It's better (and safe) to keep updating requests either as a cron Rake Task or a cron ActiveJob.

And having the 2nd point in mind, I will close this issue.
Auto-update certs during your application common flow is possible, but risky.

I'm going to let the topic open to discussion as someone can point out better arguments.