Skip to content

fix: make reset-ubuntu script wrk with username/password - #62

Merged
aspectrr merged 8 commits into
mainfrom
aspectrr/remote-runner-creds
Feb 12, 2026
Merged

fix: make reset-ubuntu script wrk with username/password#62
aspectrr merged 8 commits into
mainfrom
aspectrr/remote-runner-creds

Conversation

@aspectrr

Copy link
Copy Markdown
Owner

Description

  • update some deploy scripts to use username and password for auth

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code style update (formatting, renaming)
  • Code refactor (no functional changes)
  • Configuration change
  • Test update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works

Release Notes

Labels

Copilot AI review requested due to automatic review settings February 11, 2026 04:17
@claude

claude Bot commented Feb 11, 2026

Copy link
Copy Markdown

Code Review: Password-based SSH Authentication Support

Thank you for this PR! I have reviewed the changes to add username/password authentication support to the deployment scripts.

Strengths

  1. Backwards Compatible: The changes gracefully fall back to key-based authentication when password credentials are not provided
  2. Clear Environment Variable Mapping: The SSH_PASSWORD to SSHPASS mapping is well-documented in the code
  3. Comprehensive Application: All SSH/SCP commands are consistently updated to use the new authentication method
  4. User Feedback: Good use of log messages to inform users when password-based auth is enabled

CRITICAL Security Concerns

1. StrictHostKeyChecking Disabled (Line 81 in run-on-remotes.sh)

The PR automatically disables host key verification when using password auth:

SSH_OPTS="$SSH_OPTS -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"

This makes connections vulnerable to MITM attacks - a significant security regression.

Recommendation: Remove this automatic disabling, add a warning log message, or use StrictHostKeyChecking=accept-new instead.

2. Password Exposure Risk

Storing passwords in environment variables (SSH_PASSWORD, SSHPASS) is less secure:

  • Can leak through process listings
  • Appear in logs and crash dumps
  • Exposed in Docker history

3. No Credential Validation

The script does not validate SSH_PASSWORD values before use.

Potential Issues

1. Missing Dependency Check

The code assumes sshpass is available but does not verify installation. Add a check:

if [[ -n "${SSHPASS:-}" ]]; then
    if ! command -v sshpass &> /dev/null; then
        log_error "sshpass required but not installed"
        exit 1
    fi
fi

2. Host Parsing Logic

Lines 100-105 handle both user@host and bare host formats correctly, but this is implicit. Add a comment explaining the logic.

Code Quality Issues

1. Missing Documentation

  • No updates to scripts/README.md explaining SSH_USER and SSH_PASSWORD
  • Dockerfile comment mentions "optional" but does not explain when/why
  • No usage examples

2. Testing

No automated tests exist for these scripts. Consider:

  • Manual testing with various host formats
  • Test missing sshpass binary
  • Test both auth methods

Summary

This PR should NOT be merged as-is due to security implications.

Required Changes:

  1. Remove automatic StrictHostKeyChecking=no or add prominent warnings
  2. Add sshpass availability check
  3. Update README.md with usage examples and security warnings

Recommended Changes:

  • Add explanatory comments for host parsing
  • Add basic tests
  • Validate credential values

Next Steps

  1. Address StrictHostKeyChecking security concern
  2. Add documentation to scripts/README.md
  3. Add dependency check for sshpass
  4. Consider if password auth is truly necessary (key-based is more secure)

Let me know if you would like help with these changes!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the remote execution tooling used by the scripts/reset-ubuntu.Dockerfile workflow to support password-based SSH (via sshpass) and optional username overrides when deploying/running scripts on remote hosts.

Changes:

  • Add optional password-based SSH/SCP support to run-on-remotes.sh using sshpass when SSH_PASSWORD/SSHPASS is set.
  • Add SSH_USER override support to rewrite user@host targets when reading the hosts file.
  • Install sshpass and add placeholder SSH credential env vars in reset-ubuntu.Dockerfile.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
scripts/run-on-remotes.sh Adds ssh/scp command wrapping for password auth + user override while iterating hosts
scripts/reset-ubuntu.Dockerfile Installs sshpass and exposes optional env vars for the container entrypoint

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/run-on-remotes.sh Outdated
Comment on lines +79 to +84
if [[ -n "${SSHPASS:-}" ]]; then
log_info "Password-based SSH authentication enabled"
SSH_OPTS="$SSH_OPTS -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
SCP_CMD="sshpass -e scp"
SSH_CMD="sshpass -e ssh"
fi

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

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

If SSHPASS/SSH_PASSWORD is provided but sshpass is not installed on the machine running this script, the first scp/ssh attempt will fail with a generic copy/exec error. Add an early dependency check (e.g., command -v sshpass) when enabling password-based mode and emit a clear error before processing hosts.

Copilot uses AI. Check for mistakes.
Comment thread scripts/run-on-remotes.sh Outdated
Comment on lines +69 to +77
# Build SSH/SCP command prefixes based on env vars
SSH_OPTS="-o ConnectTimeout=5"
SCP_CMD="scp"
SSH_CMD="ssh"

# Map SSH_PASSWORD to SSHPASS (what sshpass -e reads)
if [[ -n "${SSH_PASSWORD:-}" ]] && [[ -z "${SSHPASS:-}" ]]; then
export SSHPASS="$SSH_PASSWORD"
fi

Copilot AI Feb 11, 2026

Copy link

Choose a reason for hiding this comment

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

This change introduces new environment variables (SSH_USER, SSH_PASSWORD/SSHPASS) that alter how hosts are targeted and how authentication works, but the script header/usage text still implies only user@host entries in the hosts file. Please document these env vars (and their precedence/behavior) in the script’s usage comments or scripts/README.md so users know how to invoke password mode safely.

Copilot uses AI. Check for mistakes.
@claude

claude Bot commented Feb 11, 2026

Copy link
Copy Markdown

Code Review

Thank you for this contribution! I've reviewed the changes to add username/password authentication support to the deployment scripts. Here's my feedback:

Security Concerns 🔒

CRITICAL - Password Exposure:

  1. Environment variable visibility (scripts/run-on-remotes.sh:85): The warning message acknowledges that credentials are visible in process environment, but this is a significant security risk. Any process on the system can read these environment variables.

  2. StrictHostKeyChecking=accept-new (scripts/run-on-remotes.sh:87): While this provides some MITM protection, it's still vulnerable on first connect. Consider adding a warning or documentation about the security implications.

  3. Dockerfile ENV declarations (scripts/reset-ubuntu.Dockerfile:10-11): ENV vars in Dockerfiles are baked into the image layers and can be extracted. While they default to empty strings here, the pattern could be misused.

Recommendations:

  • Document that password-based auth should only be used in trusted environments
  • Consider using SSH keys as the primary authentication method
  • If passwords must be used, suggest a secrets management solution (e.g., Docker secrets, vault)
  • Add a note in the PR description about when password auth is appropriate

Code Quality ✅

Good practices observed:

  • Proper validation that sshpass is installed before using it (scripts/run-on-remotes.sh:81-83)
  • Clear warning messages about security implications (scripts/run-on-remotes.sh:85)
  • Good documentation in comments explaining the SSH credential usage (scripts/reset-ubuntu.Dockerfile:6-9)
  • Proper handling of both SSH_PASSWORD and SSHPASS environment variables (scripts/run-on-remotes.sh:74-76)

Minor improvements:

  1. Unquoted variable expansion (scripts/run-on-remotes.sh:121, 133, 143, 154): The SCP_CMD and SSH_CMD variables should be evaluated, not quoted, since they contain the command prefix. This is actually correct, but could be clearer with a comment explaining why they're not quoted.

  2. User override logic (scripts/run-on-remotes.sh:106-112): The logic is correct, but could benefit from a test case or example in comments for edge cases like hosts without @ symbols.

Best Practices 📋

Documentation:

  • The inline comments are excellent (scripts/reset-ubuntu.Dockerfile:6-9, scripts/run-on-remotes.sh:106-108)
  • Consider adding a section in the README or deployment docs about when to use password vs. key-based auth

Error handling:

  • Good validation and error messages throughout
  • Consider adding a check to warn if both SSH_PASSWORD and SSH keys are configured

Testing 🧪

Missing:

  • No tests added for the new password authentication flow
  • Consider adding integration tests or at least documentation on how to test this manually

Suggested tests:

  • Test with SSH_USER set
  • Test with SSH_PASSWORD set
  • Test with both set
  • Test with neither set (fallback to key-based auth)
  • Test the user override logic with various host formats

Performance ⚡

No significant performance concerns. The changes are minimal and don't introduce any performance regressions.

Summary

The implementation is functionally sound and handles the password authentication use case well. The main concern is security - password-based authentication should be clearly documented as a last resort for specific deployment scenarios.

Before merging:

  1. Add documentation about when password auth is appropriate
  2. Consider adding security warnings in logs when password auth is used
  3. Add basic tests or testing documentation

Overall: Good work on the implementation and documentation. Address the security documentation concerns and this will be ready to merge! 👍

@claude

claude Bot commented Feb 11, 2026

Copy link
Copy Markdown

Code Review

This PR introduces several important improvements to the readonly VM access system, TUI user experience, and deployment scripts. Here's my detailed feedback:

✅ Strengths

1. Excellent Security Enhancement

  • Base64 encoding for sudo elevation (fluid/internal/readonly/prepare.go:78-81): Smart workaround for shell quoting issues with heredocs. This prevents command injection during the prepare process.
  • Restricted shell improvement (fluid/internal/readonly/shell.go:162-176): The login shell invocation via -c argument is properly handled, with comprehensive test coverage added.
  • Comprehensive test coverage (fluid/internal/readonly/shell_test.go:192-283): Excellent tests covering all invocation modes including precedence rules.

2. Outstanding UX Improvements

  • Progress reporting (fluid/internal/tui/messages.go:502-515, fluid/internal/tui/agent.go:2421-2432): The live progress display during source VM preparation is a huge UX win.
  • Auto read-only mode (fluid/internal/tui/agent.go:1814-1828): Automatically enabling read-only mode when operating on source VMs prevents accidental destructive operations. The manual override via Shift+Tab is a nice touch.
  • Enhanced status bar (fluid/internal/tui/logo.go:445-480): Showing source VM context and sandbox base image provides better situational awareness.
  • Mouse support (fluid/internal/tui/model.go:537-547, fluid/internal/tui/model.go:1683-1744): Scroll wheel support and proper mouse event filtering is well-implemented.

3. Improved Remote Deployment

  • Environment-based hosts (scripts/run-on-remotes.sh): Moving from file-based to environment variable-based host configuration is more container-friendly and secure.
  • Password authentication support: Adding user:password@host syntax provides flexibility for automated deployments.
  • DHCP lease flushing (scripts/reset-ubuntu.sh:1416-1426): Prevents IP conflicts when reusing deterministic MAC addresses - subtle but important fix.

4. Blog Post Visual Enhancements

The styled execution flow diagrams make the security model much more accessible.


⚠️ Issues & Concerns

1. Security: Base64 Sudo Wrapper (HIGH)

Location: fluid/internal/readonly/prepare.go:76-81

Issue: This bypasses all command validation and gives unrestricted sudo access. If an attacker can control the command parameter, they get root access.

Recommendation:

  • Add a comment explaining why this is safe (only used in prepare context with hardcoded commands)
  • Consider adding a validation layer or restricting which commands can be elevated
  • Document that this should NEVER be exposed to untrusted input

2. Missing Error Handling

Location: fluid/internal/readonly/prepare.go:104

Issue: Errors from usermod are silently ignored. If usermod fails, the user might have the wrong shell or home directory.

Recommendation: Log failures at minimum.

3. Remote Host Credential Security

Location: scripts/run-on-remotes.sh:1542-1548

Issue: Passwords via SSHPASS are risky - environment variables can leak via ps, /proc, logs.

Recommendation:

  • Document that password auth should only be used for initial setup
  • Recommend switching to key-based auth after first deployment
  • Consider using sshpass -f with a temporary file instead

4. File Handle Leak Potential

Location: scripts/run-on-remotes.sh:1501-1504

Issue: Temporary file is not cleaned up on error/exit.

Recommendation: Add trap for cleanup.

5. VM Service Remote IP Discovery

Location: fluid/internal/vm/service.go:1772-1788

Performance concern: Every RunSourceVMCommandWithCallback creates a new SSH connection. For frequently accessed source VMs, this is inefficient.

Recommendation: Consider caching remote managers or reusing connections.


🤔 Questions & Clarifications

  1. Test Coverage: Are there integration tests that verify the base64 sudo wrapper works correctly on actual VMs?

  2. Auto Read-Only Mode: What happens if an agent operation spans multiple source VMs? Does the auto read-only state get confused?

  3. Mouse Event Filter: The leaked SGR sequence filter (fluid/internal/tui/model.go:1691-1711) is clever. Is this a known bubbletea issue?

  4. DHCP Lease Flushing: Why delete lease files instead of using virsh net-update --command delete?


📋 Minor Suggestions

  1. Inconsistent nil checks: Some places check err != nil || code != 0, others just err != nil. Be consistent.

  2. Magic number: fluid/internal/readonly/prepare.go:71 has Total: 6 hardcoded. Consider deriving from the number of steps.

  3. Home directory: Document why the switch from /nonexistent to /var/empty was made.

  4. Blog post CSS: The inline styles are extensive (>400 lines). Consider extracting to a separate CSS file.

  5. Missing tests: The new GetCurrentSandboxBaseImage(), GetCurrentSourceVM(), and ClearAutoReadOnly() methods don't have tests.


🎯 Priority Recommendations

Before merging:

  1. Add security documentation for the base64 sudo wrapper
  2. Fix error handling in readonly prepare (log instead of ignore)
  3. Add trap for temp file cleanup in run-on-remotes.sh

Follow-up tasks:

  1. Add integration tests for the prepare flow
  2. Consider caching remote managers for performance
  3. Document password auth security implications
  4. Extract blog post CSS to separate file

Summary

This is a high-quality PR with significant improvements to security, UX, and deployment automation. The code is well-structured, and the test coverage for the restricted shell changes is exemplary. The main concerns are around the sudo elevation wrapper (which needs documentation) and some minor error handling improvements. With the priority recommendations addressed, this is ready to merge.

Overall Rating: 8.5/10 ⭐

Great work on the auto read-only mode and progress reporting - these are exactly the kind of UX polish that makes tools delightful to use!

@claude

claude Bot commented Feb 11, 2026

Copy link
Copy Markdown

Code Review: PR #62 - Username/Password Auth for Deploy Scripts

Summary

This PR adds support for username/password authentication in deployment scripts and introduces comprehensive test coverage for the readonly preparation module. While the implementation is generally solid, there are critical security concerns that must be addressed before merging.

🔴 Critical Security Issues

1. SSH Public Key Exposure in Repository

File: scripts/ssh-users.conf

A real user's SSH public key (cpfeifer) is committed to the repository. While public keys are less sensitive than private keys, this still presents security and privacy concerns:

  • ❌ Real user identity and key fingerprint permanently exposed in git history
  • ❌ Attackers can identify which hosts this key has access to
  • ❌ Key revocation becomes problematic

Required Fix:

git rm --cached scripts/ssh-users.conf
# Create ssh-users.conf.example with dummy keys instead
# Users should create their own ssh-users.conf locally (already in .gitignore)

2. Hardcoded Default Password

Files: scripts/reset-ubuntu.sh (line 208), scripts/setup-ubuntu.sh (line 254)

password: ubuntu
chpasswd: { expire: False }

The default password "ubuntu" is hardcoded and never expires.

Recommendation:

  • Use random generated passwords
  • Force password change on first login
  • Or better: use SSH key-only authentication

🟡 High Priority Issues

3. Error Handling in Deployment Scripts

File: scripts/reset-ubuntu.sh

Several critical operations use || true which silently ignores failures:

virsh net-start default || true  # Line 98

If the network fails to start, VMs won't get IPs, but the script continues silently.

Fix: Remove || true from critical operations and add proper error checking.

4. SSHD Restart May Disconnect Session

File: fluid/internal/readonly/prepare.go (line 184)

restartCmd := `systemctl restart sshd ...`

Restarting sshd during preparation will disconnect the current SSH session.

Recommendation: Use systemctl reload sshd instead of restart where possible.

5. Inconsistent Timeout Values

  • scripts/reset-ubuntu.sh: MAX_WAIT=180
  • scripts/setup-ubuntu.sh: MAX_WAIT=120

Fix: Standardize timeout values or make them configurable.

✅ Excellent Work

Test Coverage

The new test files are exemplary:

  • 663 lines of comprehensive tests in prepare_test.go
  • 470+ lines of security bypass tests in shell_test.go
  • ✅ Tests cover: base64 wrapping, progress reporting, failure scenarios, context cancellation
  • ✅ Excellent mock infrastructure

This is exactly what the project's AGENTS.md requires. Great job!

Architecture & Design

  • ✅ Clean progress reporting architecture with PrepareProgress type
  • ✅ Well-documented security context for base64 sudo wrapping (lines 75-94)
  • ✅ Proper separation of setup auth (sudo) vs. runtime auth (readonly user)
  • ✅ Flexible credential format in run-on-remotes.sh (password vs. key-based)

🔧 Minor Improvements

6. Logger Creation in main.go

File: fluid/cmd/fluid/main.go (line 1354)

result, err := readonly.Prepare(ctx, sshRunFunc, string(caPubKey), nil, slog.Default())

Suggestion: Pass the existing logger from context instead of creating a new default logger.

7. SSH Key Type Assumption

File: scripts/entrypoint.sh (lines 9-14)

Assumes all keys are ed25519. Should auto-detect key type or use generic naming.

8. Missing Documentation

Need to document:

  • Security model for when to use passwords vs. keys
  • Secure credential storage recommendations
  • Why keys are added to both VM and host
  • SSH proxy jump usage

📊 Code Quality Metrics

  • Files Changed: 19
  • Additions: 1,764 lines
  • Deletions: 128 lines
  • Test Coverage: Excellent (new tests added)
  • Security: ⚠️ Concerns identified

🎯 Verdict: Request Changes

Must Fix Before Merge:

  1. Remove real SSH public key from scripts/ssh-users.conf - create .example file
  2. Fix hardcoded "ubuntu" password or document as temporary
  3. Add error handling to critical operations in deployment scripts
  4. Add security warnings to documentation for password-based auth

After Fixes: The PR will be ready to merge. The code quality, test coverage, and architecture are solid. The authentication implementation is appropriate for its use case once security concerns are addressed.

💬 Questions

  1. Is the scripts/ssh-users.conf file supposed to be a template, or should it be in .gitignore entirely?
  2. Are the VMs created by these scripts intended to be temporary/ephemeral? This would affect password security requirements.
  3. Should we add parallel execution support for multi-host operations?

Great work on the comprehensive test coverage! 🎉


Note: The base64-encoded sudo commands in prepare.go are well-documented and appropriate for the trusted operator setup context. The security model is sound there.

@claude

claude Bot commented Feb 11, 2026

Copy link
Copy Markdown

PR Review: Make reset-ubuntu script work with username/password

This PR updates deployment scripts to support password-based SSH authentication and significantly improves the read-only VM preparation system with progress tracking, comprehensive testing, and better TUI integration.

Strengths

1. Excellent Test Coverage

  • 663 new test lines for prepare.go with comprehensive edge cases
  • 93 new test lines for shell.go covering security bypass attempts
  • Tests verify base64 encoding/decoding, command content, error handling, progress reporting
  • Shell tests include sophisticated bypass attempts (nested substitution, whitespace tricks, interpreter variants)
  • Strong security testing for the restricted shell validation

2. Security Improvements

  • Base64 encoding for sudo commands eliminates shell injection risks from complex heredocs and quotes
  • Well-documented security context explaining why base64 is used (lines 75-94 in prepare.go)
  • Comprehensive shell command blocking with extensive test coverage
  • Password handling via sshpass with proper SSHPASS cleanup after each host

3. Code Quality

  • Clear separation of concerns with ProgressFunc callback pattern
  • Idempotent preparation steps that can safely re-run
  • Excellent inline documentation explaining design decisions
  • Mock SSH runner with mutex protection for thread-safe testing

4. UX Improvements

  • Progress reporting during VM preparation (6 steps tracked)
  • Better error messages with context (stdout, stderr, exit codes)
  • Enhanced logging throughout the preparation flow
  • TUI integration with PrepareProgress messages

Areas for Improvement

1. Security Concerns

Critical: Password in Environment Variable
Line 130 in scripts/run-on-remotes.sh exports SSHPASS directly which is visible in /proc and process listings.
Recommendation: Use a temporary file with restricted permissions and sshpass -f instead.

SSH Host Key Verification
Line 118 uses StrictHostKeyChecking=accept-new which automatically accepts unknown host keys (MITM risk).
Recommendation: For production deployments, pre-populate known_hosts or document this security tradeoff.

2. Error Handling Issues

Silent Failures in reset-ubuntu.sh
Lines 92-98, 122-124 use || true which masks all errors, making debugging difficult.
Recommendation: Check specific error conditions or at least log failures.

Usermod Failure Logged as Warning
prepare.go lines 122-127 log usermod failures as warnings. If usermod fails, the user might have the wrong shell or home directory.
Recommendation: Consider this a critical error or verify the user shell/home afterward.

3. Code Style Issues

Inconsistent Variable Naming
Line 100 in run-on-remotes.sh uses local_remainder (lowercase) while other variables use UPPERCASE.

Magic Numbers
prepare.go line 71 hardcodes Total: 6 in multiple places.
Recommendation: Define const totalPrepareSteps = 6

Potential Issues

1. Race Condition in Mock SSH Runner

prepare_test.go lines 35-44: The m.responses map is accessed without a lock after releasing the mutex.
Fix: Keep the lock until after reading from m.responses

2. SSH_USERS_FILE Parsing

reset-ubuntu.sh lines 217-229 assume format: username publickey.
If a line contains only a username (no space), pubkey will equal username.
Recommendation: Validate that pubkey looks like a valid SSH key before adding.

3. MAC Address Collision

reset-ubuntu.sh lines 287-290: VM_INDEX 1-255 will have identical MAC prefixes.
Only becomes unique at VM_INDEX 256+. Impact is low but should be documented.

Recommendations

High Priority

  1. Fix password exposure: Use sshpass -f with temporary file instead of environment variable
  2. Review SSH host key handling: Document security tradeoffs or tighten for production
  3. Fix mock race condition: Extend mutex lock to cover m.responses access

Medium Priority

  1. Make usermod failure a critical error or add verification
  2. Add validation for SSH_USERS_FILE format
  3. Extract magic number (6 steps) to a constant

Low Priority

  1. Improve error handling in reset-ubuntu.sh
  2. Standardize bash variable naming
  3. Add script header documentation

Summary

Overall Assessment: Approve with suggestions

This is a solid PR that significantly improves the codebase with excellent test coverage and good documentation. The security concerns around password handling and SSH host key verification should be addressed, but they do not block the merge since this is for deployment scripts (not production runtime).

The test suite is particularly impressive with comprehensive coverage of edge cases and security scenarios for the restricted shell. The progress tracking and TUI integration are clean additions.

Impact: Medium (improves deployment workflow and VM preparation)
Risk: Low (well-tested, mainly affects initial setup)
Code Quality: High (good tests, documentation, structure)

Great work!

@aspectrr
aspectrr merged commit c9a4fb5 into main Feb 12, 2026
7 checks passed
@claude

claude Bot commented Feb 12, 2026

Copy link
Copy Markdown

Pull Request Review

Summary

This PR updates deployment scripts to support username/password authentication alongside SSH key-based auth, and adds comprehensive test coverage for the readonly VM preparation flow. The changes also include UI improvements for TUI progress reporting and mouse wheel scrolling.


✅ Strengths

1. Excellent Test Coverage

  • Added 663 lines of comprehensive tests in prepare_test.go
  • Tests cover both success and failure scenarios
  • Mock SSH runner is well-designed for testing

2. Security Improvements

  • Smart sudo wrapper: Commands are now base64-encoded and executed via sudo wrapper (lines 59-72 in prepare.go)
  • This prevents shell injection attacks in the prepare flow
  • Proper separation of concerns between operator credentials and fluid-readonly user

3. Better Progress Reporting

  • Added PrepareProgress callback mechanism
  • TUI can now show inline progress during VM preparation
  • Improves user experience significantly

4. Script Flexibility

  • run-on-remotes.sh now supports both password auth (via sshpass) and key-based auth
  • Per-host credential parsing is clean and well-documented
  • Good use of environment variables for sensitive data

5. All CI Checks Passing

  • Fluid CLI: SUCCESS
  • Python SDK: SUCCESS
  • Web Frontend: SUCCESS
  • Landing Page: SUCCESS
  • GitGuardian Security: SUCCESS

⚠️ Issues & Concerns

🔴 Critical: Password Exposure Risk

Location: scripts/run-on-remotes.sh:130-132

export SSHPASS="$HOST_PASS"
SCP_CMD="sshpass -e scp"
SSH_CMD="sshpass -e ssh"

Issue: While SSHPASS is cleared at line 180, if the script exits unexpectedly (signals, errors before cleanup), the password remains in the environment.

Recommendation: Use a trap to ensure cleanup:

cleanup_sshpass() {
    unset SSHPASS
}
trap cleanup_sshpass EXIT INT TERM

🟡 Medium: Incomplete Error Handling

