-
Notifications
You must be signed in to change notification settings - Fork 681
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
External auth background and goals. #2459
Comments
Basic Authentication API ProposalAn administrator should be able to define users for authentication using common htpasswd format, which is also used in other reverse proxies such as NGINX. apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: name-example-foo
namespace: default
spec:
virtualhost:
fqdn: foo1.bar.com
routes:
- services:
- name: s1
port: 80
auth:
basic:
- htpasswd: admin:$2y$10$0GIc9.rhJd8U7UjG9yq4VObl.QxfhmcN1Z7ZI7Hn4T2mioa.2lkhi
- htpasswd: alice:$2y$10$6Xnm2tVXLKDbh2iK4LmaMu9XmI8EyN9F8D1hRFU5guAGxIyVZj5M2
- htpasswd: bob:$2y$10$Trw2zst7Vb8RW2.pjvkSk.8VHBrX/K9tTzntV7ZaYS4euX0E2BBfS In that particular example, the passsword is BCrypt-hashed, which is quite secure and makes it fine for it to be visible in plain view. If I'm not mistaken, htpasswd format can be also be:
ConfigMap / Secret ReferenceBut because Contour is Cloud Native, we should also support Kubernetes-style configmap / secret reference (for the extra paranoid): apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: name-example-foo
namespace: default
spec:
virtualhost:
fqdn: foo1.bar.com
routes:
- services:
- name: s1
port: 80
auth:
basic:
- secretKeyRef:
name: myhtpasswd-secret
key: htpasswd
- configMapKeyRef:
name: myhtpasswd-configmap
key: htpasswd This API is similar to the API used by Kubernetes for defining environment variable using Secret or ConfigMap value:
The value inside the ConfigMap or Secret should be a newline-delimited value of htpasswd file:
All these techniques should be similar to the technique used by Apache / NGINX for creating Basic authentication users... ... while maintaining familiarity for general Kubernetes users and should be good enough for 99% use cases. |
As for the OpenID Connect external authentication feature, I would like to request a feature where the administrator can define what roles can access a particular service. Roles and Groups claims are quite common in OpenID Connect products such as:
For example: An HTTPProxy is configured to only allow "Manager" role to access the page. Bob has these roles: "IT", "Manager" When the user has not logged in, the HTTPProxy will redirect the user to the login page of the Identity Provider. When Bob logged in, he will receive "roles" claims (if the scope is requested) After Bob has logged in, Contour will check Bob roles against roles allowed, which is the "Manager" role. Since Bob has that role, he is allowed to access the page. On the other hand, Alice has no roles at all. When Alice has logged in and redirected back to the application, she will be kicked to a 403 Forbidden page. This feature is similar to feature offered by authentication reverse proxies such as Keycloak Gatekeeper: https://www.keycloak.org/docs/latest/securing_apps/#group-claims Example OpenID Connect in HTTPProxyapiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
name: name-example-foo
namespace: default
spec:
virtualhost:
fqdn: foo1.bar.com
routes:
- services:
- name: s1
port: 80
auth:
openid:
- authority: https://oidc.company.com
- client_id: myapp
- response_type: code # Contour should get claims from UserInfo endpoint!
- pkce: 'true' # when using PKCE, no client secret is required
- scopes:
- openid
- profile
- email
- roles
- required:
- roles: # can be other custom claims which needs to be checked such as "groups"
- Manager
|
@ryanelian Thanks for your detailed comments! I think that there's enough substance in each of those to generate their own discussions, so I think that it is best to file new issues for basic auth and OIDC configuration (including the information in the comments above). I want to be sure that we don't lose the focus on those features in this discussion. Thanks :) |
This updates projectcontour#432. This updates projectcontour#2459. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. This updates projectcontour#2325. Signed-off-by: James Peach <jpeach@vmware.com>
See https://github.com/projectcontour/contour-authserver |
This updates projectcontour#432. This updates projectcontour#2459. This updates projectcontour#2325. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. This updates projectcontour#2325. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. This updates projectcontour#2325. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. This updates projectcontour#2325. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. This updates projectcontour#2325. Signed-off-by: James Peach <jpeach@vmware.com>
This updates projectcontour#432. This updates projectcontour#2459. This updates projectcontour#2325. Signed-off-by: James Peach <jpeach@vmware.com>
This issue has served its purpose. Thanks for all the feedback. |
This issue captures background context and research for adding Contour support for service authentication. It's not the final design, though preliminary design directions are included. The goal of this issue is to capture feedback about the direction.
Goals
Since Contour targets soft multi-tenancy for proxies, we should expect
that different services have different authentication needs. This means
that Contour must support multiple authentication servers.
The Contour external authentication mechanism should be general enough to
support multiple kinds of authentication. At minimum, we should support
HTTP basic auth and OAuth2 (via OIDC).
For some kinds of authentication, the authentication server can run in
the same cluster. However, running an auth server has a certain amount
of overhead cost and may have specific security operational requirements,
so Contour should support using an out-of-cluster service as an external
authentication server.
Writing a external authentication server can be non-trivial. Contour
should facilitate users who wish to use existing authentication
servers. Contour should not invent a bespoke protocol to attach
authentication servers.
Since Contour will not invent its own server attachment protocol,
exposing the Envoy protocol makes the most sense. Both the GRPC and
HTTP attachment protocols should be exposed since (1) other Envoy-based
Ingress controllers expose both and (2) there are authentication servers
that depend on both protocols.
Contour should always use TLS to send request to authentication
servers. Mutual TLS is not required, though it seems reasonable
for sites to want that capability.
In API that describes how to bind an external authentication service,
Contour should leverage the existing configuration stanzas and concepts
in HTTPProxy as much as possible (e.g. Service, HeadersPolicy).
Many applications have internal HTTP paths that don't require
authentication (e.g. static assets). There needs to be a way to disable
the authentication requirement for specific paths within a virtual host.
Non-Goals
We should not support any non-external authentication in Contour since
this would divert resources (development, testing and documentation)
from the external server path, which is the primary use case. This means
that the Contour service itself should not satisfy authentication requests
or load plugins that do.
Contour does not need to support attaching authentication servers over
HTTP. It can assume HTTPS.
Since the IngressRoute API is deprecated, there is no need to ever
implement external authentication there. The situation for Ingress is
less clear. Ingress is a supported API, but is also less expressive in
some ways than HTTPProxy. For now, Ingress won't be supported for
external auth, but we should be open to revisiting the isssue.
Authorization request flow
Authorizing requests with an external server involves a number of
collaborating parties, so it can be helpful so understand how requests
flow through the various services.
an OIDC server, a server that can do LDAP authentication, or HTTP Basic
auth. It could be implemented in the same process as the ExtAuth service.
Verifying an authorized request
This flow describes what happens if the client already has already
authenticated and obtained some sort of authorization token.
Signing in to an service
This flow describes what happens if the client doesn't already already
have any authentication information and needs to sign in to some
authentication service.
Note that in the sign in flow, the ExtAuth server may need to generate
a 302 redirection to send the client back to the authentication provider
to obtain the proper authorization tokens. Once this happens, the client
has to resend the original request and enters the verification flow above.
Envoy ext_authz semantics
The Envoy ext_authz filter is a HTTP filter that is specified as a
field on the HTTP Connection Manager. This forces some limitations on
how authentication can be configured. Notably, there can be exactly 1
external auth server for a HTTP ConnectionManager.
For the HTTP (cleartext on port 80) listener, Contour configures a single
HTTP Connection Manager which contains a VirtualHost field for each
domain. Since HTTP filters are attached to the Connection Manager, there
can only be one ext_authz server filter configured. This means that all
the domains exposed on this listener must have the same ext_authz server.
For the HTTPS (TLS on port 443) listener, Contour constructs a
configuration tree with an extra FilterChainMatch level to match on the
TLS SNI server name. The filters associated with this match include a
HTTP Connection Manager which references a unique route configuration
for the matching hostname. This implements a strong binding between the
SNI server name and available routes, but as a side-effect, the unique
Connection Manager allows a separate ext_authz filter to be naturally
specified for each SNI server name.
These behaviours allow us to enumerate the following
configuration possibilities:
must have the same ext_authz server.
It is possible to raise the limitations of the Envoy ext_authz
filter. One way to do this is to write an extauth server that ships
with Contour. This extauth server would be configured with a policy for
how to choose a next-hop external auth server that can be a lot more
flexible than the Envoy configuration (e.g. an arbitrary virtual host,
an HTTP path or header). From our goals, we wish to be able to support
existing authentication server integrations, so this extauth server
would then proxy to the selected external auth server using the same
wire protocols that the Envoy ext_authz filter uses.
In this model, it is necessary for Contour to implement and ship the
extauth proxy, because its semantics will be exposed as part of the
Contour API. That is, it is not possible for a third party to implement
this approach. Obviously, an alternative to this approach would be to
directly address the configuration limitation in Envoy.
Design Proposal
At a high level, this design proposes a new CRD to represent an external
authentication server. This CRD can be referenced by HTTP services.
This design proposes that
that are bound to a SNI server name
The rationale for this is that practically all HTTP authentication
mechanisms require TLS since they often carry private informations (bearer
tokens, API keys, etc). Extending external auth to other cases leads to
confusing and inexplicable limitations, and removing those limitations
requires a lot more engineering work. Starting with a HTTPS-only would
not preclude extending support later if necessary.
ExternalAuth CRD
TBD
The ExternalAuth CRD need to contain enough information to configure and
Envoy cluster for the auth server, as well as relevant fields from the
ExtAuthz
protobuf. We should try to re-use concepts or structures fromHTTPProxy (maybe the Service struct).
Using a separate CRD allows Contour to update status on it, which can
facilitate #2352.
HTTPProxy Changes
TBD
On the root HTTPProxy, specify which ext_authz service to attach to
with a reference to a ExternalAuth document. Allow
ExtAuthzPerRoute
context extension key/value pairs here.
On the HTTPProxy route (probably?), add a boolean field to toggle
disabling authentication.
Think through whether it makes sense to default authentication to being
disabled on the root HTTPProxy. Could be more convenient for some cases,
but adds a lot of complexity.
Ingress Changes
TBD
Supporting authentication for Ingress is similar to supporting it
in HTTPProxy. The ExternalAuth CRD still represents an external
authentication service, but rather than referencing it with document
fields as HTTPProxy does, Ingress references it with annotations.
Implementation Survey
Traefik
https://docs.traefik.io/middlewares/forwardauth/
https://docs.traefik.io/v1.7/configuration/backends/kubernetes/#authentication
Forwards whole request to auth server. If auth responds 200,
releases request, otherwise returns auth server response.
Specific TLS config for auth server.
Auth server config is represented in a custom "middleware" CRD.
Ingress implementation lets you target different auth servers per
ingress.
Auth servers:
Ambassador
https://www.getambassador.io/docs/latest/topics/running/services/auth-service/
https://www.getambassador.io/docs/latest/topics/running/services/ext_authz/
https://www.getambassador.io/docs/latest/topics/using/filters/
Envoy filter.
For HTTP auth servers, the inbound request is a combination of
the upstream client request and the auth request
For HTTP auth servers, the response is
For GRPC, auth servers must implement Envoy ext_authz protocol directly.
Ambassador has a semi-generic way to express filters using the Filter
and FilterPolicy CRDs.
The AuthService CRD is meant to configure a single global auth service,
but Filter is supposed to be per host or even per path. I was not able
to get Filters to make any changes to the Envoy config. Ambassador
seems to always configure a single built-in authz cluster pointing to
itself. That might indicate that it has an intermediate auth service,
but I wasn't able to prove that or find the code in open source.
OAuth2 Filter is a OIDC client. Substantial configuration
surface. Lots of work to support web applications.
JWT Filter validates JWT tokens. More substantial configuration
surface. Does request header and error response body templating.
Kong
https://docs.konghq.com/hub/#authentication
Gloo
https://docs.solo.io/gloo/latest/guides/security/auth/
https://docs.solo.io/gloo/latest/guides/security/auth/custom_auth/
Custom external auth server is defined globally in Settings
CRD, then vhosts opt in with their own CRDs.
There can only be one custom external auth server, but multiple
instances of the builtin auth types.
Direct support for envoy GRPC.
Auth servers can co-locate in same pod and auth over unix
domain sockets. Not clear whether this includes custom auth
servers (possibly not).
HTTP custom auth server protocol is lightly described, but
probably the same as Ambassador (i.e. envoy HTTP mechanism).
NGINX
http://nginx.org/en/docs/http/ngx_http_auth_request_module.html
respond 2xx to allow the original request, or 401/403 only
to deny.
subrequest to the main response.
Auth servers:
HAProxy
Authentication types
Auth servers to Support
pomerium
oath2-proxy
OPA
DEX
https://github.com/travisghansen/external-auth-server
https://github.com/ajmyyra/ambassador-auth-oidc
https://github.com/open-policy-agent/opa-istio-plugin (GRPC)
Related Contour Issues
#68 Ingress auth labels
#432 Main auth issue
#433 TLS client auth
#1922 Forward auth (traefik style)
#748 JWT auth (closed)
#986 Single sign on (closed)
#1014 design proposal
#2325 Contour checking for infrastructure clusters
The text was updated successfully, but these errors were encountered: