Skip to content

Conversation

@yuyuvn
Copy link
Contributor

@yuyuvn yuyuvn commented Jan 8, 2026

Description

Fix #4009

Checklist

  • I made sure to update ./CHANGELOG.yml (our release notes are generated from this file).
  • I made sure to add any documentation changes required for my change.
  • My change is adequately tested.
  • I updated CONTRIBUTING.md with any special dev tricks I had to use to work on this code efficiently.
  • Once my PR is ready to have integration tests ran, I posted the PR in #telepresence-oss channel on the
    CNCF Slack so that the "ok to test" label can be applied.

@yuyuvn yuyuvn force-pushed the support-revoke-intercept branch from a8ba8f0 to 6518075 Compare January 8, 2026 07:21
@thallgren
Copy link
Member

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.

@yuyuvn yuyuvn force-pushed the support-revoke-intercept branch 5 times, most recently from 5d1489f to 4ed3287 Compare January 9, 2026 06:43
@yuyuvn
Copy link
Contributor Author

yuyuvn commented Jan 9, 2026

sorry, after I commit DCO, the change related to token review was disapeared...

I added it and add unit test, too

@yuyuvn yuyuvn force-pushed the support-revoke-intercept branch 2 times, most recently from 3e50e55 to 448d483 Compare January 9, 2026 06:46
Copy link
Member

@thallgren thallgren left a 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.


// 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 {
Copy link
Member

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) ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

resolved in 80274bd

}

// IsMemberOfGroup checks if a user belongs to a specific group.
func IsMemberOfGroup(groups []string, targetGroup string) bool {
Copy link
Member

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 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

resolved in 80274bd

Comment on lines 66 to 71
for _, group := range groups {
if group == targetGroup {
return true
}
}
return false
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
for _, group := range groups {
if group == targetGroup {
return true
}
}
return false
return slices.Contains(groups, targetGroup)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

resolved in 80274bd

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)
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

resolved in 80274bd

@yuyuvn yuyuvn force-pushed the support-revoke-intercept branch 3 times, most recently from 479017a to 74327a1 Compare January 13, 2026 08:25
@yuyuvn
Copy link
Contributor Author

yuyuvn commented Jan 13, 2026

I refactored to use AGENT_K8S_ADMIN_GROUPS env to control allowed admin groups because it's hard to test in kind cluster for harded code group (with a dynamic group, it can also allow service account token to be used)

Can quickly test by creating a service account in ambassador namespace and add this env to manager deployment

          - name: AGENT_K8S_ADMIN_GROUPS
            value: "system:masters system:serviceaccounts:ambassador"

with token created from

kubectl create token test-admin -n ambassador --duration=1h

it also works with OIDC token from aws eks get-token

@yuyuvn yuyuvn force-pushed the support-revoke-intercept branch 7 times, most recently from d5e663f to bac5c2f Compare January 14, 2026 03:01
@yuyuvn yuyuvn force-pushed the support-revoke-intercept branch from bac5c2f to 8611806 Compare January 14, 2026 03:01
@yuyuvn
Copy link
Contributor Author

yuyuvn commented Jan 14, 2026

Fixed lint 🙏

Copy link
Member

@thallgren thallgren left a 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>",
Copy link
Member

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.

  1. 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.
  2. 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.

Copy link
Contributor Author

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)

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 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?

@yuyuvn
Copy link
Contributor Author

yuyuvn commented Jan 14, 2026

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.

I can try if SubjectAccessReview can work without define custom resource for intercept.
it would be more k8s native if intercept state is stored in k8s storage with crd for intercept, but I feel like it would be a big refactor. that also resolve problem how to get list other's intercept

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.

Able to forcefully kill an intercept from other

2 participants