Example image

If you work with AWS temporary credentials at a production scale, at some point you risk being throttled by AWS because you are generating too many requests. The risk becomes even more prominent as AWS does not mention when it will start throttling you or the scope of throttling. This leaves the developers wondering if AWS is going to deny requests from a particular session, user or the entire account.

Caching the temporary credentials is one solution to the problem . This article illustrates certain challenges in caching the temporary credentials with Guava cache and how you can overcome them.

Sources of temporary credentials

There are two main sources from which you can generate temporary credentials from AWS

  1. Subscoping a long term credentials
    The credentials can have duration from 15 min to 12 hours.
  2. Assuming a role
    The credentials can have duration from 15 min to 1 hour.

We will talk about caching both of these type of credentials and why the implementation can differ for them.

Selecting a cache key

Cache key will depend on whether credential is generated by subscoping a long term credential or by assuming a role. The key may contain —

For temporary credentials generated from a long term credential:

  1. AWS_ACCESS_KEY_ID of long term creds
  2. POLICY — excluding the policy from the cache key may result in credentials with wrong policy being returned and may result in a security vulnerability.

For temporary credentials generated by assuming a role:

  1. ROLE_ARN
  2. EXTERNAL_ID — If present
  3. POLICY — excluding the policy from the cache key may result in credentials with wrong policy being returned and may result in a security vulnerability.

NOTE: AWS policy may contain durationSeconds for which the credentials are valid. If the durationSeconds gets included in the cache key and your clients request credentials with varying durationSeconds, our cache will generate new cache entry for every durationSeconds requested. To avoid this, you might want to exclude the durationSeconds in the policy from the cache key. More about credential validity guarantees in the next section about refreshing the cache entries.

Refreshing the cache entry (credentials)

When you are caching AWS temporary credentials, you are caching something that has a predefined shelf life (durationSeconds). The remaining duration of an entry will be different when you ask for it the next time. How we cache such entries will depend on the guarantees we would like to provide to our clients.

  1. Refreshing an entry only when the client asks for a credential with higher duration than what we have remaining on the cached credential.
    This will require writing an wrapper on top of guava cache which refreshes an entry if the client asks for a credential with higher duration than what we have. Guava currently does not natively support refreshing an entry based on a condition.
    Cons: If all/majority of your clients ask for an entry with highest duration(1 hour/12 hours), you will end up refreshing the entry for every client. If your clients ask the credential for a duration less than maximum, you can get around this by asking AWS for the credential for the maximum duration.
    Example — If the maximum duration for which you can ask AWS is 1 hr, and your clients all ask for a duration of say 45 min, you can always refresh for maximum duration of 1hr and then refresh when the remaining duration drops below 45 min.
  2. Refreshing an entry when some percentage of requested duration is remaining.
    This again requires writing a wrapper as guava does not support refreshing based on a condition. Also, guava does not allow specifying refresh interval per entry. Additionally, this will confuse your clients of what guarantee of lifespan your cache provides.
  3. Refreshing based on some guarantee you want to provide to your clients.
    This does not require writing a wrapper. In this approach your clients do not ask for a duration for which they want the credential. Instead you specify a duration guarantee (say 30 min) for which any credential returned by you will always be valid.
    Guava also does not allow you to specify different refresh interval per entry. So you may want ask AWS the credential for the maximum duration and then refresh it before reaches your minimum guaranteed duration.

Happy caching!