-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Enable external Authentication (authn) and Authorization (authz) via Extensible Auth Provider. #434
Comments
Hi @petemiron, do you have any plan to implement this requirement? |
Hi @wenzheng, do you have feedback on this? Many of the ideas stem from your Pull Request, but we've tried to balance performance with the flexibility in your suggestion in these requirements. If you agree and would like to modify your PR to suit these requirements, we'd happily review it. We do think this is a great idea, but our core team doesn't have the bandwidth to implement at this point. We just wanted to make sure to capture the suggestions as a set of requirements. |
Hi @petemiron I see our colleague @firebook had commented in the previous PR#429, but yes I think it would be possible for us to modify the PR to suit the requirements, I will talk to our team and see when can we make this happen |
👍 for this... This would enable us to provide NATS as a brokered service to our apps running on Cloudfoundry. In fact I could live with a very minimal implementation as in #428. |
Hi, We would like to know what is the current status of this issue? We are going to use nats to connect >50k devices from "outer space" and not happy with updating/reloading config files. @petemiron @derekcollison It's clear that the performance and reliability are top priorities when reviewing external auth feature. But what about having user auth service internally connected to nats with system subscriptions. Have you discussed this possibility already? Are there any stop factors to implement it? The idea is to have have nats client(s) to serve as auth provider. I see it now like having additional subscriptions and/or maybe protocol message, so auth provider(s) is able to announce when ready and be registered by gnatsd. |
I believe reloading configuration files, a WIP, will solve the majority of needs here. |
@derekcollison At least for our use-case (automatic provisioning of nats subject subtrees to apps on Cloudfoundry & Kubernetes via a service-broker) it feels awkward and error prone to generate nats configs on multiple nodes and then to rely on config reloads. |
I would imagine that the process would be automated, where config files are properly generated, updated, distributed securely, and the server's signalled properly to reload the configuration. |
It's certainly doable, but something like #428 would be so much simpler and less error prone (and without timing issues - the state of the authn/authz can always authoritatively be answered by the external entity and is not "in flux" during the regeneration/reload of the config). |
I think the idea has merit, however it is not complete. For instance, when a user is removed, or permissions updated, these cases are covered by configuration reload, but are currently not accounted for in #428. The synchronization issues are the same in both cases IMO as well as error handling and exceptions. |
Removed user or updated permission could be tracked with auth TTL (should have some configured period) if not available/changed - close connection to force client to re-connect. If one don't want TTL defined because of additional traffic, there should be a possibility to receive the message from auth provider and kill connection. It could be webhook or subscription if auth provider is nats client |
The removal of SetClientAuthMethod removed any possibility of providing a custom auth backend. This patch add it back as a Option attribute, so we can wait comfortably for nats-io#434, which aims to provide more extensible external Auth.
Can you clarify on the timeline? I can only chime in, that this is much sought after. |
something like this would be great, and I imagine quite simple: |
any progress? |
We are moving forward with this through our Nkey and JWT work. Will keep everyone posted as best we can. Look for something before end of year. |
may be you have some testing code in branch? i'm realy want to check this |
You can customize permissions with NATS in operator mode using claim JWTs and private nkeys (or designate the JWT to be a bearer token). Do you own the Oauth2 domain? |
thanks for your quick answer. This may be not the best place to discuss this, but I do not own the domain. I receive on the client side an authorization token I am supposed to validate on the server side, at login time, using custom rules (validate against public key retrieved by http, and check a few fields of the token). I wonder how it could be done in the nats ecosystem. |
As far as I know the only way we support today is if you emedded the nats broker into your own code, you can then supply your own authentication logic. |
You could have a bearer token delivered to the client. Or a normal creds file as well. Will that now work? |
I saw #1149 and it is really close. IMHO there may be corner cases where a server side script for token validation may be usefull. But this PR is very close to offer Oauth2 compliant authenticaction, yes. |
as an example there is a rfc that specifies how to validate the token (RFC 7662 I think), but the people I work with (automotive industry) ask for specific way to validate the token, so the parameters exposed in the PR may not be enough for all cases. IMHO it woud be nice to have some kind of plugin or external resolver pattern for custom token validation, as not every identity provider or deployment are not exactly following the spec. I agree that in strict oauth2 cases, it should be possible to implement validation through configuration file. |
We wanted to go for nats back in 2017 but we missed this feature. |
Its on the near term roadmap. As it's such a varied topic maybe you can expand a bit on exactly how you would want to see this work? |
Thanks for that update @ripienaar We use the message bus not only for internal microservice communication, but we expose it and connect every user that is using our platform's webinterface + our thick app to the message bus, to use its full potential. This can be up to 500k users in our case. Pushing messages to a webinterface using fine graded subscribe patterns like Why recreating the complete exchange logic across a horizontally scaled infrastructure to reach certain users being connected to different endpoints, when nats does exactly this? |
@JOHN-DEV thanks, for the input sure it will be handy when we work on this. Building something like this using nats server as a library is fairly trivial - have done a NATS server that calls a external auth in under a hour, but sure its not to everyones liking to build custom server binaries. |
Exactly, using custom build binaries is not an option for us, unfortunately. |
The auth system is an already supported extension point, when calling the server from Go. |
Can you outline what that exactly means? |
Ignoring whats involved in starting a nats server in go - we have many examples in tests - you can replace the auth system entirely with your own. type MyAuth struct {
user string
pass string
}
func (a *MyAuth) Check(Check(c server.ClientAuthentication) bool {
opts := c.GetOpts()
return opts.Username == user && opts.Password == pass
} You can now set this into the run time options So this is a super simple example, but there in To note this entirely replaces the built in auth system. So the work to support external auth would be to work on this area, extend it to perhaps call external binaries or perhaps to call out over NATS in specially designated account for a service that can handle auth and so forth based on what users say they need, we're likely to start with something basic and expand over time. |
Interesting. Yup, you can: user := &server.User{
Username: "bob",
Account: "some_account_that_exists",
Permissions: &server.Permissions{
// set permissions
},
}
c.RegisterUser(user) |
Sorry, Account is a handle to the server account that you can get with |
Thanks for that, i got authentication and permissions working. It is not ideal to have a custom build but well, nothing is perfect. |
Indeed, not ideal, but maybe this gets you going and moving to whatever the final natively supported system we decide on will not be onerous. |
Wow, I note I edited your earlier comment instead of commenting new - sorry about that, anyway we got there in the end! |
Auth callouts and mapping external Authn to NATS Authz is top priority for 2.10 release. Along with the ability to reuse an existing connection. |
Hi, is there a temporary branch where we can test this before release in its current state? |
Yes, the |
NATS Authorization Callout I also need |
@bruth I think this can now be closed as 2.10 has been released |
Requirements
1.1. The external auth provider must support TLS, including specifying certificate authority.
1.2. The external auth provider should accept and check credentials (username and secret) for the gnatsd server.
1.3. The external auth provider must have a configurable timeout for DNS, TCP connect, and response. These timeouts may be tracked in a single timeout or separated.
1.4. Metrics for requests, successful, failed and at least average response time of queries to external auth provider must be available through monitoring endpoints.
1.5. If no external auth provider is configured, the must be no additional impact on CONNECT performance.
2.1 the external auth provider must check authn and return a 200 with authz data (similar to example in Create Endpoint API option for client authorization #428):
{ user: 'optional', permissions: { publish: ['foo.*'], subscribe: ['foo.*', 'bar.*'] } }
2.2. The credentials must be checked during client CONNECT.
2.3. The external auth provider may return a Time-to-Live (TTL) for authz data.
2.4. If a TTL is returned, the server should respect the TTL and re-request authn for the user on any new message sent to or received from that user after TTL expiration.
2.5. The external auth provider must provide a means for failover (eg. DNS round-robin, or multiple addresses in the configuration).
Plugin Interface Mockup
For discussion, here is a mockup of a plugin interface that passes a context around. This pushes locking responsibility into the plugin itself. It is not complete by any stretch of the imagination.
Related Issues
#428
#429
#369
The text was updated successfully, but these errors were encountered: