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
Authorization Callouts #3719
Authorization Callouts #3719
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed everything except server/auth_callout_test.go
// Check for server configured auth callouts. | ||
if opts.AuthCallout != nil { | ||
// Make sure we have a valid account and auth_users. | ||
_, err := s.lookupAccount(opts.AuthCallout.Account) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it guaranteed that lookupAccount will be fully populated, in all account resolver modes, so that this must succeed during initial parse of the config file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lookupAccount can reach out. Like SYSTEM account, if you are running in operator mode, this account should also be part of the preloads. But if it isn't we will try to fetch it. If that fails we will error.
@@ -557,6 +578,54 @@ func (s *Server) processClientOrLeafAuthentication(c *client, opts *Options) boo | |||
err error | |||
ao bool // auth override | |||
) | |||
|
|||
// Check if we have auth callouts enabled at the server level or in the bound account. | |||
defer func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a lot of security-critical work to be happening inside a deferred function. I'm worried about this being triggered after a panic. Is this something which could be put into a new intermediary function instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be a defer to be able to reference the result of authorized which is a return variable.
return | ||
} | ||
|
||
// Do it this way to fail to compile if fields are added to jwt.ClientInformation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see what would cause a compilation failure here: the other fields would just be left on their default values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assignment part. Left side, not right side.
I have a few comments / wishes to add here:
|
f38d8b9
to
e14ce48
Compare
This is visible in the account of the user and not the service, so might be considered leaking info.
Phil asked about this as well. I think starting with server logs is right approach, and we can add in events. Not opposed.
Can you give me an example of what would be helpful?
Possibly, we would need to go back into the jwt lib and add a response claim that would include the user claim such that we could trust the error response etc. So non-trivial.
Good idea. I can add that, will also require update to jwt lib.
Examples? |
I mean the ones that get sent to
fair
If a server config significantly change the authentication parameters of behavior that's definitely something you want to communicate and warn about. It stands out so there's no inadvertant mistakes or no surprises.
cool
At debug it would for sure be good to know you're calling out and when you got a response/or not/or timeout etc. It can be hard to debug this as its a bit of effect at a distance so debug info would help developers working on auth plugins. |
Should also add in cluster to server portion if we are adding tags. @ripienaar for the AuthorizationResponse, should it be code + description similar to how we evolved in JetStream? |
Don’t think it needs code - since this is not for internal use it’s user supplied code so would be hard to standardise on coded errors. Yeah cluster would be good for sure |
So just error as a string an empty user_claim sounds good to you? |
I thought maybe |
e14ce48
to
8a56588
Compare
8a56588
to
f176c42
Compare
I force pushed update that has the AuthorizationResponse now. Still working on the correct approach to auth error events offline with the team. |
ec025ad
to
3b08d96
Compare
This adds the ability to augment or override the NATS auth system. A server will send a signed request to $SYS.REQ.USER.AUTH on the specified account. The request will contain client information, all client options sent to the server, and optionally TLS information and client certificates. The external auth service will respond with an empty message if not authorized, or a signed User JWT that the user will bind to. The response can change the account the client will be bound to. Signed-off-by: Derek Collison <derek@nats.io>
3b08d96
to
2daf904
Compare
…on from the callout service. Signed-off-by: Derek Collison <derek@nats.io>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, didnt have time to end to end test the new event but looks good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Believe these were handled.
An implementation for a server-signed authorization request mechanism. The mechanism will be used in both server configuration and operator mode servers. This allows external NATS applications to securely authorize users with external AuthN.
Signed-off-by: Derek Collison derek@nats.io
/cc @nats-io/core