Skip to content

Extract JWT claims as string lists under request.auth.claims[] for RBAC#1906

Closed
lei-tang wants to merge 7 commits intoistio:masterfrom
lei-tang:update_group_output
Closed

Extract JWT claims as string lists under request.auth.claims[] for RBAC#1906
lei-tang wants to merge 7 commits intoistio:masterfrom
lei-tang:update_group_output

Conversation

@lei-tang
Copy link
Copy Markdown
Contributor

@lei-tang lei-tang commented Aug 9, 2018

What this PR does / why we need it: Extract JWT claims as string lists under request.auth.claims[] for RBAC.

Which issue this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close that issue when PR gets merged): fixes #

Special notes for your reviewer:

Release note:

@istio-testing
Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To fully approve this pull request, please assign additional approvers.
We suggest the following additional approver: jimmycyj

If they are not already assigned, you can assign the PR to them by writing /assign @jimmycyj in a comment when ready.

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@googlebot googlebot added the cla: yes Set by the Google CLA bot to indicate the author of a PR has signed the Google CLA. label Aug 9, 2018
lei-tang referenced this pull request Aug 9, 2018
* Add the groups JWT claims to the attribute request.auth.groups

* Fix lint errors

* Simplify the code

* Fix lint error

* Simplify the code

* Add a test

* Fix the test error
@lei-tang
Copy link
Copy Markdown
Contributor Author

lei-tang commented Aug 9, 2018

/cc @liminw

@istio-testing istio-testing requested a review from liminw August 9, 2018 23:09
@lei-tang
Copy link
Copy Markdown
Contributor Author

lei-tang commented Aug 9, 2018

/cc @diemtvu

@istio-testing istio-testing requested a review from diemtvu August 9, 2018 23:09
@lei-tang
Copy link
Copy Markdown
Contributor Author

lei-tang commented Aug 9, 2018

/cc @qiwzhang

[istio::utils::AttributeName::kAuthDerivedClaims]
.mutable_struct_value();
::google::protobuf::ListValue* value =
(*s->mutable_fields())["groups"].mutable_list_value();
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.

Please use new styple for loop

for (const auto& group : origin.groups()) 

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

@diemtvu diemtvu left a comment

Choose a reason for hiding this comment

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

