Skip to content

Add Jwt cache.#14341

Merged
wrowe merged 64 commits intoenvoyproxy:mainfrom
mk46:jwt-cache
Jul 22, 2021
Merged

Add Jwt cache.#14341
wrowe merged 64 commits intoenvoyproxy:mainfrom
mk46:jwt-cache

Conversation

@mk46
Copy link
Copy Markdown
Contributor

@mk46 mk46 commented Dec 9, 2020

Signed-off-by: Manish Kumar manish.kumar1@india.nec.com

Commit Message: Add Jwt cache.
Additional Description: Added Jwt cache, which makes Jwt verification faster.
Risk Level:
Testing: Format and unit
Docs Changes: done
Release Notes: done
Fixes #12644

Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
@mk46 mk46 requested a review from lizan as a code owner December 9, 2020 12:37
@mk46 mk46 marked this pull request as draft December 9, 2020 12:38
@mk46
Copy link
Copy Markdown
Contributor Author

mk46 commented Dec 9, 2020

Hi @qiwzhang PTAL, I am not sure where to call addTokenResult and findTokenResult.

// The pubkey expiration time.
MonotonicTime expiration_time_;
// Jwt object for verified token.
std::unique_ptr<::google::jwt_verify::Jwt> jwt_;
Copy link
Copy Markdown
Contributor

@qiwzhang qiwzhang Dec 9, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cache should be:


// Map a token to its result in the cache
absl::flat_hash_map<string,  TokenResult> token_cache_;

Struct TokenResult {
     // cache expire time, default cache for 5 minutes
     MonotonicTime expiration_time_;
     // verification status
     Status  status_;
}

In the jwt_authn config, in the JwtProvider config, add

   // enable cache 
   bool enable_token_cache ;

  // specify token cache during,  default to 5 minutes
   Duration  token_cache_duration;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the cache have a (optionally) limited size to cap the amount of memory it can use?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh nvm, i saw you commented on that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Contributor

@qiwzhang qiwzhang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My proposed change only skip jwt::verify part with cache. We still need to parse jwt. I am not sure how fast the jwt parsing which is base64url_decode() of 3 sections.

Maybe we should.

Some other issuers we need to work on:

  1. should a cache item be expired? Maybe not. But we need to handle "exp" and "nbf" correctly. Since we cache parsed jwt result, even for cache hit, we should always check its time constraint. For a "nbf" failed token, once time comes, it is valid again, we should verify it and cache the verify result.

  2. cache size should not keep growing, otherwise we will have OOO. How, and when do we purge cache? Should we use LRU?

@qiwzhang
Copy link
Copy Markdown
Contributor

qiwzhang commented Dec 9, 2020

BTW, there is a LRU cache implementation here. We can copy the code here

A good example of jwt_cache code using that LRU cache is here

Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
@repokitteh-read-only
Copy link
Copy Markdown

CC @envoyproxy/api-shepherds: Your approval is needed for changes made to api/envoy/.
API shepherd assignee is @lizan
CC @envoyproxy/api-watchers: FYI only for changes made to api/envoy/.

🐱

Caused by: #14341 was synchronize by mk46.

see: more, trace.

@mk46 mk46 marked this pull request as ready for review December 13, 2020 09:53
@lizan
Copy link
Copy Markdown
Member

lizan commented Dec 13, 2020

BTW, there is a LRU cache implementation here. We can copy the code here

A good example of jwt_cache code using that LRU cache is here

Can we have this LRU as a part of jwt-verify-lib? That makes license and ownership clearer.

Manish Kumar added 3 commits December 13, 2020 16:57
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
@qiwzhang
Copy link
Copy Markdown
Contributor

qiwzhang commented Dec 14, 2020

@mk46 Please copy simple_lru code to jwt_verify_lib repo and keep their copyright info? Thanks

@qiwzhang
Copy link
Copy Markdown
Contributor

qiwzhang commented Dec 16, 2020

I think it is quite slow to parsing JWT token (split sections and base64_decode). I like jwt_cache to cache the parsing result too.

So here is how it should work:

struct TokenCacheData {
   // jwt parsing status
   Status  jwt_status;
   // parsed JWT
   std::unique_ptr<Jwt>  jwt_;
   // If valid, the  verification status
   optional<Status> sig_status;
};

We don't need "cache_duration" config. Usually, a token has "exp" field for 1 hour, it is removed from the cache when it is expired. For parsing failed token, it doesn't have expiration time, it will be purged by LRU. If a token doesn't have "exp", it never expire, it is OK to keep it in the cache until purged by LRU.

So the data follow is:

1) for a token, check its cache, if cache miss, do the normal parsing, verification, and cache its result
2) for a cache hit, check its `jwt_status`,  if it is OK,   verifyTimeConstraint of its jwt.   If it is expired, remove it from the cache
3) if sig_status is invalid, verify it, otherwise use sig_sattus

Hi @mk46 what do you think?

@mk46
Copy link
Copy Markdown
Contributor Author

mk46 commented Dec 16, 2020

SGTM, We should keep cache_duration in the config and will be evaluated like min(exp, cache_duration) if given otherwise exp.

@qiwzhang
Copy link
Copy Markdown
Contributor

SG for "cache_duration" config. If specified, it can apply to parsing failed token too.

@mk46
Copy link
Copy Markdown
Contributor Author

mk46 commented Dec 16, 2020

I think we should leave it for a failed token while parsing. Since the probability of hitting the same failed token will be very less. Please LMK if you still want to keep it.

@qiwzhang
Copy link
Copy Markdown
Contributor

OK, if we don't cache parsing failed tokens, the data flow could be much simpler. Thanks

Manish Kumar added 3 commits December 17, 2020 16:47
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
@repokitteh-read-only repokitteh-read-only bot added the deps Approval required for changes to Envoy's external dependencies label Dec 25, 2020
qiwzhang
qiwzhang previously approved these changes Jul 8, 2021
@repokitteh-read-only repokitteh-read-only bot removed the deps Approval required for changes to Envoy's external dependencies label Jul 13, 2021
wrowe
wrowe previously approved these changes Jul 13, 2021
Copy link
Copy Markdown
Contributor

@wrowe wrowe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm deps

@wrowe
Copy link
Copy Markdown
Contributor

wrowe commented Jul 13, 2021

@htuch please reconfirm for api and your asks, and I'm happy to merge.

@mk46 mk46 dismissed stale reviews from wrowe and qiwzhang via 1de642f July 14, 2021 16:30
@repokitteh-read-only repokitteh-read-only bot added api deps Approval required for changes to Envoy's external dependencies labels Jul 14, 2021
@mk46 mk46 requested review from htuch, qiwzhang and wrowe July 14, 2021 16:32
Manish Kumar added 3 commits July 14, 2021 22:34
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
fix
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
@mk46
Copy link
Copy Markdown
Contributor Author

mk46 commented Jul 15, 2021

@lizan Please take a look. Thanks!

Manish Kumar added 2 commits July 15, 2021 11:58
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
fix
Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
Copy link
Copy Markdown
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm api

Copy link
Copy Markdown
Contributor

@wrowe wrowe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lizan's changes seem to be addressed, /lgtm deps

@moderation
Copy link
Copy Markdown
Contributor

/lgtm deps

@wrowe for repokitteh to pick up the deps approval it needs to be on it's own line

@repokitteh-read-only repokitteh-read-only bot removed the deps Approval required for changes to Envoy's external dependencies label Jul 19, 2021
@wrowe wrowe dismissed htuch’s stale review July 22, 2021 19:04

All threads resolved, dismissing per @htuch on slack

@wrowe wrowe merged commit 2738707 into envoyproxy:main Jul 22, 2021
@mk46 mk46 mentioned this pull request Jul 26, 2021
leyao-daily pushed a commit to leyao-daily/envoy that referenced this pull request Sep 30, 2021
* Add Jwt cache.
* Added release docs.
* Added unit test.

Signed-off-by: Manish Kumar <manish.kumar1@india.nec.com>
Co-authored-by: Wayne Zhang <qiwzhang@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add JWT cache