-
Notifications
You must be signed in to change notification settings - Fork 360
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
[Feature] Integrate External Auth Principals management #7539
Conversation
♻️ PR Preview 7600075 has been successfully destroyed since this PR has been closed. 🤖 By surge-preview |
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.
Add a few suggestions/questions.
Overall looks good.
api/swagger.yml
Outdated
ExternalPrincipal: | ||
type: object | ||
required: | ||
- users |
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.
Why users and not only user IDs?
Where do we use the other information?
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.
Why users and not only user IDs?
Notice users
is of type array[string]
, user IDs.
Where do we use the other information?
Other information is essentially config that will be digested by the remote authenticator.
For example, in AWS remote auth - when we create principal, this will contain flag indicating if we want to use the session name or not.
It's optional, to stay agile it's not specific to anything so that we don't need to break the API tomorrow.
api/swagger.yml
Outdated
@@ -2523,7 +2554,98 @@ paths: | |||
description: too many requests | |||
default: | |||
$ref: "#/components/responses/ServerError" | |||
|
|||
/auth/external/principals: |
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'm not sure what this API returns.
a list of external principals configured for the current installation?
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 used the exact pattern we use for groups, roles, users.
depends on the HTTP verb, one is a list the other will create attachment.
api/swagger.yml
Outdated
post: | ||
tags: | ||
- auth | ||
- external | ||
operationId: createExternalPrincipal | ||
summary: Create principal as external identity connected to lakeFS user |
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 thought that external auth are configurable, not something the user need to make an API call to add
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'm not sure what you mean, perhaps a miss understanding?
As the summary suggests (maybe not that well?) it will create a specific principal.
i.e arn:123:role:abc
-> user_a
.
Co-authored-by: Idan Novogroder <43949240+idanovo@users.noreply.github.com>
TODO:
|
@idanovo please review |
docs/assets/js/swagger.yml
Outdated
@@ -2523,6 +2589,104 @@ paths: | |||
description: too many requests | |||
default: | |||
$ref: "#/components/responses/ServerError" | |||
|
|||
/auth/external/principals: | |||
get: |
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's either removing this API or making it useful by returning something more than the id
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 that getting the list of principals' IDs we have might be useful.
We should consider changing ExternalPrincipalList
to return an actual list of ExternalPrincipals
so we will get the user IDs too.
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.
Looks good!
Minor comments
pkg/api/controller.go
Outdated
|
||
func (c *Controller) CreateUserExternalPrincipal(w http.ResponseWriter, r *http.Request, body apigen.CreateUserExternalPrincipalJSONRequestBody, userID, principalID string) { | ||
ctx := r.Context() | ||
if c.Config.IsAuthUISimplified() || !c.Auth.IsExternalPrincipalsEnabled(ctx) { |
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.
Can you create a function for this? It's a reused code.
func (a *APIAuthService) IsExternalPrincipalsEnabled(ctx context.Context) bool { | ||
return a.externalPrincipalseEnabled | ||
} | ||
func (a *APIAuthService) CreateUserExternalPrincipal(ctx context.Context, userID, principalID string) error { |
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'm not sure if we need to check here user's existence.
WDYT?
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 wouldn't want to check this here.
If you look at other requests such as AttachPolicyToUser
and DetachPolicyFromUser
when using APIAuthService
(API service) we let that API decide on the correct authorization.
Especially around external principal implementation i'd rather let the auth service dictate the business logic since the implementation details belong to there.
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
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.
Thanks for the PR, it's great to see the progress 💪
Mostly nit, a few blocking comments
user_id: | ||
type: string | ||
description: | | ||
lakeFS user ID to associate with an external principal. |
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.
Email? something else?
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 have no idea what's the question?
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 we have many id types for a user in Treeverse, right? I may be wrong..
api/swagger.yml
Outdated
properties: | ||
id: | ||
type: string | ||
description: A unique identifier for the external principal |
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.
Can you add a string example?
api/swagger.yml
Outdated
|
||
|
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 actually like the blank lines, it's very hard for me to udnerstand where an object ends without them
additionalProperties: | ||
type: string | ||
description: Additional settings to be consumed by the remote authenticator |
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 understand what this is. Is it Opaque? Can you add an example?
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 opaque on purpose to avoid breaking the API.
An example is forcing session_name or only matching based on role_name in IAM.
Another example would be specifying max ttl.
ExternalPrincipalCreation: | ||
type: object | ||
properties: | ||
settings: | ||
type: object | ||
items: | ||
$ref: "#/components/schemas/ExternalPrincipalSettings" |
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.
Creation has just a list of settings which are strings?
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.
That's currently optional, ExternalPrincipalSettings
is an object of key/value with string type.
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.
Thanks for the prompt fix! Single non blocking comment
c.LogAction(ctx, "create_user_external_principal", r, "", "", "") | ||
|
||
err := c.Auth.CreateUserExternalPrincipal(ctx, userID, principalID) | ||
if c.handleAPIError(ctx, w, r, err) { |
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 I see what happened here.
You check first thing for isExternalPrincipalNotSupported
and then return not implemented. I thought we reach the AuthService
that returns an error auth.ErrNotImplemented
but I was wrong. When handleAPIError
sees an error it doesn't recognize it will return Internal Server Error
which is not what we want but also not the case here.
I believe it's slightly better to have the AuthService
handle the possible ExternalPrincipal
s enabled/disabled status in terms of separation of concerns, i.e. it's not the controller
responsibility, you have errors as communication protocol between the 2 components. BUT - it is also not a bug, and definitely not a blocking bug.
Closes #7536
Change Description
Adding auth management endpoints for external principals management such as AWS IAM roles.
Background
As part of getting token in lakeFS from external principals such as IAM role we need to support for the CRUD operations around those attachments between an external principal and lakeFS user.
Testing Details
Added unit tests.
Breaking Change?
Additional Info
More things that needs to be done before this feature is complete: