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

feat: auth-req caching #4278

Merged
merged 1 commit into from
Jul 17, 2019
Merged

Conversation

moolen
Copy link
Contributor

@moolen moolen commented Jul 7, 2019

What this PR does / why we need it:
This PR adds a way to configure the proxy_cache_* (docs) directive for external authentication.

It adds these annotations, as proposed by @Stono in #2862 :

  • nginx.ingress.kubernetes.io/auth-cache-key
  • nginx.ingress.kubernetes.io/auth-cache-duration

The first one sets the proxy_cache_key (e.g. $uri$cookie__auth_proxy) and enables the feature. The latter sets the cache duration (defaults to 10m)

Note:
The user-defined cache_key may contain sensitive information (e.g. Authorization header). That's why we want to store only a hash of that key, not the key itself on disk.

fixes #2862

@k8s-ci-robot
Copy link
Contributor

Welcome @moolen!

It looks like this is your first PR to kubernetes/ingress-nginx 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes/ingress-nginx has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added the do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. label Jul 7, 2019
@k8s-ci-robot
Copy link
Contributor

Hi @moolen. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 7, 2019
@moolen moolen force-pushed the feat/auth-req-cache branch from 4a495bb to 255ece5 Compare July 7, 2019 17:00
@k8s-ci-robot k8s-ci-robot removed the do-not-merge/invalid-commit-message Indicates that a PR should not merge because it has an invalid commit message. label Jul 7, 2019
@aledbf
Copy link
Member

aledbf commented Jul 7, 2019

@moolen please add e2e tests

@aledbf
Copy link
Member

aledbf commented Jul 7, 2019

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jul 7, 2019
@aledbf
Copy link
Member

aledbf commented Jul 7, 2019

/hold

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 7, 2019
@codecov-io
Copy link

codecov-io commented Jul 7, 2019

Codecov Report

Merging #4278 into master will increase coverage by 0.16%.
The diff coverage is 82.75%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4278      +/-   ##
==========================================
+ Coverage    58.3%   58.47%   +0.16%     
==========================================
  Files          87       87              
  Lines        6478     6528      +50     
