Skip to content

Add db save-password command with role support#60

Merged
cevian merged 4 commits intomainfrom
add-save-password-env-and-interactive
Oct 18, 2025
Merged

Add db save-password command with role support#60
cevian merged 4 commits intomainfrom
add-save-password-env-and-interactive

Conversation

@cevian
Copy link
Contributor

@cevian cevian commented Oct 15, 2025

NOTE: THIS INCLUDES A BREAKING CHANGE TO PASSWORD STORAGE

Summary

  • Implements new tiger db save-password command to save database passwords
  • Adds support for storing passwords for different database roles independently
  • Provides three password input methods with clear precedence

Changes

New Features

  • save-password command: New command under tiger db to save passwords to configured storage
  • Role-based storage: Support for storing passwords per database role (tsdbadmin, readonly, custom roles)
  • Multiple input methods:
    1. --password=value flag (highest precedence)
    2. TIGER_NEW_PASSWORD environment variable
    3. Interactive prompt (when neither provided)

Implementation Details

  • Modified password storage interface to include role parameter
  • Updated all storage backends (KeyringStorage, PgpassStorage, NoStorage) with role support
  • Added comprehensive test coverage for all input methods and storage backends
  • Updated spec documentation to reflect the new command and its behavior

Examples

# Save password with explicit value
tiger db save-password svc-12345 --password=mypass

# Save password for custom role
tiger db save-password svc-12345 --password=mypass --role readonly

# Use environment variable
export TIGER_NEW_PASSWORD=mypass
tiger db save-password svc-12345

# Interactive prompt
tiger db save-password svc-12345
Enter password: <user types password>

Test plan

  • All existing tests pass
  • New tests for save-password command with explicit password
  • New tests for save-password with environment variable
  • New tests for interactive password prompt
  • New tests for custom roles
  • New tests for different storage backends (keyring, pgpass)
  • Error handling tests (no auth, no service ID, empty password)

🤖 Generated with Claude Code

}

return fmt.Sprintf("password-%s-%s", *service.ProjectId, *service.ServiceId), nil
return fmt.Sprintf("password-%s-%s-%s", *service.ProjectId, *service.ServiceId, role), nil
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the cause of the breaking change

@cevian cevian force-pushed the add-save-password-env-and-interactive branch from f94d52f to 5364139 Compare October 16, 2025 12:03
Copy link
Member

@nathanjcochran nathanjcochran left a comment

Choose a reason for hiding this comment

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

Left a handful of comments/questions, but overall LGTM.

// Note: We don't fail the service creation if password saving fails
// The error is handled by displaying the appropriate message below
result, _ := password.SavePasswordWithResult(service, initialPassword)
result, _ := password.SavePasswordWithResult(service, initialPassword, "tsdbadmin")
Copy link
Member

@nathanjcochran nathanjcochran Oct 17, 2025

Choose a reason for hiding this comment

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

Not a big deal, but tsdbadmin is hard-coded in several places now. Might be worth making a constant at some point? Doesn't have to be now, just a thought.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ill do this in a diff pr

Comment on lines +357 to +363
if role == "" {
return PasswordStorageResult{
Success: false,
Method: "none",
Message: "Role is required",
}, fmt.Errorf("role is required")
}
Copy link
Member

Choose a reason for hiding this comment

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

I think this check is duplicative, as I think all of the storage.Save (called below) methods do the same validation 🤷‍♂️.

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'd rather keep this for safety as it never makes sense to save without a role

cevian and others added 4 commits October 18, 2025 21:01
…e-password spec

Update the save-password command specification to support:
- TIGER_NEW_PASSWORD environment variable (used when --password flag not provided)
- Interactive password prompt when --password flag provided with no value
- Clear precedence: explicit flag value → interactive prompt → env var

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

Co-Authored-By: Claude <noreply@anthropic.com>
Implement role-based password storage to support storing passwords
for different database roles (tsdbadmin, readonly, custom roles, etc.)
independently. This enables users to manage multiple credentials per
service for different database users.

Key changes:
- Add role parameter to PasswordStorage interface (Save, Get, Remove)
- Update KeyringStorage to use role in keyring keys
- Update PgpassStorage to store role in pgpass entries
- Update all callers in cmd, mcp, and password packages
- Add comprehensive tests including mixed-case role names
- Verify role isolation (different roles store passwords independently)

All tests pass.

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

Co-Authored-By: Claude <noreply@anthropic.com>
Add new command to save database passwords with support for different
database roles. Passwords can be provided via three methods:
1. --password=value flag (highest precedence)
2. TIGER_NEW_PASSWORD environment variable
3. Interactive prompt (when neither provided)

The command stores passwords according to the --password-storage
setting (keyring, pgpass, or none) and supports saving passwords
for different database roles independently.

Features:
- Save passwords for any database role (default: tsdbadmin)
- Three input methods with clear precedence
- Integration with existing password storage system
- Comprehensive test coverage for all input methods

Example usage:
  tiger db save-password svc-12345 --password=mypass
  tiger db save-password svc-12345 --role readonly
  tiger db save-password svc-12345  # prompts interactively

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

Co-Authored-By: Claude <noreply@anthropic.com>
- Add -p short flag for --password option
- Use term.ReadPassword instead of bufio.Scanner for secure password input
- Add TTY check before interactive prompt to fail gracefully in non-terminal environments
- Scope err variable to conditional block for cleaner code
- Output status messages to stderr instead of stdout for consistency
- Make TTY check and password reading testable via function variables
- Update tests to mock terminal behavior without requiring actual TTY
- Move TIGER_NEW_PASSWORD documentation from global to save-password section

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

Co-Authored-By: Claude <noreply@anthropic.com>
@cevian cevian force-pushed the add-save-password-env-and-interactive branch from f9a5bf0 to 221ce14 Compare October 18, 2025 19:05
@cevian cevian merged commit d1d53a8 into main Oct 18, 2025
2 checks passed
@cevian cevian deleted the add-save-password-env-and-interactive branch October 18, 2025 19:21
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.

3 participants