Skip to content

Conversation

bhcopeland
Copy link

Add --auth-token CLI option to include Bearer authentication in gRPC requests. Supports both command line argument and SSHX_AUTH_TOKEN environment variable.

This enables integration with authentication systems that require tokens to be passed in the Authorization header for both session creation and cleanup.

Add --auth-token CLI option to include Bearer authentication in gRPC requests.
Supports both command line argument and SSHX_AUTH_TOKEN environment variable.

This enables integration with authentication systems that require tokens
to be passed in the Authorization header for both session creation and cleanup.

Signed-off-by: Ben Copeland <[email protected]>
@bhcopeland
Copy link
Author

bhcopeland commented Jul 28, 2025

I see this fails CI. Since it only touches client code, it's good in its current form. However, if you want me to include another commit, I can add the Controller::new calls to include the auth_token. Thanks!

I have included a diff of the proposed fix:

-    let controller = Controller::new(&server.endpoint(), "", Runner::Echo, false).await?;
+    let controller = Controller::new(&server.endpoint(), "", Runner::Echo, false, &None).await?;
     controller.close().await?;
     Ok(())
 }
@@ -23,7 +23,7 @@ async fn test_handshake() -> Result<()> {
 async fn test_command() -> Result<()> {
     let server = TestServer::new().await;
     let runner = Runner::Shell("/bin/bash".into());
-    let mut controller = Controller::new(&server.endpoint(), "", runner, false).await?;
+    let mut controller = Controller::new(&server.endpoint(), "", runner, false, &None).await?;

     let session = server
         .state()
@@ -71,7 +71,7 @@ async fn test_ws_missing() -> Result<()> {
 async fn test_ws_basic() -> Result<()> {
     let server = TestServer::new().await;

-    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false).await?;
+    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false, &None).await?;
     let name = controller.name().to_owned();
     let key = controller.encryption_key().to_owned();
     tokio::spawn(async move { controller.run().await });
@@ -103,7 +103,7 @@ async fn test_ws_basic() -> Result<()> {
 async fn test_ws_resize() -> Result<()> {
     let server = TestServer::new().await;

-    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false).await?;
+    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false, &None).await?;
     let name = controller.name().to_owned();
     let key = controller.encryption_key().to_owned();
     tokio::spawn(async move { controller.run().await });
@@ -147,7 +147,7 @@ async fn test_ws_resize() -> Result<()> {
 async fn test_users_join() -> Result<()> {
     let server = TestServer::new().await;

-    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false).await?;
+    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false, &None).await?;
     let name = controller.name().to_owned();
     let key = controller.encryption_key().to_owned();
     tokio::spawn(async move { controller.run().await });
@@ -176,7 +176,7 @@ async fn test_users_join() -> Result<()> {
 async fn test_users_metadata() -> Result<()> {
     let server = TestServer::new().await;

-    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false).await?;
+    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false, &None).await?;
     let name = controller.name().to_owned();
     let key = controller.encryption_key().to_owned();
     tokio::spawn(async move { controller.run().await });
@@ -201,7 +201,7 @@ async fn test_users_metadata() -> Result<()> {
 async fn test_chat_messages() -> Result<()> {
     let server = TestServer::new().await;

-    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false).await?;
+    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, false, &None).await?;
     let name = controller.name().to_owned();
     let key = controller.encryption_key().to_owned();
     tokio::spawn(async move { controller.run().await });
@@ -234,7 +234,7 @@ async fn test_read_write_permissions() -> Result<()> {
     let server = TestServer::new().await;

     // create controller with read-only mode enabled
-    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, true).await?;
+    let mut controller = Controller::new(&server.endpoint(), "", Runner::Echo, true, &None).await?;
     let name = controller.name().to_owned();
     let key = controller.encryption_key().to_owned();
     let write_url = controller

@bhcopeland
Copy link
Author

@ekzhang I am not sure if you have any comments on this. Let me know, be good to get this upstreamed, otherwise I'll have to build sshx locally :).

@ekzhang
Copy link
Owner

ekzhang commented Aug 18, 2025

Ah yes this makes sense, we could do this. Technically self-hosting is not supported, but it seems like the bare minimum sshx could offer to help. Thanks for implementing!

@ekzhang
Copy link
Owner

ekzhang commented Aug 18, 2025

I should change the API a bit so it doesn't break CI, and also add validation to the server

@bhcopeland
Copy link
Author

@ekzhang, no problem. It would be awesome to have it upstreamed soon if possible! Yes, I understand. I'll leave it with you. Let me know if you want me to make any changes. Thanks for a great project!

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.

2 participants