Skip to content

feat: Gateway: CRW-8927 - Simplify login in to the OCP cluster from the Gateway plugin#247

Open
vrubezhny wants to merge 31 commits intoredhat-developer:mainfrom
vrubezhny:feaat-sso-auth
Open

feat: Gateway: CRW-8927 - Simplify login in to the OCP cluster from the Gateway plugin#247
vrubezhny wants to merge 31 commits intoredhat-developer:mainfrom
vrubezhny:feaat-sso-auth

Conversation

@vrubezhny
Copy link
Copy Markdown
Collaborator

@vrubezhny vrubezhny commented Jan 20, 2026

fixes https://redhat.atlassian.net/browse/CRW-10338

This POC PR adds a possibility to authorize on...

  • ...an OpenShift cluster via OpenShift OAuth Authenticator
  • ...a Sandbox provisioned cluster via RedHat SSO Authenticator
image

POC Demo:

Openshift-Authentication-POC.mp4

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Jan 20, 2026

Codecov Report

❌ Patch coverage is 8.16960% with 1776 lines in your changes missing coverage. Please review.
✅ Project coverage is 21.09%. Comparing base (71098f6) to head (3c2ffa7).
⚠️ Report is 337 commits behind head on main.

Files with missing lines Patch % Lines
...ools/gateway/view/steps/DevSpacesServerStepView.kt 0.00% 231 Missing ⚠️
...evtools/gateway/auth/code/OpenShiftAuthCodeFlow.kt 0.00% 156 Missing ⚠️
...vtools/gateway/openshift/OpenShiftClientFactory.kt 0.00% 116 Missing ⚠️
...at/devtools/gateway/kubeconfig/KubeConfigUpdate.kt 0.00% 85 Missing ⚠️
...ateway/auth/session/OpenShiftAuthSessionManager.kt 0.00% 74 Missing ⚠️
...t/devtools/gateway/auth/code/RedHatAuthCodeFlow.kt 0.00% 73 Missing ⚠️
...evtools/gateway/auth/tls/DefaultTlsTrustManager.kt 0.00% 63 Missing ⚠️
...way/view/steps/auth/TokenAuthenticationStrategy.kt 0.00% 63 Missing ⚠️
...gateway/auth/sandbox/SandboxClusterAuthProvider.kt 0.00% 61 Missing ⚠️
...auth/OpenShiftCredentialsAuthenticationStrategy.kt 0.00% 60 Missing ⚠️
... and 55 more
Additional details and impacted files
@@            Coverage Diff             @@
##            main     #247       +/-   ##
==========================================
+ Coverage   0.00%   21.09%   +21.09%     
==========================================
  Files          4       98       +94     
  Lines         26     4134     +4108     
  Branches       0      736      +736     
==========================================
+ Hits           0      872      +872     
- Misses        26     3152     +3126     
- Partials       0      110      +110     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@vrubezhny vrubezhny force-pushed the feaat-sso-auth branch 2 times, most recently from 198f7c1 to 0efefa4 Compare January 21, 2026 01:42
@vrubezhny
Copy link
Copy Markdown
Collaborator Author

A few changes made to the Authentication and Select Cluster Wizard:

  • Auth via Username/password was added
  • Radio buttons changed to Tabs to make it more compact
  • The resulting token gets saved to Kube config not only for Auth via token, but also when authenticating via OpenshiftAuth or via Username/Password, if user checked the "Save config" option
  • Token and Password fields are ****-masked by default now, a checkboxes were added to the according Tabs to make these fields turn visible, if user checked the "Show token/password" option

Here's a POC demo for Auth via Username/Password onto a local CRC cluster (+DevSpaces installed):

Username-Password-Authentication-POC.mp4

@adietish
Copy link
Copy Markdown
Collaborator

adietish commented Feb 9, 2026

@vrubezhny is this ready to be reviewed or should I wait for you to finish it?

@TheChosenMok
Copy link
Copy Markdown

Quick question: does this also work the same the other way around, if i follow the flow from dev spaces dashboard will it also automatically login?

@vrubezhny
Copy link
Copy Markdown
Collaborator Author

vrubezhny commented Feb 12, 2026

Quick question: does this also work the same the other way around, if i follow the flow from dev spaces dashboard will it also automatically login?

Yes we're going to add this to the Connection Provider that uses Join Link from the Che Dashboard.
(However it's not included yet, at the moment the only DevSpaces connection wizard has this POC included.)

UPD: @TheChosenMok, I might have misunderstood the question... Connecting to a DevWorkspace from the Che Dashboard is just opening the JB's IDEA IDE app by joinLink - it doesn't have any auth information, so users will still have to authenticate with their credentials - so this Connect to Cluster dialog will still be appearing.
The fact that user has already been authenticated in Che Dashboard browser session doesn't make JB's IDEA Gateway plugin to be "authenticated" too.

@rgrunber
Copy link
Copy Markdown
Member

rgrunber commented Mar 5, 2026

Random drive-by comment : Most users aren't typing out the token themselves. They probably have it copied. Would it be possible to read the clipboard/copy buffer, detect if it is in the form of a token, and then autofocus the "Token" tab ? Maybe even autofilling the values ? You can also consider doing this in a separate issue as a nice-to-have after this is merged to reduce the amount of time spent on the PR.

@vrubezhny
Copy link
Copy Markdown
Collaborator Author

vrubezhny commented Mar 5, 2026

Random drive-by comment : Most users aren't typing out the token themselves. They probably have it copied. Would it be possible to read the clipboard/copy buffer, detect if it is in the form of a token, and then autofocus the "Token" tab ? Maybe even autofilling the values ? You can also consider doing this in a separate issue as a nice-to-have after this is merged to reduce the amount of time spent on the PR.

I thought about doing this and I believe it should be quite possible to read the Clipboard contents and paste it into the token field... But we don't actually have a certain source for getting the information how and where do we need to connect to before we choose a Dev Workspace (I mean which tab to switch to initially and why) - like yes, we may have a Kube config with its current context, but it might not even exist... For the Connection Provider is the same.

I mean... User must select/type in a cluster first, After that we should check that we don't have, for instance, client certificate set for the cluster (which usually, when set, tends to be the primary way to authenticate),and only after that we can start thinking on whether we have a token saved to the Clipboard or not... It's not like " hey! we have a token saved to the CB - let's connect using it" - cluster selection should be made first.

So, if we accept having Kube config's current context as the primary source for this information, we can try detecting if it points to a "token"-like connection and then try reading the Clipboard. Otherwise this would be a dumb guessing of what a user really wants to connect to.

Adding the Clipboard's saved token value as the source for making decision on what connection tab to choose may help, but also could add nothing but mess if such a choice will have no clear logic.

I'd created the separate issues for the possible further improvements including the Clipboard usage after this "starting" PR gets approved. (The PR has already ~60 changed files and it could become a really difficult to keep rebasing and improving it until it's merged)

PS: As the first approximation we can make it working for the token tab (so user must select a cluster, then switch to the Token tab explicitly):

Screencast.From.2026-03-05.23-43-37.mp4

@vrubezhny vrubezhny marked this pull request as ready for review March 6, 2026 14:48
@vrubezhny
Copy link
Copy Markdown
Collaborator Author

Fixup added for the cluster TLS Certificate verification. Now users asked for their trust-or-not decision on new cluster TLS Certificates:

Screenshot From 2026-03-06 20-15-44

@vrubezhny vrubezhny requested a review from rgrunber March 7, 2026 12:07
@csfercoci
Copy link
Copy Markdown

csfercoci commented Mar 11, 2026

all is tested properly? can it enter into main?

@vrubezhny
Copy link
Copy Markdown
Collaborator Author

all is tested properly? can it enter into main?

Yes, we're aiming to merge it into main, but at the moment the PR is under review.