Overall, I think we should change the way we populate and passing claims. First, we should change the type under JwtPayload to use protobuf::Struct (https://github.com/istio/proxy/blob/master/src/istio/authn/context.proto#L37), so we it's more flexible to keep all claims, instead of just string. There may be an util to convert Json object to proto struct, if you are lucky. Though it's should be ok to write one, and 'normalize' the type (e.g always keep as string array for certain types).

After that, in this part of the code, you simply need to set the 'request.auth.claims' to that struct without any modification.

@lei-tang lei-tang force-pushed the update_group_output branch from df22cea to 1549b46 Compare August 14, 2018 00:15
@lei-tang lei-tang changed the title Reorganize the groups claim under auth.derived.claims Organize the groups claim in request.auth.claims[groups] Aug 14, 2018
@lei-tang lei-tang force-pushed the update_group_output branch from 1549b46 to 47d2ea4 Compare August 14, 2018 00:21
@lei-tang
Copy link
Copy Markdown
Contributor Author

/cc @wattli

@istio-testing istio-testing requested a review from wattli August 14, 2018 00:38
@lei-tang
Copy link
Copy Markdown
Contributor Author

This PR puts the groups claim (e.g., "groups: group1") in a JWT under the key request.auth.claims[groups] in the dynamic metadata (this is to be consistent with istio/istio#7747). The change of JwtPayload in context.proto to use protobuf::Struct can be implemented in a separate PR.

@@ -58,12 +58,14 @@ void Authentication::SaveAuthAttributesToStruct(
origin.audiences(0));
}
if (!origin.groups().empty()) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Can we do it for all claims instead of just "groups"?

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.

A JWT may contain various claims, including user defined ones (e.g., department, machine-model, IMEI and etc). Probably we can place all claims in a JWT into request.auth.claims[] or we can all non-well-known claims in a JWT into request.auth.claims[]. But such a PR can be a separate PR to keep this PR small and simple.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In the Pilot PR istio/istio#7747 you just checked in, all claims are matched using ListMatcher. If you don't create ListValue for all claims here, RBAC will break.

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.

Per discussions, in this PR, JWT claims are extracted as string lists for RBAC list matcher. A new PR https://github.com/istio/proxy/issues/1920 has been created to change the "claims" to a protobuf struct.

@lei-tang lei-tang changed the title Organize the groups claim in request.auth.claims[groups] Extract JWT claims as string lists under request.auth.claims[] for RBAC Aug 14, 2018
@lei-tang lei-tang force-pushed the update_group_output branch from e795b7c to 4b603c0 Compare August 15, 2018 00:23
Copy link
Copy Markdown
Contributor

@yangminzhu yangminzhu left a comment

Choose a reason for hiding this comment

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

I recommend to do #1920 right in this PR.
The code and logic in ProcessJwtPayload() is already complex and seems quite hack to me. It's better to avoid making it more complex and the claims_string_list seems a very specific solution.

@lei-tang lei-tang force-pushed the update_group_output branch from dc4e421 to 80fbc16 Compare August 15, 2018 04:55
@lei-tang lei-tang force-pushed the update_group_output branch from ec5ae71 to 7434c90 Compare August 16, 2018 02:07
if (field.second.list_value().values_size() > 0) {
// Only uses the first item in the list as string
(*entries)[field.first] =
field.second.list_value().values().Get(0).string_value();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We need to make them comma separated strings. If this is not fixed now, please leave a TODO here.

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.

"some-other-string-claims": "some-claims-kept"
},
raw_claims: "\n {\n \"iss\": \"issuer@foo.com\",\n \"sub\": \"sub@foo.com\",\n \"aud\": \"aud1\",\n \"non-string-will-be-ignored\": 1512754205,\n \"some-other-string-claims\": \"some-claims-kept\"\n }\n "
raw_claims: "\n {\n \"iss\": \"issuer@foo.com\",\n \"sub\": \"sub@foo.com\",\n \"aud\": \"aud1\",\n \"non-string-will-be-ignored\": 1512754205,\n \"some-other-string-claims\": \"some-claims-kept\"\n }\n ",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In the test case, you may want to have claims that have more than one string entries.

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: added a claim of two string entries.

void ExtractJwtGroups(
const Envoy::Json::Object& obj,
void ExtractStringList(
const std::string key, const Envoy::Json::Object& obj,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

const std::string&

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.

payload->mutable_claims();

// Extract claims
// Extract claims as strings
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Since you are doing it for all claims, do you want to replace the logic here with what you had for ExtractStringList()?

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.

ExtractStringList() extracts a string list whereas the code here only extracts a string. So the logic for ExtractStringList() is not applied here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I mean, you can apply the same logic, first try as a string, then string list, here. With the current way, you actually do it twice, first cast all claims to string in this function, then cast them to string list in ExtractStringList function.

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.

Before ExtractStringList(key, *json_obj, *claims, list) is called, claims must have been extracted. Hence the separation of two loops (one at line 93, the other at line 123).

@lei-tang
Copy link
Copy Markdown
Contributor Author

/retest

const std::string& key, const Envoy::Json::Object& obj,
const ::google::protobuf::Map< ::std::string, ::std::string>& claims,
istio::authn::JwtPayload* payload) {
const std::string& key = kJwtGroupsKey;
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.

Do you still need kJwtGroupsKey in line 29?

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.

No, I have removed it. Thanks.

@lei-tang
Copy link
Copy Markdown
Contributor Author

This PR is replaced by #1925, which use protobuf::Struct for storing claims.

@istio-testing istio-testing added the needs-rebase Indicates a PR needs to be rebased before being merged label Aug 30, 2018
@istio-testing
Copy link
Copy Markdown
Collaborator

@lei-tang: PR needs rebase.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@lei-tang
Copy link
Copy Markdown
Contributor Author

This PR is closed as it has been replaced by #1925.

@lei-tang lei-tang closed this Aug 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla: yes Set by the Google CLA bot to indicate the author of a PR has signed the Google CLA. needs-rebase Indicates a PR needs to be rebased before being merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants