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

API Refactors: Authorization middleware scaffolding #1589

Merged
merged 3 commits into from
May 29, 2020

Conversation

azdagron
Copy link
Member

This middleware can be used to set up authorization for the whole API surface from a single spot.

The middleware provide information on the context for handlers, like the caller address, SPIFFE ID, and X509-SVID.

This change also updates the rpccontext package to provide finer grained values and remove specific details on how those values are determined.

It also removes the auth check in a bundle handler since the middleware is now in charge of all authorization checks.

Individual authorizers to use with this middleware will land in future PRs.

This middleware can be used to set up authorization for the whole API
surface from a single spot.

The middleware provide information on the context for handlers, like
the caller address, SPIFFE ID, and X509-SVID.

This change also updates the rpccontext package to provide finer grained
values and remove specific details on how those values are determined.

It also removes the auth check in a bundle handler since the middleware is
now in charge of all authorization checks.

Signed-off-by: Andrew Harding <andrew.harding@hpe.com>
Copy link
Member

@amartinezfayo amartinezfayo left a comment

Choose a reason for hiding this comment

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

Thank you for this @azdagron!
My main feedback is around error codes returned.

pkg/server/api/middleware/authorization.go Outdated Show resolved Hide resolved
pkg/server/api/rpccontext/caller.go Outdated Show resolved Hide resolved
authorizer, ok := m.authorizers[methodName]
if !ok {
rpccontext.Logger(ctx).Error("Authorization misconfigured; this is a bug")
return nil, status.Errorf(codes.Internal, "authorization misconfigured")
Copy link
Member

Choose a reason for hiding this comment

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

Maybe codes.PermissionDenied is a better code to use here? We may include the method name in the error?

Copy link
Member Author

Choose a reason for hiding this comment

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

My intention here was to only return PermissionDenied if we actually determined that the caller did not have permission. In this case, this means that we (SPIRE devs) messed up and didn't set up authorization for a method. Clients may choose to do some action based on the status code and I didn't want to conflate the two. Internal is an indication that something is wrong outside of the callers control that they can't rectify on their own.

I didn't add the method name to the returned error because the caller presumably knows the method name they are calling? I'd be ok adding it though if you think it will help debuggability.

The logger will already have fields added with the method name.

Copy link
Member

Choose a reason for hiding this comment

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

I think that makes sense.
Regarding including the method name, I think that I will not hurt and can help in the case of debugging this error.

func callerContextFromContext(ctx context.Context) (context.Context, error) {
p, ok := peer.FromContext(ctx)
if !ok {
return nil, status.Error(codes.Internal, "no peer information available")
Copy link
Member

Choose a reason for hiding this comment

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

Looks like we currently return codes.Unauthenticated in this case. Curious to know if you consider that needs to be changed?

Copy link
Member Author

Choose a reason for hiding this comment

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

This check is purely defensive. I don't expect this to ever happen, since gRPC takes care of adding the peer to the context. That being said, I think Internal is a clearer code and communicates that something is really wrong internally. A caller might interpret Unauthenticated to mean that they could take some action to become authenticated, but in this case, there isn't anything they can do.

Also fixed up some comments based on PR feedback.

Signed-off-by: Andrew Harding <andrew.harding@hpe.com>
Copy link
Member

@amartinezfayo amartinezfayo left a comment

Choose a reason for hiding this comment

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

LGTM!

@azdagron
Copy link
Member Author

Build passed on travis but is stuck notifying. Merging anyway.

@azdagron azdagron merged commit 8b3029a into spiffe:master May 29, 2020
@azdagron azdagron deleted the authorization-middleware-scaffolding branch May 29, 2020 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants