Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add one/many path templating support for AuthPolicy #50365

Merged
merged 13 commits into from
Apr 20, 2024

Conversation

jaellio
Copy link
Contributor

@jaellio jaellio commented Apr 10, 2024

Please provide a description of this PR:

Updates paths and notPaths in the AuthorizationPolicy resource to support a limited set of templating based on envoy's uri templating.

#16585

Adds support for:

  • {*}
  • {**}

If a path contains {*} or {**} it will be interpreted as a uri template rather than a string match. {*} will be converted to * and {**} will be convert to ** when applied in the envoy config.

Open questions:

  1. If a path contains an invalid template (ie. {}, {*, etc) should we return an error or interpret the path as a string match?
  2. If a path contains * or ** (invalid chars in uris, but valid for paths and notPaths) and supported templates ({*} and {**}), should we return an error, interpret the path as a string match, or interpret the path as a uri template (which might result in unintended behavior since * and ** will be interpreted as uri templates)?

Todo:

  • Write integration tests
  • Update analyzer support (if applicable)
  • Add path validation

@istio-testing
Copy link
Collaborator

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@istio-testing istio-testing added the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Apr 10, 2024
@istio-policy-bot
Copy link

😊 Welcome @jaellio! This is either your first contribution to the Istio istio repo, or it's been
a while since you've been here.

You can learn more about the Istio working groups, Code of Conduct, and contribution guidelines
by referring to Contributing to Istio.

Thanks for contributing!

Courtesy of your friendly welcome wagon.

@istio-testing istio-testing added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Apr 10, 2024
@jaellio
Copy link
Contributor Author

jaellio commented Apr 10, 2024

/test all

@jaellio
Copy link
Contributor Author

jaellio commented Apr 10, 2024

/test all

@@ -399,6 +399,17 @@ func (g pathGenerator) permission(key, value string, forTCP bool) (*rbacpb.Permi
return nil, fmt.Errorf("%q is HTTP only", key)
}

// TODO(jaellio): Should we interpret the path as a PathMatcher if it is an invalid or unsupported by Istio PathTemplate?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@michaelbannister what are your initial thoughts on this? For my initial draft I didn't add any logic to disallow invalid or unsupported templating. Wanted to get this out for review ASAP.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know – is there a general philosophy that Istio applies regarding invalid config? As a user I'd rather be told early that my authorization policy is broken or will never match a path, than spend ages debugging it at runtime, so I'd be in favour of fairly strict validation and failing with a meaningful error, rather than generating a rule which won't match anything.

But would such an error get surfaced to the client through a validation webhook? I suspect it may depend on how istio's been set up…

Copy link
Member

Choose a reason for hiding this comment

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

We should block in validation, and make this an error probably

Copy link
Contributor

Choose a reason for hiding this comment

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

The hard part about error is that previously allowed policies could now be blocked. That may be acceptable though due to a low likelihood?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with Keith, I was concerned about disallowing previously allowed paths/policies. However, those paths might technically have been invalid so this might be an acceptable regression.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like validation was pushed up @jaellio?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added basic validation to ensure that if a path contains a support path template ({*} or {**}) it must also not contain * or ** or any named variable ({path}, {path=*}, or {path=**}).

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know – is there a general philosophy that Istio applies regarding invalid config? As a user I'd rather be told early that my authorization policy is broken or will never match a path, than spend ages debugging it at runtime, so I'd be in favour of fairly strict validation and failing with a meaningful error, rather than generating a rule which won't match anything.

But would such an error get surfaced to the client through a validation webhook? I suspect it may depend on how istio's been set up…

Agree - invalid should be reflected in resource status at least. As we move to CEL validation - not sure if all validations will be possible in CEL and it may be best to use status consistently.

Since this is a very envoy-specific feature - may be worth adopting the same doc and validations that envoy makes. And to confirm - is the syntax in this PR identical to the syntax used by Envoy, or did we make any subtle changes ?

@jaellio jaellio added the do-not-merge/hold Block automatic merging of a PR. label Apr 11, 2024
@jaellio
Copy link
Contributor Author

jaellio commented Apr 11, 2024

Marking as ready for review. Would appreciate feedback on the general approach. Hold on merging until I have added integration tests.

@jaellio jaellio marked this pull request as ready for review April 11, 2024 19:37
@jaellio jaellio requested a review from a team as a code owner April 11, 2024 19:37
@istio-testing istio-testing removed the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Apr 11, 2024
// Ex: "/foo/{*" is not a valid PathTemplate.
// Ex: "/foo/{bar}" is an unsupported PathTemplate.
//
// Should we disallow the use of `*` and `**` in the path if it is a PathTemplate (the path contains `{*}` or `{**}`, and `*` or `**`)?
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be inclined towards disallowing it. I think the chances of someone trying to match a path that genuinely has a * in it, and using PathTemplate matchers as well, are vanishingly small, and if they do exist they will raise a feature request to have the validation relaxed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@michaelbannister added logic to disallow the use of * and ** with path templating. Did not add the logic to check for invalid path templates (i.e. /foo/{*).

Copy link
Member

@howardjohn howardjohn left a comment

Choose a reason for hiding this comment

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

Overall looks good. I think we need validation (pkg/config/validation/validation.go) and integration tests

@@ -399,6 +399,17 @@ func (g pathGenerator) permission(key, value string, forTCP bool) (*rbacpb.Permi
return nil, fmt.Errorf("%q is HTTP only", key)
}

// TODO(jaellio): Should we interpret the path as a PathMatcher if it is an invalid or unsupported by Istio PathTemplate?
Copy link
Member

Choose a reason for hiding this comment

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

We should block in validation, and make this an error probably

@keithmattix
Copy link
Contributor

/test integ-basic-arm64_istio

@jaellio jaellio requested a review from a team as a code owner April 16, 2024 23:53
@jaellio
Copy link
Contributor Author

jaellio commented Apr 16, 2024

/test unit-tests-arm64

@keithmattix keithmattix added this to the 1.22 milestone Apr 17, 2024
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
a to b requests
- Adds a name to typed extension config for uri template

Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Added additional path template validation.

Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
multiple matches

Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Copy link
Contributor

@keithmattix keithmattix left a comment

Choose a reason for hiding this comment

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

LGTM aside from some nits

pkg/config/security/security.go Outdated Show resolved Hide resolved
releasenotes/notes/16585.yaml Outdated Show resolved Hide resolved
pkg/config/security/security_test.go Outdated Show resolved Hide resolved
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
},
// Test matches for `/store/{**}/cart`
{
path: "/store//cart",
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep; we should update that page or the docs for this field/feature with a warning

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@howardjohn Created a PR to clarify behavior of MERG_SLASHES with {**} https://github.com/istio/istio.io/pull/14954/files

rules:
- to:
- operation:
paths: ["/allow/admin/{**}", "/foo/{*}/bar/{**}.txt", "/store/{**}/cart"]
Copy link
Member

Choose a reason for hiding this comment

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

can we test an inline {*}? like /abc{*}efg/?

Copy link
Member

Choose a reason for hiding this comment

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

Also do we even want to support these inline ones? or just whole segments?

Copy link
Contributor

Choose a reason for hiding this comment

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

I thought envoy only allows ** as the last component ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It has to be the last operator, not the last component of the path.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add a test with url-encoded *, {, etc ?

@costinm
Copy link
Contributor

costinm commented Apr 19, 2024 via email

template it cannot have the following chars outside of a supported
template: {, }, and *.

Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
@istio-testing istio-testing added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Apr 19, 2024
Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
Copy link
Member

@howardjohn howardjohn left a comment

Choose a reason for hiding this comment

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

LGTM, just one small validation improvement I think we can use and a question

func CheckValidPathTemplate(key string, paths []string) error {
for _, path := range paths {
// If path does not contain any path templates, skip the check.
if !ContainsPathTemplate(path) {
Copy link
Member

Choose a reason for hiding this comment

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

I think we want to remove this if now, so we would reject something like /foo/{name}/bar.

Though we will need to improve the Contains(*) check since that is valid for !ContainsPathTemplate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated

template operators in path.

Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
@jaellio jaellio removed the do-not-merge/hold Block automatic merging of a PR. label Apr 20, 2024
@istio-testing istio-testing merged commit 6f0f913 into istio:master Apr 20, 2024
28 checks passed
jaellio added a commit to jaellio/istio.io that referenced this pull request Apr 24, 2024
Follow up to istio/istio#50365 (comment)

Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
istio-testing pushed a commit to istio/istio.io that referenced this pull request Apr 24, 2024
Follow up to istio/istio#50365 (comment)

Signed-off-by: Jackie Elliott <jaellio@microsoft.com>
@@ -100,6 +105,36 @@ func CheckEmptyValues(key string, values []string) error {
return nil
}

func CheckValidPathTemplate(key string, paths []string) error {
Copy link
Member

Choose a reason for hiding this comment

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

Moving this into pilot/pkg/security/authz/matcher/template.go will look more cohesive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants