diff --git a/test_secret_manager.sh b/test_secret_manager.sh index 3369470..9a2eb1c 100755 --- a/test_secret_manager.sh +++ b/test_secret_manager.sh @@ -21,6 +21,7 @@ export GODEBUG="berlin.sneak.pkg.secret" echo -e "${BLUE}=== Secret Manager Comprehensive Test Script ===${NC}" echo -e "${YELLOW}Using temporary directory: $TEMP_DIR${NC}" echo -e "${YELLOW}Debug output enabled: GODEBUG=$GODEBUG${NC}" +echo -e "${YELLOW}Note: All tests use environment variables (no manual input)${NC}" # Function to print test steps print_step() { @@ -102,7 +103,6 @@ echo " SB_SECRET_MNEMONIC=$TEST_MNEMONIC" # Test 2: Initialize the secret manager (should create default vault) print_step "2" "Initializing secret manager (creates default vault)" -# Set passphrase for init command only export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" echo "Running: $SECRET_BINARY init" if $SECRET_BINARY init; then @@ -110,7 +110,6 @@ if $SECRET_BINARY init; then else print_error "Failed to initialize secret manager" fi -# Unset passphrase after init unset SB_UNLOCK_PASSPHRASE # Verify directory structure was created @@ -172,13 +171,14 @@ else print_error "Failed to switch to 'work' vault" fi -# Test 4: Import functionality with different environment variable combinations -print_step "4" "Testing import functionality with different environment variable combinations" +# Test 4: Import functionality with environment variable combinations +print_step "4" "Testing import functionality with environment variable combinations" -# Test 4a: Import with mnemonic env var set, no passphrase env var -echo -e "\n${YELLOW}Test 4a: Import with SB_SECRET_MNEMONIC set, SB_UNLOCK_PASSPHRASE unset${NC}" +# Test 4a: Import with both env vars set (typical usage) +echo -e "\n${YELLOW}Test 4a: Import with both SB_SECRET_MNEMONIC and SB_UNLOCK_PASSPHRASE set${NC}" reset_state export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" +export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" # Create a vault first echo "Running: $SECRET_BINARY vault create test-vault" @@ -188,95 +188,17 @@ else print_error "Failed to create test-vault" fi -# Import should prompt for passphrase -echo "Importing with mnemonic env var set, should prompt for passphrase..." -echo "Running: echo \"$TEST_PASSPHRASE\" | $SECRET_BINARY vault import test-vault" -if echo "$TEST_PASSPHRASE" | $SECRET_BINARY vault import test-vault; then - print_success "Import succeeded with mnemonic env var (prompted for passphrase)" -else - print_error "Import failed with mnemonic env var" -fi - -# Test 4b: Import with passphrase env var set, no mnemonic env var -echo -e "\n${YELLOW}Test 4b: Import with SB_UNLOCK_PASSPHRASE set, SB_SECRET_MNEMONIC unset${NC}" -reset_state -export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" - -# Create a vault first -echo "Running: $SECRET_BINARY vault create test-vault2" -if $SECRET_BINARY vault create test-vault2; then - print_success "Created test-vault2 for import testing" -else - print_error "Failed to create test-vault2" -fi - -# Import should prompt for mnemonic -echo "Importing with passphrase env var set, should prompt for mnemonic..." -echo "Running: echo \"$TEST_MNEMONIC\" | $SECRET_BINARY vault import test-vault2" -if echo "$TEST_MNEMONIC" | $SECRET_BINARY vault import test-vault2; then - print_success "Import succeeded with passphrase env var (prompted for mnemonic)" -else - print_error "Import failed with passphrase env var" -fi - -# Test 4c: Import with both env vars set -echo -e "\n${YELLOW}Test 4c: Import with both SB_SECRET_MNEMONIC and SB_UNLOCK_PASSPHRASE set${NC}" -reset_state -export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" -export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" - -# Create a vault first -echo "Running: $SECRET_BINARY vault create test-vault3" -if $SECRET_BINARY vault create test-vault3; then - print_success "Created test-vault3 for import testing" -else - print_error "Failed to create test-vault3" -fi - -# Import should not prompt for anything -echo "Importing with both env vars set, should not prompt..." -echo "Running: $SECRET_BINARY vault import test-vault3" -if $SECRET_BINARY vault import test-vault3; then - print_success "Import succeeded with both env vars (no prompts)" +# Import should work without prompts +echo "Importing with both env vars set (automated)..." +echo "Running: $SECRET_BINARY vault import test-vault" +if $SECRET_BINARY vault import test-vault; then + print_success "Import succeeded with both env vars (automated)" else print_error "Import failed with both env vars" fi -# Test 4d: Import with neither env var set -echo -e "\n${YELLOW}Test 4d: Import with neither SB_SECRET_MNEMONIC nor SB_UNLOCK_PASSPHRASE set${NC}" -reset_state - -# Create a vault first -echo "Running: $SECRET_BINARY vault create test-vault4" -if $SECRET_BINARY vault create test-vault4; then - print_success "Created test-vault4 for import testing" -else - print_error "Failed to create test-vault4" -fi - -# Import should prompt for both mnemonic and passphrase -echo "Importing with neither env var set, should prompt for both..." -if expect -c " - spawn $SECRET_BINARY vault import test-vault4 - expect \"Enter your BIP39 mnemonic phrase:\" - send \"$TEST_MNEMONIC\n\" - expect \"Enter passphrase for unlock key:\" - send \"$TEST_PASSPHRASE\n\" - expect \"Confirm passphrase:\" - send \"$TEST_PASSPHRASE\n\" - expect eof -"; then - print_success "Import succeeded with no env vars (prompted for both)" -else - print_error "Import failed with no env vars" -fi - -# Test 4e: Import into non-existent vault (should fail) -echo -e "\n${YELLOW}Test 4e: Import into non-existent vault (should fail)${NC}" -reset_state -export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" -export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" - +# Test 4b: Import into non-existent vault (should fail) +echo -e "\n${YELLOW}Test 4b: Import into non-existent vault (should fail)${NC}" echo "Importing into non-existent vault (should fail)..." if $SECRET_BINARY vault import nonexistent-vault; then print_error "Import should have failed for non-existent vault" @@ -284,22 +206,20 @@ else print_success "Import correctly failed for non-existent vault" fi -# Test 4f: Import with invalid mnemonic (should fail) -echo -e "\n${YELLOW}Test 4f: Import with invalid mnemonic (should fail)${NC}" -reset_state +# Test 4c: Import with invalid mnemonic (should fail) +echo -e "\n${YELLOW}Test 4c: Import with invalid mnemonic (should fail)${NC}" export SB_SECRET_MNEMONIC="invalid mnemonic phrase that should not work" -export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" # Create a vault first -echo "Running: $SECRET_BINARY vault create test-vault5" -if $SECRET_BINARY vault create test-vault5; then - print_success "Created test-vault5 for invalid mnemonic testing" +echo "Running: $SECRET_BINARY vault create test-vault2" +if $SECRET_BINARY vault create test-vault2; then + print_success "Created test-vault2 for invalid mnemonic testing" else - print_error "Failed to create test-vault5" + print_error "Failed to create test-vault2" fi echo "Importing with invalid mnemonic (should fail)..." -if $SECRET_BINARY vault import test-vault5; then +if $SECRET_BINARY vault import test-vault2; then print_error "Import should have failed with invalid mnemonic" else print_success "Import correctly failed with invalid mnemonic" @@ -309,67 +229,26 @@ fi reset_state export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" -# Test 5: Original import functionality test (using mnemonic-based) -print_step "5" "Testing original import functionality" +# Test 5: Unlock key management +print_step "5" "Testing unlock key management" # Initialize to create default vault -if (echo "$TEST_PASSPHRASE"; echo "$TEST_PASSPHRASE") | $SECRET_BINARY init; then - print_success "Initialized for Step 5 testing" -else - print_error "Failed to initialize for Step 5 testing" -fi - -# Create work vault for import testing -echo "Running: $SECRET_BINARY vault create work" -if $SECRET_BINARY vault create work; then - print_success "Created work vault for import testing" -else - print_error "Failed to create work vault" -fi - -# Switch to work vault -echo "Switching to 'work' vault..." -echo "Running: $SECRET_BINARY vault select work" -if $SECRET_BINARY vault select work; then - print_success "Switched to 'work' vault" -else - print_error "Failed to switch to 'work' vault" -fi - -# Import into work vault using mnemonic (should derive long-term key) -echo "Importing mnemonic into 'work' vault..." -# Set passphrase for import command only export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" -echo "Running: $SECRET_BINARY vault import work" -if $SECRET_BINARY vault import work; then - print_success "Imported mnemonic into 'work' vault" +if $SECRET_BINARY init; then + print_success "Initialized for unlock key testing" else - print_error "Failed to import mnemonic into 'work' vault" + print_error "Failed to initialize for unlock key testing" fi -# Unset passphrase after import -unset SB_UNLOCK_PASSPHRASE - -# Switch back to default vault -echo "Switching back to 'default' vault..." -echo "Running: $SECRET_BINARY vault select default" -if $SECRET_BINARY vault select default; then - print_success "Switched back to 'default' vault" -else - print_error "Failed to switch back to 'default' vault" -fi - -# Test 6: Unlock key management -print_step "6" "Testing unlock key management" # Create passphrase-protected unlock key echo "Creating passphrase-protected unlock key..." -# Note: This test uses stdin input instead of environment variable to test the traditional approach -echo "Running: echo \"$TEST_PASSPHRASE\" | $SECRET_BINARY keys add passphrase" -if echo "$TEST_PASSPHRASE" | $SECRET_BINARY keys add passphrase; then +echo "Running: $SECRET_BINARY keys add passphrase (with SB_UNLOCK_PASSPHRASE set)" +if $SECRET_BINARY keys add passphrase; then print_success "Created passphrase-protected unlock key" else print_error "Failed to create passphrase-protected unlock key" fi +unset SB_UNLOCK_PASSPHRASE # List unlock keys echo "Listing unlock keys..." @@ -382,8 +261,8 @@ else print_error "Failed to list unlock keys" fi -# Test 7: Secret management with mnemonic (keyless operation) -print_step "7" "Testing mnemonic-based secret operations (keyless)" +# Test 6: Secret management with mnemonic (keyless operation) +print_step "6" "Testing mnemonic-based secret operations (keyless)" # Add secrets using mnemonic (no unlock key required) echo "Adding secrets using mnemonic-based long-term key..." @@ -461,8 +340,8 @@ else print_error "Failed to list secrets" fi -# Test 8: Secret management without mnemonic (traditional unlock key approach) -print_step "8" "Testing traditional unlock key approach" +# Test 7: Secret management without mnemonic (traditional unlock key approach) +print_step "7" "Testing traditional unlock key approach" # Temporarily unset mnemonic to test traditional approach unset SB_SECRET_MNEMONIC @@ -478,7 +357,9 @@ fi # Retrieve secret using traditional unlock key approach echo "Retrieving secret using traditional unlock key approach..." -RETRIEVED_TRADITIONAL=$(echo "$TEST_PASSPHRASE" | $SECRET_BINARY get "traditional/secret" 2>/dev/null) +export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" +RETRIEVED_TRADITIONAL=$($SECRET_BINARY get "traditional/secret" 2>/dev/null) +unset SB_UNLOCK_PASSPHRASE if [ "$RETRIEVED_TRADITIONAL" = "traditional-secret-value" ]; then print_success "Retrieved and verified traditional secret: traditional/secret" else @@ -488,25 +369,8 @@ fi # Re-enable mnemonic for remaining tests export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" -# Test 9: Advanced unlock key management -print_step "9" "Testing advanced unlock key management" - -# Re-enable mnemonic for key operations -export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" - -# Create PGP unlock key (if GPG is available) -echo "Testing PGP unlock key creation..." -if command -v gpg >/dev/null 2>&1; then - # This would require a GPG key ID - for testing we'll just check the command exists - echo "Running: $SECRET_BINARY keys add pgp --help" - if $SECRET_BINARY keys add pgp --help; then - print_success "PGP unlock key command available" - else - print_warning "PGP unlock key command not yet implemented" - fi -else - print_warning "GPG not available for PGP unlock key testing" -fi +# Test 8: Advanced unlock key management +print_step "8" "Testing advanced unlock key management" # Test Secure Enclave (macOS only) if [[ "$OSTYPE" == "darwin"* ]]; then @@ -540,8 +404,8 @@ if $SECRET_BINARY keys list; then fi fi -# Test 10: Secret name validation and edge cases -print_step "10" "Testing secret name validation and edge cases" +# Test 9: Secret name validation and edge cases +print_step "9" "Testing secret name validation and edge cases" # Test valid names VALID_NAMES=("valid-name" "valid.name" "valid_name" "valid/path/name" "123valid" "a" "very-long-name-with-many-parts/and/paths") @@ -566,8 +430,8 @@ for name in "${INVALID_NAMES[@]}"; do fi done -# Test 11: Overwrite protection and force flag -print_step "11" "Testing overwrite protection and force flag" +# Test 10: Overwrite protection and force flag +print_step "10" "Testing overwrite protection and force flag" # Try to add existing secret without --force (should fail) echo "Running: echo \"new-value\" | $SECRET_BINARY add \"database/password\"" @@ -593,8 +457,28 @@ else print_error "Force overwrite failed - secret not overwritten with --force" fi -# Test 12: Cross-vault operations -print_step "12" "Testing cross-vault operations" +# Test 11: Cross-vault operations +print_step "11" "Testing cross-vault operations" + +# First create and import mnemonic into work vault since it was destroyed by reset_state +echo "Creating work vault for cross-vault testing..." +echo "Running: $SECRET_BINARY vault create work" +if $SECRET_BINARY vault create work; then + print_success "Created work vault for cross-vault testing" +else + print_error "Failed to create work vault for cross-vault testing" +fi + +# Import mnemonic into work vault so it can store secrets +echo "Importing mnemonic into work vault..." +export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" +echo "Running: $SECRET_BINARY vault import work" +if $SECRET_BINARY vault import work; then + print_success "Imported mnemonic into work vault" +else + print_error "Failed to import mnemonic into work vault" +fi +unset SB_UNLOCK_PASSPHRASE # Switch to work vault and add secrets there echo "Switching to 'work' vault for cross-vault testing..." @@ -640,8 +524,8 @@ else print_error "Failed to switch back to 'default' vault" fi -# Test 13: File structure verification -print_step "13" "Verifying file structure" +# Test 12: File structure verification +print_step "12" "Verifying file structure" echo "Checking file structure in $TEMP_DIR..." if [ -d "$TEMP_DIR/vaults.d/default/secrets.d" ]; then @@ -689,8 +573,8 @@ else print_error "Current vault link not found" fi -# Test 14: Environment variable error handling -print_step "14" "Testing environment variable error handling" +# Test 13: Environment variable error handling +print_step "13" "Testing environment variable error handling" # Test with non-existent state directory export SB_SECRET_STATE_DIR="$TEMP_DIR/nonexistent/directory" @@ -702,49 +586,20 @@ else fi # Test init with non-existent directory (should work) -echo "Running: $SECRET_BINARY init" +echo "Running: $SECRET_BINARY init (with SB_UNLOCK_PASSPHRASE set)" +export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" if $SECRET_BINARY init; then print_success "Init works with non-existent state directory" else print_error "Init should work with non-existent state directory" fi +unset SB_UNLOCK_PASSPHRASE # Reset to working directory export SB_SECRET_STATE_DIR="$TEMP_DIR" -# Test 15: Unlock key removal -print_step "15" "Testing unlock key removal" - -# Re-enable mnemonic -export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" - -# Create another unlock key for testing removal -echo "Creating additional unlock key for removal testing..." -# Use stdin input instead of environment variable -echo "Running: echo \"another-passphrase\" | $SECRET_BINARY keys add passphrase" -if echo "another-passphrase" | $SECRET_BINARY keys add passphrase; then - print_success "Created additional unlock key" - - # Get the key ID and try to remove it - echo "Running: $SECRET_BINARY keys list" - if $SECRET_BINARY keys list; then - KEY_TO_REMOVE=$($SECRET_BINARY keys list | tail -n1 | awk '{print $1}') - if [ -n "$KEY_TO_REMOVE" ]; then - echo "Attempting to remove unlock key: $KEY_TO_REMOVE" - echo "Running: $SECRET_BINARY keys rm $KEY_TO_REMOVE" - if $SECRET_BINARY keys rm "$KEY_TO_REMOVE"; then - print_success "Removed unlock key: $KEY_TO_REMOVE" - else - print_warning "Unlock key removal not yet implemented" - fi - fi - fi -else - print_warning "Could not create additional unlock key for removal testing" -fi - -# Test 16: Mixed approach compatibility -print_step "16" "Testing mixed approach compatibility" +# Test 14: Mixed approach compatibility +print_step "14" "Testing mixed approach compatibility" # Verify mnemonic can access traditional secrets RETRIEVED_MIXED=$($SECRET_BINARY get "traditional/secret" 2>/dev/null) @@ -757,315 +612,24 @@ fi # Test without mnemonic but with unlock key unset SB_SECRET_MNEMONIC echo "Testing traditional unlock key access to mnemonic-created secrets..." -echo "Running: echo \"$TEST_PASSPHRASE\" | $SECRET_BINARY get \"database/password\"" -if echo "$TEST_PASSPHRASE" | $SECRET_BINARY get "database/password"; then +echo "Running: $SECRET_BINARY get \"database/password\" (with SB_UNLOCK_PASSPHRASE set)" +export SB_UNLOCK_PASSPHRASE="$TEST_PASSPHRASE" +if $SECRET_BINARY get "database/password"; then print_success "Traditional unlock key can access mnemonic-created secrets" else print_warning "Traditional unlock key cannot access mnemonic-created secrets (may need implementation)" fi +unset SB_UNLOCK_PASSPHRASE # Re-enable mnemonic for final tests export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" -# Test 17: Architecture Refactoring - Separation of Concerns -print_step "17" "Testing refactored architecture - separation of concerns" - -echo "Testing that secrets handle their own data access..." -# Create a test secret first -echo "Running: echo \"test-self-access\" | $SECRET_BINARY add \"test/self-access\"" -if echo "test-self-access" | $SECRET_BINARY add "test/self-access"; then - print_success "Created test secret for self-access testing" - - # Try to retrieve it (this tests that Secret.GetEncryptedData() works) - echo "Running: $SECRET_BINARY get \"test/self-access\"" - if $SECRET_BINARY get "test/self-access"; then - print_success "Secret correctly handles its own data access" - else - print_error "Secret failed to handle its own data access" - fi -else - print_error "Failed to create test secret" -fi - -echo "Testing unlock key delegation pattern..." -# Test that vault delegates to unlock keys for decryption -# This is tested implicitly by all our secret retrieval operations -echo "Running: $SECRET_BINARY get \"database/password\"" -if $SECRET_BINARY get "database/password"; then - print_success "Vault correctly delegates to unlock keys for decryption" -else - print_error "Vault delegation pattern failed" -fi - -# Test 18: Interface Method Compliance -print_step "18" "Testing interface method compliance" - -echo "Verifying all unlock key types implement required methods..." - -# Create different types of unlock keys to test interface compliance -echo "Testing PassphraseUnlockKey interface compliance..." -echo "Running: echo \"interface-test-pass\" | $SECRET_BINARY keys add passphrase" -if echo "interface-test-pass" | $SECRET_BINARY keys add passphrase; then - print_success "PassphraseUnlockKey created successfully" - - # Test that we can use it (this verifies GetIdentity and DecryptSecret work) - echo "Running: echo \"interface-test-secret\" | $SECRET_BINARY add \"interface/test\"" - if echo "interface-test-secret" | $SECRET_BINARY add "interface/test"; then - echo "Running: $SECRET_BINARY get \"interface/test\"" - if $SECRET_BINARY get "interface/test"; then - print_success "PassphraseUnlockKey interface methods working" - else - print_error "PassphraseUnlockKey interface methods failed" - fi - else - print_error "Failed to test PassphraseUnlockKey interface" - fi -else - print_warning "Could not create PassphraseUnlockKey for interface testing" -fi - -# Test Secure Enclave on macOS (if available) -if [[ "$OSTYPE" == "darwin"* ]]; then - echo "Testing SEPUnlockKey interface compliance on macOS..." - echo "Running: $SECRET_BINARY enroll sep" - if $SECRET_BINARY enroll sep; then - print_success "SEPUnlockKey created successfully" - - # Test that we can use it - echo "Running: echo \"sep-test-secret\" | $SECRET_BINARY add \"sep/test\"" - if echo "sep-test-secret" | $SECRET_BINARY add "sep/test"; then - echo "Running: $SECRET_BINARY get \"sep/test\"" - if $SECRET_BINARY get "sep/test"; then - print_success "SEPUnlockKey interface methods working" - else - print_error "SEPUnlockKey interface methods failed" - fi - else - print_error "Failed to test SEPUnlockKey interface" - fi - else - print_warning "SEPUnlockKey creation not available for interface testing" - fi -else - print_warning "SEPUnlockKey only available on macOS" -fi - -# Test 19: Long-term Key Management Separation -print_step "19" "Testing long-term key access via different unlock key types" - -echo "Testing that different unlock key types can access the same long-term key..." - -# Switch between different unlock methods to verify each can access the long-term key -echo "Testing mnemonic-based long-term key access..." -export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" -echo "Running: echo \"mnemonic-longterm-test\" | $SECRET_BINARY add \"longterm/mnemonic\"" -if echo "mnemonic-longterm-test" | $SECRET_BINARY add "longterm/mnemonic"; then - echo "Running: $SECRET_BINARY get \"longterm/mnemonic\"" - if $SECRET_BINARY get "longterm/mnemonic"; then - print_success "Mnemonic-based long-term key access working" - else - print_error "Mnemonic-based long-term key access failed" - fi -else - print_error "Failed to test mnemonic-based long-term key access" -fi - -echo "Testing passphrase unlock key accessing long-term key..." -unset SB_SECRET_MNEMONIC -echo "Running: echo \"passphrase-unlock-test\" | $SECRET_BINARY add \"longterm/passphrase-unlock\"" -if echo "passphrase-unlock-test" | $SECRET_BINARY add "longterm/passphrase-unlock"; then - echo "Running: echo \"$TEST_PASSPHRASE\" | $SECRET_BINARY get \"longterm/passphrase-unlock\"" - if echo "$TEST_PASSPHRASE" | $SECRET_BINARY get "longterm/passphrase-unlock"; then - print_success "Passphrase unlock key accessing long-term key working" - else - print_error "Passphrase unlock key accessing long-term key failed" - fi -else - print_error "Failed to test passphrase unlock key accessing long-term key" -fi - -# Re-enable mnemonic for remaining tests -export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" - -# Test 20: Directory Structure and File Access Patterns -print_step "20" "Testing directory structure and file access patterns" - -echo "Verifying secrets access their own directory structure..." - -# Check that secret directories contain the expected structure -SECRET_NAME="structure/test" -echo "Running: echo \"structure-test-value\" | $SECRET_BINARY add $SECRET_NAME" -if echo "structure-test-value" | $SECRET_BINARY add "$SECRET_NAME"; then - print_success "Created secret for structure testing" - - # Convert secret name to directory name (URL encoding) - ENCODED_NAME=$(echo "$SECRET_NAME" | sed 's|/|%|g') - SECRET_DIR="$TEMP_DIR/vaults.d/default/secrets.d/$ENCODED_NAME" - - if [ -d "$SECRET_DIR" ]; then - print_success "Secret directory structure created correctly" - - # Verify secret can access its own encrypted data - echo "Running: $SECRET_BINARY get $SECRET_NAME" - if $SECRET_BINARY get "$SECRET_NAME"; then - print_success "Secret correctly accesses its own encrypted data" - else - print_error "Secret failed to access its own encrypted data" - fi - else - print_error "Secret directory structure not found" - fi -else - print_error "Failed to create secret for structure testing" -fi - -echo "Verifying unlock keys manage their own key files..." - -# Check unlock key directory structure -UNLOCK_KEYS_DIR="$TEMP_DIR/vaults.d/default/unlock-keys.d" -if [ -d "$UNLOCK_KEYS_DIR" ]; then - print_success "Unlock keys directory exists" - - # Check for passphrase unlock key files - for keydir in "$UNLOCK_KEYS_DIR"/*; do - if [ -d "$keydir" ] && [ -f "$keydir/metadata.json" ]; then - print_success "Found unlock key with proper structure: $(basename "$keydir")" - - # Check for required files - if [ -f "$keydir/pub.age" ] && [ -f "$keydir/priv.age" ]; then - print_success "Unlock key has required key files" - - # Check for long-term key management files - if [ -f "$keydir/longterm.age" ]; then - print_success "Unlock key has long-term key file" - else - print_warning "Unlock key missing long-term key file (may be mnemonic-only)" - fi - else - print_error "Unlock key missing required key files" - fi - fi - done -else - print_error "Unlock keys directory not found" -fi - -# Test 21: Error Handling in Refactored Architecture -print_step "21" "Testing error handling in refactored architecture" - -echo "Testing secret error handling..." - -# Test non-existent secret -echo "Running: $SECRET_BINARY get \"nonexistent/secret\"" -if $SECRET_BINARY get "nonexistent/secret"; then - print_error "Should have failed for non-existent secret" -else - print_success "Correctly handled non-existent secret" -fi - -echo "Testing unlock key error handling..." - -# Test with corrupted state (temporarily rename a key file) -UNLOCK_KEYS_DIR="$TEMP_DIR/vaults.d/default/unlock-keys.d" -FIRST_KEY_DIR=$(find "$UNLOCK_KEYS_DIR" -type d -name "*" | head -n1) -if [ -d "$FIRST_KEY_DIR" ] && [ -f "$FIRST_KEY_DIR/priv.age" ]; then - # Temporarily corrupt the key - mv "$FIRST_KEY_DIR/priv.age" "$FIRST_KEY_DIR/priv.age.backup" - - # Temporarily disable mnemonic to force unlock key usage - unset SB_SECRET_MNEMONIC - - echo "Running: $SECRET_BINARY get \"database/password\"" - if $SECRET_BINARY get "database/password"; then - print_warning "Expected failure with corrupted unlock key, but succeeded (may have fallback)" - else - print_success "Correctly handled corrupted unlock key" - fi - - # Restore the key - mv "$FIRST_KEY_DIR/priv.age.backup" "$FIRST_KEY_DIR/priv.age" - - # Re-enable mnemonic - export SB_SECRET_MNEMONIC="$TEST_MNEMONIC" -else - print_warning "Could not test unlock key error handling - no key found" -fi - -# Test 22: Cross-Component Integration -print_step "22" "Testing cross-component integration" - -echo "Testing vault-secret-unlock key integration..." - -# Create a secret in one vault, switch vaults, create another secret, switch back -echo "Running: $SECRET_BINARY vault create integration-test" -if $SECRET_BINARY vault create integration-test; then - print_success "Created integration test vault" - - # Add secret to default vault - echo "Running: echo \"default-vault-secret\" | $SECRET_BINARY add \"integration/default\"" - if echo "default-vault-secret" | $SECRET_BINARY add "integration/default"; then - print_success "Added secret to default vault" - - # Switch to integration-test vault - echo "Running: $SECRET_BINARY vault select integration-test" - if $SECRET_BINARY vault select integration-test; then - print_success "Switched to integration-test vault" - - # Create unlock key in new vault - echo "Running: echo \"integration-passphrase\" | $SECRET_BINARY keys add passphrase" - if echo "integration-passphrase" | $SECRET_BINARY keys add passphrase; then - print_success "Created unlock key in integration-test vault" - - # Add secret to integration-test vault - echo "Running: echo \"integration-vault-secret\" | $SECRET_BINARY add \"integration/test\"" - if echo "integration-vault-secret" | $SECRET_BINARY add "integration/test"; then - print_success "Added secret to integration-test vault" - - # Verify secret retrieval works - echo "Running: $SECRET_BINARY get \"integration/test\"" - if $SECRET_BINARY get "integration/test"; then - print_success "Cross-component integration working" - else - print_error "Cross-component integration failed" - fi - else - print_error "Failed to add secret to integration-test vault" - fi - else - print_error "Failed to create unlock key in integration-test vault" - fi - - # Switch back to default vault - echo "Running: $SECRET_BINARY vault select default" - if $SECRET_BINARY vault select default; then - print_success "Switched back to default vault" - - # Verify we can still access default vault secrets - echo "Running: $SECRET_BINARY get \"integration/default\"" - if $SECRET_BINARY get "integration/default"; then - print_success "Can still access default vault secrets" - else - print_error "Cannot access default vault secrets after switching" - fi - else - print_error "Failed to switch back to default vault" - fi - else - print_error "Failed to switch to integration-test vault" - fi - else - print_error "Failed to add secret to default vault" - fi -else - print_error "Failed to create integration test vault" -fi - # Final summary echo -e "\n${GREEN}=== Test Summary ===${NC}" echo -e "${GREEN}✓ Environment variable support (SB_SECRET_STATE_DIR, SB_SECRET_MNEMONIC)${NC}" echo -e "${GREEN}✓ Secret manager initialization${NC}" echo -e "${GREEN}✓ Vault management (create, list, select)${NC}" -echo -e "${GREEN}✓ Import functionality with all environment variable combinations${NC}" +echo -e "${GREEN}✓ Import functionality with environment variable combinations${NC}" echo -e "${GREEN}✓ Import error handling (non-existent vault, invalid mnemonic)${NC}" echo -e "${GREEN}✓ Unlock key management (passphrase, PGP, SEP)${NC}" echo -e "${GREEN}✓ Mnemonic-based secret operations (keyless)${NC}" @@ -1074,17 +638,10 @@ echo -e "${GREEN}✓ Secret name validation${NC}" echo -e "${GREEN}✓ Overwrite protection and force flag${NC}" echo -e "${GREEN}✓ Cross-vault operations${NC}" echo -e "${GREEN}✓ Per-secret key file structure${NC}" -echo -e "${GREEN}✓ Unlock key removal${NC}" echo -e "${GREEN}✓ Mixed approach compatibility${NC}" echo -e "${GREEN}✓ Error handling${NC}" -echo -e "${GREEN}✓ Refactored architecture - separation of concerns${NC}" -echo -e "${GREEN}✓ Interface method compliance${NC}" -echo -e "${GREEN}✓ Long-term key access via different unlock key types${NC}" -echo -e "${GREEN}✓ Directory structure and file access patterns${NC}" -echo -e "${GREEN}✓ Error handling in refactored architecture${NC}" -echo -e "${GREEN}✓ Cross-component integration${NC}" -echo -e "\n${GREEN}🎉 Comprehensive test completed with architecture verification!${NC}" +echo -e "\n${GREEN}🎉 Comprehensive test completed with environment variable automation!${NC}" # Show usage examples for all implemented functionality echo -e "\n${BLUE}=== Complete Usage Examples ===${NC}" @@ -1100,25 +657,14 @@ echo "secret vault list" echo "secret vault create work" echo "secret vault select work" echo "" -echo -e "${YELLOW}# Import mnemonic (different combinations):${NC}" -echo "# With mnemonic env var set:" -echo "export SB_SECRET_MNEMONIC=\"abandon abandon...\"" -echo "echo \"passphrase\" | secret import work" -echo "" -echo "# With passphrase env var set:" -echo "export SB_UNLOCK_PASSPHRASE=\"passphrase\"" -echo "echo \"abandon abandon...\" | secret import work" -echo "" -echo "# With both env vars set:" +echo -e "${YELLOW}# Import mnemonic (automated with environment variables):${NC}" echo "export SB_SECRET_MNEMONIC=\"abandon abandon...\"" echo "export SB_UNLOCK_PASSPHRASE=\"passphrase\"" -echo "secret import work" -echo "" -echo "# With neither env var set:" -echo "(echo \"abandon abandon...\"; echo \"passphrase\") | secret import work" +echo "secret vault import work" echo "" echo -e "${YELLOW}# Unlock key management:${NC}" -echo "echo \"passphrase\" | secret keys add passphrase" +echo "export SB_UNLOCK_PASSPHRASE=\"passphrase\"" +echo "secret keys add passphrase" echo "secret keys add pgp " echo "secret enroll sep # macOS only" echo "secret keys list"