@adietish
Copy link
Copy Markdown
Collaborator

Impressive! I am testing, reviewing it, will need quite some time though.

@adietish
Copy link
Copy Markdown
Collaborator

adietish commented Mar 13, 2026

Here's a usecase that doesn't work for me (or I dont use it properly).

Steps:

  1. ASSERT: have KUBECONFIG env variable and several files, each context in its own file. ~/.kube/config only has current-context
  2. EXEC: launch gateway app, use "Connect to Dev Spaces" and select the sandbox in the upcoming cluster
  3. EXEC: select "Red Hat SSO" tab and click "Check connection"
  4. ASSERT: browser window is opened pointing to http://localhost:59368/sso-redhat-callback?state=Aop3K2Of2Wc8AeWAzBWgxJghxCT_Q5DgcalNf3NA7Lo&session_state=fb95154b-f7e3-41e0-b5fd-1b87c19d6cd7&iss=https%3A%2F%2Fsso.redhat.com%2Fauth%2Frealms%2Fredhat-external&code=XXXX-XXXX-XXXXX-XXXXX-XXXX-XXXX-XXXX-XX
    and the page displays Authentication successful. You may close this window.

Result:
While the browser is opened, an error is displyed in the gateway application:
image
If I then click "OK" in the error dialog, the wizard is frozen while displaying the progress "Waiting for you to complete login in your browser..."

I also get to the frozen wizard when using the tab "OpenShift OAuth":

Steps:

  1. ASSERT: have KUBECONFIG env variable with 1 cluster/file and main file only having current-context
  2. EXEC: launch gateway app, use "Connect to Dev Spaces" and select the sandbox in the upcoming cluster
  3. EXEC: select "OpenShift OAuth" tab and click "Check connection"
  4. ASSERT: browser window is opened pointing to http://127.0.0.1:49190/callback?code=XXXX~XXXX&state=
    and the page displays Authentication successful. You may close this window.
  5. EXEC: Close the window and get back to the Gateway application.

Result:
The wizard still displays the progress "Obtaining OpenShift access..." but it's frozen. I cannot cancel it or do anything.
image

@adietish
Copy link
Copy Markdown
Collaborator

To my gusto, the error dialog is too verbose. It shows http code, response body and headers. It's far too verbose I would argue. I would show a simple, human readable cause like "You are unauthorized. Make sure you have a valid token."

image

@adietish
Copy link
Copy Markdown
Collaborator

I also think that the label "Authentication:" would look nicer if vertically aligned to the top:
image
image

Copy link
Copy Markdown
Collaborator

@adietish adietish left a comment

Choose a reason for hiding this comment

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

Impressive work!
Had first go at testing it, will do code review in a few.