Location: fluid/internal/readonly/prepare.go:68-72

encoded := base64.StdEncoding.EncodeToString([]byte(command))
wrappedCmd := fmt.Sprintf("echo '%s' | base64 -d | sudo bash", encoded)
return origRun(ctx, wrappedCmd)

Issues:

  1. No validation that command is non-empty
  2. If base64 decode fails on the remote side, error may be unclear
  3. Assumes base64 and sudo are available on the target system

Recommendation: Add a comment explaining the requirements, or validate command is non-empty.

🟡 Medium: Missing Validation

Location: scripts/reset-ubuntu.sh:212-230

The script reads SSH users from a file but doesn't validate:

  • Public key format (could be malformed)
  • Username format (could contain shell metacharacters)
  • Line length limits

Recommendation: Add basic validation:

# Validate username (alphanumeric, dash, underscore only)
if \! [[ "$username" =~ ^[a-zA-Z0-9_-]+$ ]]; then
    log_error "Invalid username: $username"
    continue
fi

🟡 Medium: Hardcoded Timeouts

Location: scripts/reset-ubuntu.sh:314-316

MAX_WAIT=180
WAIT_INTERVAL=5

These should be configurable via environment variables for CI/testing scenarios where VMs might take longer.

🟢 Minor: Documentation Gap

Location: fluid/internal/readonly/prepare.go:59-72

The sudo wrapper is a critical security feature but lacks detailed documentation explaining:

  • Why base64 encoding is needed
  • Security implications
  • What happens if sudo requires a password

Recommendation: Add a detailed comment block explaining the security model.

🟢 Minor: Inconsistent Error Handling

Location: scripts/reset-ubuntu.sh

Some commands use || true to ignore errors, others don't. This makes it unclear which failures are expected/acceptable.

Example (line 93):

virsh net-define /usr/share/libvirt/networks/default.xml || true

Recommendation: Add comments explaining why failures are acceptable in specific cases.

🟢 Minor: Missing Type Check

Location: fluid/internal/readonly/prepare.go:111

The function signature now includes logger *slog.Logger but there's no nil check. If nil is passed, it will panic on first use.

Recommendation: Either:

  1. Document that logger must not be nil, OR
  2. Add nil check: if logger == nil { logger = slog.Default() }

📋 Best Practices & Style

✅ Good Practices Followed:

  • Clear variable names and comments
  • Proper use of colors in shell output
  • Trap handlers for cleanup
  • Skip comments and empty lines in config files
  • Deterministic MAC addresses based on VM index

Suggestions:

  1. Shell Scripts: Consider using shellcheck in CI
  2. Go Code: The prepare.go changes are well-structured
  3. Testing: Great job on comprehensive test coverage!

🔒 Security Review

Positive:

  • ✅ Base64 encoding prevents shell injection in prepare flow
  • ✅ Proper SSH key permissions (600)
  • ✅ GitGuardian security checks passing
  • ✅ No hardcoded credentials in code

Concerns:

  • ⚠️ Password handling in run-on-remotes.sh needs trap cleanup
  • ⚠️ No validation of SSH public key format
  • ⚠️ Consider documenting threat model for password auth

🧪 Testing Recommendations

  1. Test password cleanup: Verify SSHPASS is cleared even on script failure
  2. Test malformed inputs: Try invalid usernames/keys in ssh-users.conf
  3. Test sudo failures: What happens if sudo requires a password?
  4. Test network timeouts: Verify graceful handling when VMs don't get IPs

📝 Documentation

The PR description says "update some deploy scripts to use username and password for auth" but:

  • ✅ README updates would be helpful
  • ✅ Consider documenting when to use password vs key auth
  • ✅ Document security implications of password auth

✅ Approval Recommendation

Status: Approve with minor changes recommended

The PR is well-implemented with good test coverage and passes all CI checks. The critical password exposure issue should be fixed before merge, but the code is otherwise production-ready.

Priority Fixes:

  1. 🔴 Add trap cleanup for SSHPASS in run-on-remotes.sh
  2. 🟡 Add nil check for logger parameter or document requirement
  3. 🟡 Validate SSH username format in reset-ubuntu.sh

Nice-to-Have:

  • Add shellcheck to CI for bash scripts
  • Document security model for password auth
  • Make timeouts configurable via env vars

Great work on this PR! The test coverage is excellent and the security model is well-thought-out. 🎉

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