-
-
Notifications
You must be signed in to change notification settings - Fork 563
Allow cluster admin revoke other intercepts #4027
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
base: release/v2
Are you sure you want to change the base?
Conversation
a8ba8f0 to
6518075
Compare
|
I don't see anything here preventing a client from revoking an intercept. You'll need to provide a test that proves that only an admin account can revoke an intercept. |
5d1489f to
4ed3287
Compare
|
sorry, after I commit DCO, the change related to token review was disapeared... I added it and add unit test, too |
3e50e55 to
448d483
Compare
thallgren
left a comment
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 code looks great overall. I made some improvement suggestions.
I'm missing one major part here though. The client side calling this new API endpoint. The PR won't be much use to an end user without that. So please also provide the new telepresence revoke command (or similar), where the user passes a token (preferably from stdin).
It would also be very valuable if you could add a section to the docs explaining how to add a user with the correct group affinity to the cluster and obtain the necessary token.
pkg/k8sapi/tokenreview.go
Outdated
|
|
||
| // VerifyToken verifies a bearer token using Kubernetes TokenReview API | ||
| // and returns information about the authenticated user including their groups. | ||
| func VerifyToken(ctx context.Context, token string) *VerifyTokenResult { |
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 a fan of returning an error as part of the result. I think it's more in line with other API's if you remove the Error field from the VerifyTokenResult and instead return (VerifyTokenResult, error).
Maybe also consider renaming the function and the struct. The function doesn't just verify a token, it actually obtains user information from that token. So perhaps something like:
func UserInfoForToken(ctx context.Context, token string) (UserInfo, 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.
resolved in 80274bd
pkg/k8sapi/tokenreview.go
Outdated
| } | ||
|
|
||
| // IsMemberOfGroup checks if a user belongs to a specific group. | ||
| func IsMemberOfGroup(groups []string, targetGroup string) bool { |
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.
Maybe this could be func (u *UserInfo) IsMemberOfGroup(group string) bool ?
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.
resolved in 80274bd
pkg/k8sapi/tokenreview.go
Outdated
| for _, group := range groups { | ||
| if group == targetGroup { | ||
| return true | ||
| } | ||
| } | ||
| return false |
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.
| for _, group := range groups { | |
| if group == targetGroup { | |
| return true | |
| } | |
| } | |
| return false | |
| return slices.Contains(groups, targetGroup) |
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.
resolved in 80274bd
cmd/traffic/cmd/manager/service.go
Outdated
| return nil, status.Errorf(codes.PermissionDenied, "user must be a member of telepresence:admin or system:masters group") | ||
| } | ||
|
|
||
| dlog.Infof(ctx, "User %s authorized to revoke intercepts", tokenResult.Username) |
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.
Please don't include the user name in the log. It might be considered sensitive information and prevent logs from being shared.
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.
resolved in 80274bd
479017a to
74327a1
Compare
|
I refactored to use Can quickly test by creating a service account in ambassador namespace and add this env to manager deployment with token created from it also works with OIDC token from |
d5e663f to
bac5c2f
Compare
Signed-off-by: Phan Duc <[email protected]>
Signed-off-by: Phan Duc <[email protected]>
Signed-off-by: Phan Duc <[email protected]>
Signed-off-by: Phan Duc <[email protected]>
Signed-off-by: Phan Duc <[email protected]>
bac5c2f to
8611806
Compare
|
Fixed lint 🙏 |
thallgren
left a comment
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.
A general question. Can we control this somehow using RBAC? Telepresence is often used in situations where it's limited to a specific set of namespaces. It would be great if the permission to revoke an intercept was associated with a role/rolebinding or clusterrole/clusterrolebinding. Which one that is in use depends on scope determined by the namespace selector. This way, any user could be permitted to do this by only associating this binding with an existing user account.
| Use: "revoke <token> <intercept_id>", | ||
| Args: cobra.ExactArgs(2), | ||
|
|
||
| Short: "Revoke an intercept by intercept ID. The intercept ID must be in the format <session_id>:<intercept_name>", |
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 see two problems with exposing and using the intercept ID like this.
- This ID is supposed to be opaque. The fact that it's composed by the client's session-id and a name isn't necessarily something that we want to expose as API and then stick with it.
- How is a user supposed to find another users session_id? AFAIK, the only place it's visible today is if you run the traffic-manager with log level debug or trace and then scan the logs.
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 can fetch it from sidecar logs (that's how I plan to use in my environment)
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 depends on what type of conflict you're encountering. If the traffic-manager detects that you have a --http-header based conflict, then you'll get an error similar to:
"intercept in error state AGENT_ERROR: Conflicts with the currently-served intercept "ae29c3db-0e14-4517-a538-7953e19fd155:echo-easy": header filters form a subset
but if the intercept is global, the user will instead see:
container port 8080 is already intercepted by root@3029256df965, intercept echo-easy
I think this is unfortunate. It would be far better, and also consistent with your approach, if both errors displayed the intercept ID. It would also remove the need to look into logs to find the ID. Do you think it would be possible for you to fix so that these errors both report the intercept ID?
I can try if SubjectAccessReview can work without define custom resource for intercept. |
Description
Fix #4009
Checklist
./CHANGELOG.yml(our release notes are generated from this file).CONTRIBUTING.mdwith any special dev tricks I had to use to work on this code efficiently.CNCF Slack so that the "ok to test" label can be applied.