-
Notifications
You must be signed in to change notification settings - Fork 904
feat: Implement list roles & enforce authorize examples #1273
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
Conversation
Authorize can be changed dynamically with middlewares.
Codecov Report
@@ Coverage Diff @@
## main #1273 +/- ##
==========================================
+ Coverage 65.96% 66.07% +0.11%
==========================================
Files 277 280 +3
Lines 18230 18384 +154
Branches 216 216
==========================================
+ Hits 12025 12147 +122
- Misses 4956 4973 +17
- Partials 1249 1264 +15
Continue to review full report at Codecov.
|
@@ -48,6 +50,7 @@ type Options struct { | |||
SecureAuthCookie bool | |||
SSHKeygenAlgorithm gitsshkey.Algorithm | |||
TURNServer *turnconn.Server | |||
Authorizer *rbac.RegoAuthorizer |
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.
Does this need to be exposed via options? It doesn't seem to be used outside of here.
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 was thinking of making it an interface that is "denyall" or something to trigger in unit tests. But for now, we don't, so I'll drop it from Options
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.
Ah wait yes. @kylecarbs this will be needed if you decide to do the rbac Authorize()
check manually inside the function, instead of the middleware. So this is required.
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 could go on api
instead, that way tests couldn't mistakenly pass it via Options
.
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.
Right now nothing else is on the api only like that.
Lines 333 to 338 in db04d67
type api struct { | |
*Options | |
websocketWaitMutex sync.Mutex | |
websocketWaitGroup sync.WaitGroup | |
} |
I don't think it'd be bad to pass one in via options 🤷♂️
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.
Oh my bad, I thought there was precedent for this 🤦
If you feel like it's fine I'll defer, but I generally think it's hasty to expose a value unless it needs to be used elsewhere. It's really easy to expose a parameter, but much harder to hide one.
// Authorize will enforce if the user roles can complete the action on the AuthObject. | ||
// The organization and owner are found using the ExtractOrganization and | ||
// ExtractUser middleware if present. | ||
func Authorize(logger slog.Logger, auth *rbac.RegoAuthorizer, action rbac.Action) func(http.Handler) http.Handler { |
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.
Authorize
feels like action, not something that would return a handler.
What do you think about renaming this to EnforceRBAC
?
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 think EnforceRBAC
is also weak though. I was thinking the package httpmw
provides enough context, and it does do the action Authorize()
.
Authorize
is the correct word for what is happening, as it's not authentication. I feel EnforceRBAC
doesn't indicate the object
and action
are included.
Another word that comes to mind is "Access". Idk, EnforceAccess
, EnforcePermissions
. Maybe EnforceRBAC
isn't that bad, just felt odd to me at first.
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.
Fair enough. I'm primarily trying to display that the RBAC
package is being leveraged when calling this handle. Enforce
is a bit sketchy too.
While it is authorizing, I'm nervous that this will get conflated with authentication really easily.
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.
yea this is classic authorization vs authentication. If you aren't familiar with it, it's easy to mix up.
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.
Agreed agreed
|
||
// WithRBACObject sets the object for 'Authorize()' for all routes handled | ||
// by this middleware. The important field to set is 'Type' | ||
func WithRBACObject(object rbac.Object) func(http.Handler) http.Handler { |
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.
It might be confusing that this is called WithRBACObject
, but the values are rbac.ResourceX
. It could be helpful to make these the same names!
// Authorize will enforce if the user roles can complete the action on the AuthObject. | ||
// The organization and owner are found using the ExtractOrganization and | ||
// ExtractUser middleware if present. | ||
func Authorize(logger slog.Logger, auth *rbac.RegoAuthorizer, action rbac.Action) func(http.Handler) http.Handler { |
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.
Agreed agreed
This is the first step to enforcing rbac roles for our endpoints. This also adds the endpoints to list the roles available to assign.