==========================================
+ Hits         3777     3817      +40     
- Misses       2274     2282       +8     
- Partials      427      429       +2
Impacted Files Coverage Δ
internal/ingress/controller/config/config.go 98.57% <100%> (ø) ⬆️
internal/ingress/controller/template/configmap.go 76.63% <66.66%> (-0.52%) ⬇️
internal/ingress/annotations/authreq/main.go 70.83% <85.41%> (+6.27%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 84af99b...23504db. Read the comment docs.

@moolen
Copy link
Contributor Author

moolen commented Jul 7, 2019

/retest

@aledbf
Copy link
Member

aledbf commented Jul 8, 2019

@moolen two comments:

  • I think auth-cache-key should prepend the nginx server_name variable
  • auth-cache-duration could be a list to allow different durations (not sure 10 minutes is ok for 401)

@moolen
Copy link
Contributor Author

moolen commented Jul 9, 2019

@aledbf Thanks for your feedback!

I think auth-cache-key should prepend the nginx server_name variable

good catch, that makes sense!

auth-cache-duration could be a list to allow different durations

You're right, it should be a list to allow configuration of multiple durations.

But while i think about that i'm not really sure if we really need this annotation at all. The user could set proxy_cache_valid using the auth-snippet annotation anyway. It would be semantically more precise to use a specific annotation, but adds more complexity to the codebase.

I'll implement it as a list for now. If you like using auth-snippet better i can remove it again (not a big deal).

not sure 10 minutes is ok for 401

It depends on the user's context i would say. For my use-case ($corp internal web-apps) i use Authorization header as cache_key and i want every auth-response (!= 5xx) to be cached.

I'd propose to lower the default value to 5m. The user can override the value using the duration annotation. What do you think?

@moolen moolen force-pushed the feat/auth-req-cache branch from b23ec18 to d4c3553 Compare July 9, 2019 11:29
@moolen
Copy link
Contributor Author

moolen commented Jul 9, 2019

i did touch this; The last runs indicate this test is flaky; let's retest and maybe dig deeper.
/test pull-ingress-nginx-test

@aledbf
Copy link
Member

aledbf commented Jul 9, 2019

I'll implement it as a list for now.

👍

I'd propose to lower the default value to 5m

👍

Also, please squash the commits

@moolen moolen force-pushed the feat/auth-req-cache branch from d4c3553 to 1262b85 Compare July 9, 2019 12:16
@aledbf aledbf removed the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Jul 10, 2019
@aledbf
Copy link
Member

aledbf commented Jul 10, 2019

/approve

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 10, 2019
@ElvinEfendi
Copy link
Member

I think auth-cache-key should prepend the nginx server_name variable

should it include location identifier too? since one can configure different external authentication for different locations in the same server.

@moolen moolen force-pushed the feat/auth-req-cache branch from 1262b85 to 67647c2 Compare July 11, 2019 20:45
@moolen
Copy link
Contributor Author

moolen commented Jul 11, 2019

again, that flaky test :/
/test pull-ingress-nginx-test

@aledbf
Copy link
Member

aledbf commented Jul 11, 2019

again, that flaky test :/

Apologies for that :(
We are removing the static SSL feature in this release. With that, this will not be an issue anymore.

@moolen
Copy link
Contributor Author

moolen commented Jul 15, 2019

@ElvinEfendi i added the location identifier and squashed the commits.

}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Is there any way to not duplicate this logic? @aledbf do we have means to share code between here and annotation? like a utils package or something

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 centralized the "parsing" logic for now in d6b9014. Let me know if you want it in a utils package. I digged into this topic - it seems there's a bunch of code that is copy/pasted with slight adaptions (e.g. returning vs. logging an error).

@ElvinEfendi
Copy link
Member

Can you add a test to assert that the cache key includes location and server identifiers? For location the test would like like this

  1. Sign in on i.e /foo
  2. Kill the external auth server
  3. Assert that /foo still works
  4. Assert that /bar does not work

@k8s-ci-robot k8s-ci-robot 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 Jul 16, 2019
@moolen
Copy link
Contributor Author

moolen commented Jul 16, 2019

Thanks for your feedback!

I added tests to verify the scope of the cache key (location/server) and addressed the other comments too.
I'm not sure about introducing a utils package. I centralized the logic for now. please let me know if that works for you!

@moolen moolen force-pushed the feat/auth-req-cache branch from 9071d9e to 836a5fd Compare July 16, 2019 21:37
@moolen
Copy link
Contributor Author

moolen commented Jul 16, 2019

/test pull-ingress-nginx-e2e-1-12

@@ -378,6 +380,10 @@ Additionally it is possible to set:
`<Response_Header_1, ..., Response_Header_n>` to specify headers to pass to backend once authentication request completes.
* `nginx.ingress.kubernetes.io/auth-request-redirect`:
`<Request_Redirect_URL>` to specify the X-Auth-Request-Redirect header value.
* `nginx.ingress.kubernetes.io/auth-cache-key`:
`<Cache_Key>` this enables caching for auth requests. specify a lookup key for auth responses. e.g. `$remote_user$http_authorization`.
Copy link
Member

Choose a reason for hiding this comment

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

Should we make a note that this will be hashed and encoded?

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 think the implementation details are not important - the mechanics are tho!

I appended this:

Each server and location has it's own keyspace. Hence a cached response is only valid on a per-server and per-location basis

@ElvinEfendi
Copy link
Member

@moolen this is looking great! Once you squash the commits we can merge this.

add a way to configure the `proxy_cache_*` [1] directive for external-auth.
The user-defined cache_key may contain sensitive information
(e.g. Authorization header).
We want to store *only* a hash of that key, not the key itself on disk.

[1] http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_key

Signed-off-by: Moritz Johner <[email protected]>
@moolen moolen force-pushed the feat/auth-req-cache branch from 836a5fd to 23504db Compare July 17, 2019 16:41
@ElvinEfendi
Copy link
Member

/test pull-ingress-nginx-e2e-1-12

@ElvinEfendi
Copy link
Member

/lgtm

thanks @moolen !

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Jul 17, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: aledbf, ElvinEfendi, moolen

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

The pull request process is described here

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

@k8s-ci-robot k8s-ci-robot merged commit 589c9a2 into kubernetes:master Jul 17, 2019
@Stono
Copy link
Contributor

Stono commented Jul 18, 2019

Hey a quick one - thanks for all your effort in this everyone, finally able to rid it of my monkeypatch

@moolen moolen deleted the feat/auth-req-cache branch July 18, 2019 09:25
@vaskozl
Copy link

vaskozl commented Jan 27, 2022

Isn't this dangerous in the case where the user specified cache key ends up being an empty variable?

E.g. if the cache key is set to $cookie_foo and the upstream auth provider decides to change the auth cookie name form foo to bar, then $cookie_foo would become empty and we start caching simply on { $server.Hostname }}{{ $authPath }} which as I see it will let everyone through for the duration of the cache?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. 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.

external auth provider results in a *lot* of external auth requests
7 participants