Closed xiaomi-tc closed 6 years ago
I'm sorry but I don't understand what you are asking. Can you clarify what feature you want and/or what changes are required to what is currently implemented?
Translation: ngx_http_auth_request_module does a lookaside HTTP request, result of which (2xx or 403) decides whether or not the request should be processed / proxied.
Yes, async request processing is possible in a filter via the AsyncClient mechanism. We have 2 auth filters at Lyft that work this way. There are other examples in the public code base. Beyond that, I'm not sure if this is an ask for a particular auth protocol being implemented.
We also use the ngx_http_auth_request_module mechanism of nginx. In case of a positive auth result (2xx), we inject custom HTTP headers (e.g. user id etc.) for the service to work with. Is custom header injection based on the result of a subrequest possible in envoy? Any chance such a generic "auth subrequest" filter could be one of the standard filters of envoy?
+1 for this.
it's nice to have a generic auth filter
@markschmid
you can take a look at the istio project's mixer filter, from their istio/proxy project.
@jwfang @markschmid if there is a generic way to do an auth filter that is useful to folks, I'm totally open to it. Feel free to drop a proposed design here. We have multiple auth filters internally at Lyft, but they contain Lyft specific functionality so it's not reasonable to open source them. I will reopen this issue to track seeing if there is a way to do a generic filter.
Thanks!
OK so I propose the following generic authentication mechanism for Envoy, implemented as a filter. It would basically mimic the "client authorization based on the result of a subrequest" mechanism of the nginx ngx_http_auth_request_module module [1], which is, in a nutshell:
Authenticate each request with an external auth service. To perform authentication, an HTTP subrequest is sent to an external auth service where the subrequest is verified. If the subrequest returns a 2xx response code, access is allowed, if it returns 401 or 403, access is denied. This generic way of authentication would allow for implementing various authentication schemes.
This is the proposed mechanism step by step:
Possible filter configuration
{
"type": "decoder", // unsure, maybe "both"?
"name": "auth_request",
"config": {
"inject_headers": ["X-Authrequest-Userid", "X-Authrequest-Foo", "X-Authrequest-Bar", ...], // headers received from the auth service response that need to be injected into the verified request
"timeout": "...", // maybe a configurable timeout in ms for the auth service response (?)
}
}
Notes:
Additional reading about the nginx module in question can be found in [2] and finally, I think, the repository containing the source of that nginx module is found in [3] I hope this makes at least some sense. As I've only just started looking into envoy a few days ago, I might have missed existing options/concepts etc.
In any case, I'd be happy to further clarify or help in any other way for getting such a filter in envoy!
[1] http://nginx.org/en/docs/http/ngx_http_auth_request_module.html [2] https://www.nginx.com/resources/admin-guide/restricting-access-auth-request/ [3] https://github.com/PiotrSikora/ngx_http_auth_request_module
In general this seems reasonable to me (there are some details to sort out in terms of what should be configurable, etc.). If someone wants to sign up to implementing the filter let me know. It's not difficult and can be modeled after existing filters.
@markschmid good job
@mattklein123 while we are at it, should we be a little more ambitious about these ? in my understanding, envoy should shift system level functions from user service as much as possible, authorization is certainly one of them.
i looked at https://github.com/istio/proxy a while back ago, their mixer/transcoding filters are really interesting. transcoding soon will be in core envoy ( thanks ), so let's concentrate on mixer.
the mixer filter has three hook, Check/Quota/Report, which are called at different stage of quest processing. here is its api definitions: https://github.com/istio/api/blob/master/mixer/v1/service.proto . it does more than authorization and has a more generic hook points.
i wonder if there is any chance we can collaborate on this generic structure ?
cc @kyessenov @htuch if you are interested.
If you want a generic out-of-process auth validation, then I suggest using mixer filter. We have already modified envoy to insert a precondition check over gRPC to a golang "Mixer" server that further dispatches it to a set of plugins. There are details to be worked out regarding caching and TTLs that would need to be solved in your architecture as well.
I've mentioned this elsewhere but medium/long term I would like to move mixer filter into envoy repo and the API into envoy-api repo. Can continue to discuss with @kyessenov and @louiscryan.
I would suggest not polluting this issue since I think that some people would use a basic HTTP auth filter also.
Looks like Ambassador already has this. Maybe there's some code there you can use as a base. Specifically this.
Indeed, thanks for the info! Ambassador seems to be written in Python though. If only I knew C++, I'd implement that filter right away ... :)
@markschmid I've just added a link to the c++ filter. Here it is again.
@boosh Great, didn't see that one, thanks!
@markschmid Ambassador's front end is indeed written in Python, but authentication is mediated by an Envoy filter which is (of course) written in C++. @mattklein123, happy to chat with you about what's needed to get that filter folded in to the Envoy core -- it's pretty simple.
@kflynn as long as it is generally useful, has docs, and tests, just do a PR :)
@mattklein123 That's what I was hoping to hear. ;) OK, should be able to do that next week.
Just came across this thread.
We are evaluating between nginx & envoy for transforming HTTP/1.x REST calls to gRPC servers on the backend with support for external auth mechanisms such as Okta. ngnix doesn't support gRPC and auth support in envoy is in the works.
Any further insights on the availability of this feature?
There's an open PR that I need to get tests written for, but it works. If you're interested, I can get you information about how to test with it.
Definitely. Will help with our eval.
OK — I’ll make sure the PR is up to date and send you notes over the weekend. :)
@songole I lied -- I haven't created the PR yet. It's currently committed as https://github.com/datawire/envoy/tree/flynn/feature/extauth; you can grab a built Docker image from DockerHub as dwflynn/ambassador-envoy:201710090214
.
The extauth filter is an HTTP connection filter, with a config that looks like this:
{
"type": "decoder",
"name": "extauth",
"config": {
"cluster": "auth",
"timeout_ms": 5000,
"path_prefix": "authtest",
"allowed_headers": [
"x-auth-test", "x-hurkle"
]
}
}
The extauth
filter works by taking every incoming request, stripping the body, and forwarding it to the cluster
named in the extauth
filter. Only the body is dropped: the HTTP verb, path, and headers are all left untouched, except that if a path_prefix
is specified in the filter config, it's prepended to the path when forwarding it.
If the auth service responds with an HTTP 200, the request is considered authenticated, and processing continues. If any headers listed in allowed_headers
are supplied in the response from the auth service, they're copied into the request in flight.
If the auth service responds with anything other than 200 - note that this includes all the other 2YZ responses - the request fails, and the response from the auth service is handed back as the response to the original request.
That's all there is to it! Yell if you need more information, and we'll get this turned into a proper PR shortly.
Thank you. I will check it out.
Thanks @kflynn , I will also test it in the next few days.
I've started getting my env ready for the testing. Currently stuck somewhere in-between:
How would I configure envoy to apply this filter to all paths e.g. /api/*
with the exception of e.g. /api/login
?
I've tried with two distinct http_connection_manager
filters in my listener for port 80, but somehow envoy crashes.
I know it's not directly related with the issue but merely general envoy knowledge. Any help greatly appreciated.
@markschmid The way we would do that is to configure the extauth
filter to use an external auth service that simply returned 200 for /api/login
, but did an actual auth check for other things under /api
. Part of the point of the extauth
filter is to have a very simple interface on the Envoy side (the external part might need arbitrarily-complex business logic, after all).
@kflynn Great, thanks! I'm having an external auth service in place already. I'm gonna implement the path based distinction there now.
@kflynn Testing done, everything works as expected, awesome! My goal was to replace nginx with envoy for that specific extauth
use case and I was now able to do exactly that.
Besides the extauth
workflow per se, I've also positively tested path_prefix
and allowed_headers
. Very happy, please let me know if/how I can assist further in order to get a PR asap.
Is there any plan on incorporating this into the master branch... it is a very common use case. I would prefer not to have my own customized version of envoy, but instead have this feature in the base code. If you need additional resources for this PR I would also be glad to help.
@markschmid, @tbird321, totally agreed about getting this into the base product! Here's the issue: we need to write tests for this functionality to get the PR done, and I simply haven't had bandwidth for that. ☹️ That's definitely something where more hands could help out -- if you have any interest, drop me a line at flynn@datawire.io!
Just to keep everyone in the loop: yup, still moving here. I'm currently doing a bit of cleanup to help out the folks who've so graciously offered to help with tests (thanks!), and Datawire has a guy starting in early November who'll be able to put a lot more cycles on this issue. Onward!
Hey @kflynn -- any update on this? Sorry to bother :-P
Hi @kflynn , just wondering if there is any update here. Thanks !!!
After discussions between Envoy folks, Datawire folks, and Tigera folks, we're folding Ambassador's auth functionality into the auth filter brought in by #2417. I've opened #2828 to track that work -- thanks for the interest!
I'm going to close this in favor of https://github.com/envoyproxy/envoy/issues/2828. Please track that issue for further work on generic auth.
Just like in nginx, I can set ngx_http_auth_request_module module to implement authorization when clients connecting in with a bypass authorization server. Does envoy support this or will support? If not ,what shall I do?