Skip to content

Conversation

aarora79
Copy link
Contributor

@aarora79 aarora79 commented Sep 6, 2025

Summary

  • Fix nginx service to properly include servers with expired authentication tokens
  • Implement comprehensive health check ping fallback mechanism
  • Add HealthStatus enum with Pydantic model for type-safe status management
  • Update React frontend to display "Healthy (Auth Expired)" status with appropriate styling
  • Replace hardcoded status strings throughout codebase with constants
  • Update AI coding assistants documentation with token refresh service integration

Problem

The health check ping fallback was working correctly - when authentication failed (401), the system would fall back to a ping check without auth to determine if the server was reachable. However, services with "healthy-auth-expired" status were being excluded from the nginx configuration because the logic only included servers with status exactly equal to "healthy".

Solution

Core Fixes

  • Nginx Service Logic: Updated to include both "healthy" and "healthy-auth-expired" statuses using HealthStatus.is_healthy() method
  • Constants Refactoring: Created comprehensive HealthStatus enum to replace hardcoded strings throughout the codebase
  • Type Safety: Used Pydantic model approach for better maintainability

Frontend Updates

  • Status Display: Added orange styling and "Healthy (Auth Expired)" text for the new status
  • TypeScript Interfaces: Updated all Server interfaces to include the new status type
  • Status Indicators: Added appropriate visual indicators (orange check icon, orange status dot)

Documentation Updates

  • AI Coding Assistants: Fixed Roo Code setup instructions and added comprehensive token refresh service integration
  • Professional Appearance: Removed emojis and streamlined multi-gateway support section

Testing

  • ✅ React frontend builds successfully without TypeScript errors
  • ✅ Services with expired auth tokens are now included in nginx configuration
  • ✅ UI properly displays "Healthy (Auth Expired)" status with orange styling
  • ✅ All hardcoded status strings replaced with type-safe constants

Files Changed

Backend:

  • registry/constants.py (new) - HealthStatus enum with Pydantic model
  • registry/core/nginx_service.py - Fixed inclusion logic for expired auth services
  • registry/health/service.py - Replaced hardcoded strings with constants

Frontend:

  • frontend/src/components/ServerCard.tsx - Added new status support and styling
  • frontend/src/pages/Dashboard.tsx - Updated Server interface
  • frontend/src/hooks/useServerStats.ts - Updated Server interface

Documentation:

  • docs/ai-coding-assistants-setup.md - Enhanced with token refresh integration
  • docs/auth.md - Added token refresh service references
  • docs/jwt-token-vending.md - Added integration documentation
  • docs/token-refresh-service.md (new) - Comprehensive token refresh documentation

aarora79 and others added 3 commits September 6, 2025 02:05
…er service

- Remove update_auth_tokens() function from build_and_run.sh to separate concerns
- Remove automatic token refresher startup from deployment script
- Add standalone token refresher service with MCP config generation
- Add token_refresher.pid to .gitignore
- Add support for no-auth services in token refresher alongside egress token services
- Clean up emoji usage in logging for better compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Add HealthStatus enum with Pydantic model for type-safe status management
- Fix nginx service to include services with expired auth tokens
- Update React frontend to display 'Healthy (Auth Expired)' status with orange styling
- Replace hardcoded status strings throughout codebase with constants
- Add comprehensive health check ping fallback for expired authentication
- Improve service availability by including reachable services regardless of auth status
- Fix Roo Code configuration file name to mcp_settings.json (with underscore)
- Add comprehensive token refresh service integration documentation
- Remove emojis for professional appearance
- Remove multi-gateway support section
- Add symbolic link setup option for automatic configuration updates
- Enhance troubleshooting with token refresh service specific guidance
List of (filepath, token_data) tuples for expiring tokens
"""
if not OAUTH_TOKENS_DIR.exists():
logger.error(f"OAuth tokens directory not found: {OAUTH_TOKENS_DIR}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 21 days ago

To remediate this security issue, we should avoid logging the full path of the OAuth tokens directory in cleartext. The best approach is to log a generic error message (e.g., "OAuth tokens directory not found") without including the potentially sensitive path. This change should be made only to the log statement in question, on line 149 within the _get_expiring_tokens function. No additional imports or code structure changes are required. Only the logging statement should be changed.


Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -146,7 +146,7 @@
         List of (filepath, token_data) tuples for expiring tokens
     """
     if not OAUTH_TOKENS_DIR.exists():
-        logger.error(f"OAuth tokens directory not found: {OAUTH_TOKENS_DIR}")
+        logger.error("OAuth tokens directory not found")
         return []
     
     current_time = time.time()
EOF
@@ -146,7 +146,7 @@
List of (filepath, token_data) tuples for expiring tokens
"""
if not OAUTH_TOKENS_DIR.exists():
logger.error(f"OAuth tokens directory not found: {OAUTH_TOKENS_DIR}")
logger.error("OAuth tokens directory not found")
return []

current_time = time.time()
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
os.rename(temp_path, config_file)
os.chmod(config_file, 0o600)

logger.info(f"Generated VS Code MCP config: {config_file}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 21 days ago

Sensitive information including the location and name of files containing tokens and credentials should not be logged at an INFO (or higher) level since logs may be accessed by users or services without a strict need-to-know. Here, logging the path to a generated config file within the .oauth-tokens directory at line 680 potentially exposes the location of sensitive files. The logging statement should be reworded to remove the sensitive file path.

Best practice fix:

  • Change the log message at line 680 to avoid including config_file (the full path).
  • The message can simply indicate success, e.g. "VS Code MCP config generated successfully".
  • If file path needs to be logged for troubleshooting, use DEBUG level (where logs are less likely to be exposed) and log a sanitized/abstracted version if possible.
  • No changes to program functionality.

File/Region to change:

  • credentials-provider/token_refresher.py — line 680

No imports or extra definitions are needed.


Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -677,7 +677,7 @@
         os.rename(temp_path, config_file)
         os.chmod(config_file, 0o600)
         
-        logger.info(f"Generated VS Code MCP config: {config_file}")
+        logger.info("VS Code MCP config generated successfully")
         logger.debug(f"VS Code config written to: {config_file.absolute()}")
         return True
         
EOF
@@ -677,7 +677,7 @@
os.rename(temp_path, config_file)
os.chmod(config_file, 0o600)

logger.info(f"Generated VS Code MCP config: {config_file}")
logger.info("VS Code MCP config generated successfully")
logger.debug(f"VS Code config written to: {config_file.absolute()}")
return True

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
os.chmod(config_file, 0o600)

logger.info(f"Generated VS Code MCP config: {config_file}")
logger.debug(f"VS Code config written to: {config_file.absolute()}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 21 days ago

To fix the issue, we should ensure that sensitive path information—such as the full path to credential files in the .oauth-tokens directory—is not logged at an INFO level, and preferably not at all. In this context, the log on line 681 (logger.debug(f"VS Code config written to: {config_file.absolute()}")) is at DEBUG, but the problematic INFO log is on line 680 (logger.info(f"Generated VS Code MCP config: {config_file}")). Both lines potentially leak path details.

The best fix is to avoid logging sensitive file paths. If confirmation of successful operation is still desired, either:

  • Only log a generic message (e.g., "VS Code MCP config generated successfully") without including the path; or
  • If including the file/location is absolutely necessary for debugging, limit this to DEBUG level and redact the sensitive part (e.g., replacing directory/usernames with <redacted> or only showing the filename, not the full path).

Specifically, update the logging statement(s) within the _generate_vscode_config function after writing the config file:

  • Change or remove the INFO log(s) that contain the config file path.
  • If feasible, leave a less specific INFO message, and only log the full path at DEBUG level (with a warning in the comment).
  • Optionally, if you must report the path at DEBUG, only show the filename portion: config_file.name.

Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -677,8 +677,8 @@
         os.rename(temp_path, config_file)
         os.chmod(config_file, 0o600)
         
-        logger.info(f"Generated VS Code MCP config: {config_file}")
-        logger.debug(f"VS Code config written to: {config_file.absolute()}")
+        logger.info("Generated VS Code MCP config.")  # File path omitted for security
+        logger.debug(f"VS Code config written to: {config_file.absolute()}")  # CAUTION: Reveals sensitive path
         return True
         
     except Exception as e:
EOF
@@ -677,8 +677,8 @@
os.rename(temp_path, config_file)
os.chmod(config_file, 0o600)

logger.info(f"Generated VS Code MCP config: {config_file}")
logger.debug(f"VS Code config written to: {config_file.absolute()}")
logger.info("Generated VS Code MCP config.") # File path omitted for security
logger.debug(f"VS Code config written to: {config_file.absolute()}") # CAUTION: Reveals sensitive path
return True

except Exception as e:
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
continue

config["mcpServers"][server_key] = server_config
logger.debug(f"Added no-auth service {server_key} to Roocode config")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.
This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 21 days ago

The best fix is to avoid logging user-controlled (and potentially sensitive) information unsanitized. In this case, rather than logging the raw server_key (which is derived from an untrusted path string), we should log only non-sensitive metadata or, if needed, a redacted/hashed representation. The minimal and safest fix, with no functional impact, is simply to remove the value from the log message, or replace it with a generic statement. Alternatively, if it is important to trace which services are added, we could log the fact that a service was added—perhaps logging the index number or a redacted/hashed summary. Since server_key comes from an untrusted source, and for this trace message its specific contents are not essential, the best way is simply to drop the {server_key} from the debug message.

Edit in credentials-provider/token_refresher.py:

  • On line 748, replace:
    logger.debug(f"Added no-auth service {server_key} to Roocode config")
    with:
    logger.debug("Added no-auth service to Roocode config")

No imports or new method definitions are required.


Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -745,7 +745,7 @@
                         continue
                     
                     config["mcpServers"][server_key] = server_config
-                    logger.debug(f"Added no-auth service {server_key} to Roocode config")
+                    logger.debug("Added no-auth service to Roocode config")
             
             # Write JSON to temp file
             json.dump(config, temp_file, indent=2)
EOF
@@ -745,7 +745,7 @@
continue

config["mcpServers"][server_key] = server_config
logger.debug(f"Added no-auth service {server_key} to Roocode config")
logger.debug("Added no-auth service to Roocode config")

# Write JSON to temp file
json.dump(config, temp_file, indent=2)
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
os.rename(temp_path, config_file)
os.chmod(config_file, 0o600)

logger.info(f"Generated Roocode MCP config: {config_file}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 21 days ago

To fix this issue, the code should avoid logging the full path to the generated .oauth-tokens/mcp.json config file at INFO level. Instead, you can:

  • Log only the filename, not the directory (e.g., "Generated Roocode MCP config as mcp.json"), or
  • Use a generic message such as "Generated Roocode MCP config" without mentioning the location.
    If precise debugging information (such as the full file path) is still needed for diagnostics, consider moving such details to the DEBUG level, assuming debug logs are only available in controlled environments.
    Edit file credentials-provider/token_refresher.py:
  • On line 757, change the log statement to avoid directly exposing the sensitive file path at INFO.
  • You may optionally preserve the full path in the DEBUG log (line 758) if needed.

No new imports or definitions are required.


Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -754,7 +754,7 @@
         os.rename(temp_path, config_file)
         os.chmod(config_file, 0o600)
         
-        logger.info(f"Generated Roocode MCP config: {config_file}")
+        logger.info("Generated Roocode MCP config successfully.")
         logger.debug(f"Roocode config written to: {config_file.absolute()}")
         return True
         
EOF
@@ -754,7 +754,7 @@
os.rename(temp_path, config_file)
os.chmod(config_file, 0o600)

logger.info(f"Generated Roocode MCP config: {config_file}")
logger.info("Generated Roocode MCP config successfully.")
logger.debug(f"Roocode config written to: {config_file.absolute()}")
return True

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
os.chmod(config_file, 0o600)

logger.info(f"Generated Roocode MCP config: {config_file}")
logger.debug(f"Roocode config written to: {config_file.absolute()}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 21 days ago

To address this issue, logging of the absolute path to the MCP config file should be avoided. Retain only log messages that do not include potentially sensitive information such as file system paths. You can keep a generic message (e.g., "Generated Roocode MCP config file.") or, if you wish to indicate location, only log the filename (not the absolute path), which removes most risk—though, even then, avoid logging any variable part of the path.

The required changes are:

  • Edit credentials-provider/token_refresher.py at line 758 to remove or redact the path information. You might log only the filename using config_file.name instead of .absolute(), or just omit the path entirely from the info-level log.
  • No extra imports are needed for this change.

Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -754,7 +754,7 @@
         os.rename(temp_path, config_file)
         os.chmod(config_file, 0o600)
         
-        logger.info(f"Generated Roocode MCP config: {config_file}")
+        logger.info("Generated Roocode MCP config file.")
         logger.debug(f"Roocode config written to: {config_file.absolute()}")
         return True
         
EOF
@@ -754,7 +754,7 @@
os.rename(temp_path, config_file)
os.chmod(config_file, 0o600)

logger.info(f"Generated Roocode MCP config: {config_file}")
logger.info("Generated Roocode MCP config file.")
logger.debug(f"Roocode config written to: {config_file.absolute()}")
return True

Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
force_refresh: If True, refresh all tokens regardless of expiration
"""
logger.info("Starting token refresh cycle...")
logger.debug(f"Token directory: {OAUTH_TOKENS_DIR.absolute()}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (password)
as clear text.

Copilot Autofix

AI 21 days ago

To fix the problem, we should avoid logging the full, absolute path of the token storage directory. Instead, log only non-sensitive, high-level information, such as the directory name or a generic statement indicating which operation is under way. If location information is essential for diagnosing errors, the code should provide a sanitized or truncated version of the path that does not reveal directory structure or user information.

Specifically for this code:

  • Remove or redact the log message at line 783 (logger.debug(f"Token directory: {OAUTH_TOKENS_DIR.absolute()}")).
  • If keeping the log message is valuable, use something generic and non-sensitive (e.g., "Token directory resolved" or "Token directory set (path not shown for security)"), or log just the directory name (OAUTH_TOKENS_DIR.name) rather than its absolute path.
  • No new imports are needed.

Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -780,7 +780,7 @@
         force_refresh: If True, refresh all tokens regardless of expiration
     """
     logger.info("Starting token refresh cycle...")
-    logger.debug(f"Token directory: {OAUTH_TOKENS_DIR.absolute()}")
+    logger.debug("Token directory set (path omitted for security).")
     
     # Find expiring tokens
     if force_refresh:
EOF
@@ -780,7 +780,7 @@
force_refresh: If True, refresh all tokens regardless of expiration
"""
logger.info("Starting token refresh cycle...")
logger.debug(f"Token directory: {OAUTH_TOKENS_DIR.absolute()}")
logger.debug("Token directory set (path omitted for security).")

# Find expiring tokens
if force_refresh:
Copilot is powered by AI and may make mistakes. Always verify output.
Unable to commit as this autofix suggestion is now outdated
logger.info("OAuth Token Refresher Service Starting")
logger.info(f"Check interval: {args.interval} seconds")
logger.info(f"Expiry buffer: {args.buffer} seconds ({args.buffer / 3600:.1f} hours)")
logger.info(f"OAuth tokens directory: {OAUTH_TOKENS_DIR}")

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs sensitive data (password) as clear text.

Copilot Autofix

AI 21 days ago

To fix this problem, the log entry at line 1026 should avoid exposing the full path to the .oauth-tokens directory. Instead, the code should log only a non-sensitive part, such as a generic label ("(path hidden)") or just the directory name, without revealing the parent directories.

The fix requires modifying only line 1026 in credentials-provider/token_refresher.py, changing the log message to avoid logging the full OAUTH_TOKENS_DIR path. For troubleshooting, you can log only the directory name (OAUTH_TOKENS_DIR.name), or a placeholder to indicate the token directory is configured. No new imports or method definitions are needed.


Suggested changeset 1
credentials-provider/token_refresher.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/credentials-provider/token_refresher.py b/credentials-provider/token_refresher.py
--- a/credentials-provider/token_refresher.py
+++ b/credentials-provider/token_refresher.py
@@ -1023,7 +1023,7 @@
     logger.info("OAuth Token Refresher Service Starting")
     logger.info(f"Check interval: {args.interval} seconds")
     logger.info(f"Expiry buffer: {args.buffer} seconds ({args.buffer / 3600:.1f} hours)")
-    logger.info(f"OAuth tokens directory: {OAUTH_TOKENS_DIR}")
+    logger.info("OAuth tokens directory is configured")
     logger.info("=" * 60)
     
     # Set up signal handlers and PID file for continuous mode
EOF
@@ -1023,7 +1023,7 @@
logger.info("OAuth Token Refresher Service Starting")
logger.info(f"Check interval: {args.interval} seconds")
logger.info(f"Expiry buffer: {args.buffer} seconds ({args.buffer / 3600:.1f} hours)")
logger.info(f"OAuth tokens directory: {OAUTH_TOKENS_DIR}")
logger.info("OAuth tokens directory is configured")
logger.info("=" * 60)

# Set up signal handlers and PID file for continuous mode
Copilot is powered by AI and may make mistakes. Always verify output.
@aarora79 aarora79 committed this autofix suggestion 21 days ago.
aarora79 and others added 2 commits September 6, 2025 11:27
…ensitive information

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
…ensitive information

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
@aarora79 aarora79 merged commit 84254ae into main Sep 6, 2025
4 of 12 checks passed
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.

1 participant