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

Show device trust status in Connect #49508

Merged
merged 20 commits into from
Nov 29, 2024

Conversation

gzdunek
Copy link
Contributor

@gzdunek gzdunek commented Nov 27, 2024

Closes #47249

The original issue is about indicating if the device is enrolled, which is simply done by checking if the profile extensions include all the necessary device trust extensions.

While working on this, I realized it's quite simple to add a warning when device trust is required but the device isn't enrolled, similar to the Web UI. To implement this, I had to:

  • Add fetching authentication preferences.
  • Extract the function that determines the device trust requirement from the server code.

This partially addresses #43020.

The messages shown in Connect are slightly different than in Web UI (for reference we say there Session authorized with device trust. or Session in not authorized with Device Trust. Access is restricted.).
My reasoning was that device enrollment is persistent, you don't need to authorize every session, as in Web UI. Because of that, I dropped the "session" term.
I'm curious what are your thoughts on this :)

A confirmation that device is enrolled:
image

A warning that access is restricted without enrolling the device:
image

Changelog: Teleport Connect now shows whether it is being used on a trusted device or if enrollment is required for full access

…TS definitions for it

Generating TS definitions for the entire legacy/types/types.proto would result in 50K lines of generated code, and the bundle size would increase by ~20% (around 1 MB).
…ed both by the server and the client

Important: it now uses `GetEnforcementMode` instead of `GetEffectiveMode`. The check for OSS module is performed on the server-side anyway.
@zmb3
Copy link
Collaborator

zmb3 commented Nov 27, 2024

Can we add a little bit of color? The colors and icon are the same in both cases, so you have to read the text to determine if your device is trusted or not.

Making the shield green or yellow might make it easier to tell at a glance.

@gzdunek gzdunek marked this pull request as ready for review November 27, 2024 16:40
@gzdunek gzdunek requested review from ravicious and removed request for rudream November 27, 2024 16:41
@gzdunek
Copy link
Contributor Author

gzdunek commented Nov 27, 2024

Making the shield green or yellow might make it easier to tell at a glance.

Good idea, I will do it tomorrow.

@avatus
Copy link
Contributor

avatus commented Nov 27, 2024

Not sure if you were able to use it or not, but we have a DeviceTrustIcon component that can help you keep the colors inline with the web
https://github.com/gravitational/teleport/blob/master/web/packages/teleport/src/TopBar/DeviceTrustIcon.tsx#L26-L28

Copy link
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

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

Nice! Thanks for the change, Grzegorz.

api/proto/teleport/legacy/types/types.proto Outdated Show resolved Hide resolved
lib/devicetrust/authz/authz.go Outdated Show resolved Hide resolved
lib/devicetrust/authz/authz.go Outdated Show resolved Hide resolved
lib/devicetrust/authz/authz.go Outdated Show resolved Hide resolved
lib/devicetrust/authz/authz.go Outdated Show resolved Hide resolved
lib/teleterm/clusters/cluster.go Outdated Show resolved Hide resolved
lib/teleterm/clusters/cluster.go Outdated Show resolved Hide resolved
lib/teleterm/clusters/cluster.go Show resolved Hide resolved
lib/devicetrust/authz/authz_test.go Outdated Show resolved Hide resolved
@gzdunek
Copy link
Contributor Author

gzdunek commented Nov 28, 2024

Not sure if you were able to use it or not, but we have a DeviceTrustIcon component that can help you keep the colors inline with the web
https://github.com/gravitational/teleport/blob/master/web/packages/teleport/src/TopBar/DeviceTrustIcon.tsx#L26-L28

At first I wanted to use it, but then I realized that it would require some changes to make it work Connect (customizable size, getting rid of the container). I believe there's not much benefit to using the shared icon, and it's not worth the effort of making it shared.

On top of that, in Connect I used more vibrant colors: success.main/warning.main vs success.active/warning.active to better match ConnectionStatusIndicator color :)

This is how it looks now:
image

image

@gzdunek gzdunek requested a review from codingllama November 28, 2024 11:35
Copy link
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

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

LGTM.

lib/devicetrust/authz/authz.go Outdated Show resolved Hide resolved
lib/devicetrust/authz/authz.go Outdated Show resolved Hide resolved
lib/devicetrust/authz/authz.go Outdated Show resolved Hide resolved
Copy link
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

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

Looking good. 👌

user types.User
roles []types.Role
)

group, groupCtx := errgroup.WithContext(ctx)
Copy link
Member

Choose a reason for hiding this comment

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

At some point we might want to put some kind of limit here. I know that the code responsible for things like tsh ls -R sets that limit to 10 active goroutines:

// Fetch node listings for all clusters in parallel with an upper limit
group, groupCtx := errgroup.WithContext(cf.Context)
group.SetLimit(10)

Though in that case, each goroutine uses a separate connection and that's why it's limited (I assume). Here from what I can tell we have three separate clients making three separate connections and it's just 8 goroutines total. So we should be safe for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for setting a limit to the group.

Copy link
Member

Choose a reason for hiding this comment

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

@codingllama But at this point what we should set it to?

Copy link
Contributor

Choose a reason for hiding this comment

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

The number itself doesn't matter a whole lot, what is more important IMO is making sure we have an upper bound on the number of goroutines. I usually consider 8 to 10 fairly big numbers for this kind of work. Also note that you probably don't need to increase the number every time you add a new group.Go call - at limit=8 this should be pretty fast anyway.

For example:

	group, groupCtx := errgroup.WithContext(ctx)
	const groupLimit = 8 // Arbitrary. No need to increase for every new goroutine.
	group.SetLimit(groupLimit)

Copy link
Contributor

Choose a reason for hiding this comment

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

(If this is really critical you can always measure for a better number.)

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 set it to 8 for now.

Comment on lines +66 to +67
top: 1.5px;
right: 1.5px;
Copy link
Member

Choose a reason for hiding this comment

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

I wanted to check if this is consistent with the other indicators in the top bar and… ggs we'll get them next time.

top-bar

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 placed it to fit in the border of the Profiles button :/

But in general, we should replace this icon, it's too detailed for its size and transparent, making it difficult to place over other elements. Maybe I will find time for this when redesigning the profile switcher.

@gzdunek gzdunek enabled auto-merge November 29, 2024 09:45
@gzdunek gzdunek added this pull request to the merge queue Nov 29, 2024
Merged via the queue into master with commit 095b0a3 Nov 29, 2024
45 checks passed
@gzdunek gzdunek deleted the gzdunek/indicate-device-trust-in-connect branch November 29, 2024 10:35
@public-teleport-github-review-bot

@gzdunek See the table below for backport results.

Branch Result
branch/v16 Failed
branch/v17 Failed

gzdunek added a commit that referenced this pull request Nov 29, 2024
* Check if device is trusted

* Move `TrustedDeviceRequirement` enum to a separate file and generate TS definitions for it

Generating TS definitions for the entire legacy/types/types.proto would result in 50K lines of generated code, and the bundle size would increase by ~20% (around 1 MB).

* Extract function to calculate device trust requirement that can be used both by the server and the client

Important: it now uses `GetEnforcementMode` instead of `GetEffectiveMode`. The check for OSS module is performed on the server-side anyway.

* Check what is device trust requirement based on cluster config and user roles

* Show device trust status in UI

* Remove `types.` prefix

* Improve godocs

* Bring back `getRoles func() ([]types.Role, error)`

* Simplify `TestHasDeviceTrustExtensions`

* Clean up and improve `TestCalculateTrustedDeviceRequirement`

* Move `CalculateTrustedDeviceRequirement` and tests to a separate file

* Add colors to shield icons

* Declare variables where they are used

* Extract a component to display device trust status for better readability

* Correctly reference `lib/client.ProfileStatus.Extensions`

* Set group limit to 8

* Make `switch` exhaustive

* Regenerate protos

* `make fix-license`

(cherry picked from commit 095b0a3)
gzdunek added a commit that referenced this pull request Nov 29, 2024
* Check if device is trusted

* Move `TrustedDeviceRequirement` enum to a separate file and generate TS definitions for it

Generating TS definitions for the entire legacy/types/types.proto would result in 50K lines of generated code, and the bundle size would increase by ~20% (around 1 MB).

* Extract function to calculate device trust requirement that can be used both by the server and the client

Important: it now uses `GetEnforcementMode` instead of `GetEffectiveMode`. The check for OSS module is performed on the server-side anyway.

* Check what is device trust requirement based on cluster config and user roles

* Show device trust status in UI

* Remove `types.` prefix

* Improve godocs

* Bring back `getRoles func() ([]types.Role, error)`

* Simplify `TestHasDeviceTrustExtensions`

* Clean up and improve `TestCalculateTrustedDeviceRequirement`

* Move `CalculateTrustedDeviceRequirement` and tests to a separate file

* Add colors to shield icons

* Declare variables where they are used

* Extract a component to display device trust status for better readability

* Correctly reference `lib/client.ProfileStatus.Extensions`

* Set group limit to 8

* Make `switch` exhaustive

* Regenerate protos

* `make fix-license`

(cherry picked from commit 095b0a3)
gzdunek added a commit that referenced this pull request Nov 29, 2024
* Check if device is trusted

* Move `TrustedDeviceRequirement` enum to a separate file and generate TS definitions for it

Generating TS definitions for the entire legacy/types/types.proto would result in 50K lines of generated code, and the bundle size would increase by ~20% (around 1 MB).

* Extract function to calculate device trust requirement that can be used both by the server and the client

Important: it now uses `GetEnforcementMode` instead of `GetEffectiveMode`. The check for OSS module is performed on the server-side anyway.

* Check what is device trust requirement based on cluster config and user roles

* Show device trust status in UI

* Remove `types.` prefix

* Improve godocs

* Bring back `getRoles func() ([]types.Role, error)`

* Simplify `TestHasDeviceTrustExtensions`

* Clean up and improve `TestCalculateTrustedDeviceRequirement`

* Move `CalculateTrustedDeviceRequirement` and tests to a separate file

* Add colors to shield icons

* Declare variables where they are used

* Extract a component to display device trust status for better readability

* Correctly reference `lib/client.ProfileStatus.Extensions`

* Set group limit to 8

* Make `switch` exhaustive

* Regenerate protos

* `make fix-license`

(cherry picked from commit 095b0a3)
github-merge-queue bot pushed a commit that referenced this pull request Nov 29, 2024
* Show device trust status in Connect (#49508)

* Check if device is trusted

* Move `TrustedDeviceRequirement` enum to a separate file and generate TS definitions for it

Generating TS definitions for the entire legacy/types/types.proto would result in 50K lines of generated code, and the bundle size would increase by ~20% (around 1 MB).

* Extract function to calculate device trust requirement that can be used both by the server and the client

Important: it now uses `GetEnforcementMode` instead of `GetEffectiveMode`. The check for OSS module is performed on the server-side anyway.

* Check what is device trust requirement based on cluster config and user roles

* Show device trust status in UI

* Remove `types.` prefix

* Improve godocs

* Bring back `getRoles func() ([]types.Role, error)`

* Simplify `TestHasDeviceTrustExtensions`

* Clean up and improve `TestCalculateTrustedDeviceRequirement`

* Move `CalculateTrustedDeviceRequirement` and tests to a separate file

* Add colors to shield icons

* Declare variables where they are used

* Extract a component to display device trust status for better readability

* Correctly reference `lib/client.ProfileStatus.Extensions`

* Set group limit to 8

* Make `switch` exhaustive

* Regenerate protos

* `make fix-license`

(cherry picked from commit 095b0a3)

* Remove unsupported property from stories
github-merge-queue bot pushed a commit that referenced this pull request Nov 29, 2024
* Check if device is trusted

* Move `TrustedDeviceRequirement` enum to a separate file and generate TS definitions for it

Generating TS definitions for the entire legacy/types/types.proto would result in 50K lines of generated code, and the bundle size would increase by ~20% (around 1 MB).

* Extract function to calculate device trust requirement that can be used both by the server and the client

Important: it now uses `GetEnforcementMode` instead of `GetEffectiveMode`. The check for OSS module is performed on the server-side anyway.

* Check what is device trust requirement based on cluster config and user roles

* Show device trust status in UI

* Remove `types.` prefix

* Improve godocs

* Bring back `getRoles func() ([]types.Role, error)`

* Simplify `TestHasDeviceTrustExtensions`

* Clean up and improve `TestCalculateTrustedDeviceRequirement`

* Move `CalculateTrustedDeviceRequirement` and tests to a separate file

* Add colors to shield icons

* Declare variables where they are used

* Extract a component to display device trust status for better readability

* Correctly reference `lib/client.ProfileStatus.Extensions`

* Set group limit to 8

* Make `switch` exhaustive

* Regenerate protos

* `make fix-license`

(cherry picked from commit 095b0a3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Indicate when a Teleport Connect session is on a trusted device
5 participants