* Represents the final result after exchanging code for tokens.
*/
enum class AuthTokenKind {
SSO,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

SSO is never used

private val clientId: String,
private val redirectUri: URI,
private val providerMetadata: OIDCProviderMetadata,
private val sslContext: SSLContext
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

sslContext is never used

Copy link
Copy Markdown
Collaborator

@adietish adietish left a comment

Choose a reason for hiding this comment

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

Suggested changes. Will work on some.

Comment thread src/main/kotlin/com/redhat/devtools/gateway/auth/code/OpenShiftAuthCodeFlow.kt Outdated
Comment thread src/main/kotlin/com/redhat/devtools/gateway/view/steps/DevSpacesServerStepView.kt Outdated
Comment thread src/main/kotlin/com/redhat/devtools/gateway/view/steps/DevSpacesServerStepView.kt Outdated
Comment thread src/main/kotlin/com/redhat/devtools/gateway/view/steps/DevSpacesServerStepView.kt Outdated
Comment thread src/main/kotlin/com/redhat/devtools/gateway/view/steps/DevSpacesServerStepView.kt Outdated
Comment on lines +259 to +292
class CreateContextWithClientCert(
clusterName: String,
clusterUrl: String,
private val clientCertPem: String,
private val clientKeyPem: String,
allConfigs: List<KubeConfig>
) : KubeConfigUpdate(clusterName, clusterUrl, "", allConfigs) {

override fun apply() {
val config = allConfigs.firstOrNull() ?: return

val user = createUser(allConfigs)
val users = config.users ?: ArrayList()
users.add(user.toMap())

val cluster = createCluster(allConfigs)
val clusters = config.clusters ?: ArrayList()
clusters.add(cluster.toMap())

val context = createContext(user, cluster, allConfigs)
val contexts = config.contexts ?: ArrayList()
contexts.add(context.toMap())

config.setContext(context.name)

save(
contexts,
clusters,
users,
config.preferences,
config.currentContext,
config.path
)
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is nearly identical to CreateContext. Maybe both could share code.

Comment thread src/main/kotlin/com/redhat/devtools/gateway/auth/tls/DefaultTlsTrustManager.kt Outdated

CoroutineScope(Dispatchers.IO).launch {
try {
val params: Parameters? = callbackServer.awaitCallback(OPENSHIFT_LOGIN_TIMEOUT_MS)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

cannot cancel browser login

val expiresAt: Long? = null
) {
fun isExpired(now: Long = System.currentTimeMillis()): Boolean =
expiresAt?.let { now >= it } ?: false
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

if token is expired things error. There's no automatic refresh. Guess we should file this to a new enhancement issue?

adietish and others added 24 commits May 4, 2026 20:00
- OpenShiftAuthCodeFlow, RedHatAuthCodeFlow: migrated all HttpClient.send() calls to sendAsync().await() to avoid thread blocking.
- SandboxApi: converted methods to suspend functions and implemented sendAsync().await().
- DefaultTlsTrustManager: refactored the TlsTrustManager interface and implementation to move network probes and I/O to Dispatchers.IO.
- IdeaSecureTokenStorage, JBPasswordSafeTokenStorage: moved PasswordSafe I/O operations to Dispatchers.IO.
- DevSpacesServerStepView: Moved blocking KubeConfigUtils calls out of the UI thread using withContext(Dispatchers.IO).
- OidcProviderMetadataResolver: Wrapped Nimbus SDK blocking calls with withContext(Dispatchers.IO).
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
…saging

Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
…ve config with cert

Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
@adietish
Copy link
Copy Markdown
Collaborator

adietish commented May 4, 2026

Tested the Token option with Save configuration enabled:
Screen.Recording.2026-04-30.at.16.16.04.mov

There's Save Config Failed error.

Probably, this is something related to my local system.

@azatsarynnyy: Can you please error logs and your config (in private) so that I can try to replicate?

Add support for both file paths and base64 data in certificate fields.
Kubeconfig can use either certificate-authority-data (base64) or
certificate-authority (file path). Same for client-certificate and
client-key.

Changes:

Data model:
- Add CertificateSource to track value, format (path vs data), and
  modification state
- Auto-detect input type (path vs base64/PEM) in fromUserInput()
- Expand ~ to absolute paths when storing

Kubeconfig support:
- KubeConfigCluster: use CertificateSource for certificateAuthority
- KubeConfigUser: use CertificateSource for clientCertificate/clientKey
- Read both -data and path fields when loading
- Write correct field type when saving (preserve original format)
- Cluster data class updated with CertificateSource fields

SSL context:
- OpenShiftClientFactory: add resolveCertificateSource() to read files
- createTrustManager/createKeyManagers accept CertificateSource
- Read file content when isFilePath=true before parsing
- Deprecated old CharArray-based methods for backward compatibility

UI:
- Add Browse buttons to Certificate Authority, Client Certificate,
  Client Key fields
- Auto-detect whether user entered path or data
- Display certificate values from loaded configs (both formats)
- Remove "(PEM)" from field labels (now format-agnostic)

This allows connecting to clusters like minikube that use file paths
in kubeconfig instead of embedded base64 data.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
@adietish adietish self-requested a review May 4, 2026 22:26
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.

7 participants