diff --git a/tests/nixos/s3-binary-cache-store.nix b/tests/nixos/s3-binary-cache-store.nix index 0e01d0a01..154c1fb1b 100644 --- a/tests/nixos/s3-binary-cache-store.nix +++ b/tests/nixos/s3-binary-cache-store.nix @@ -789,6 +789,108 @@ in print(" ✓ Compressed log uploaded with multipart") + @setup_s3( + populate_bucket=[PKGS['A']], + profiles={ + "valid": {"access_key": ACCESS_KEY, "secret_key": SECRET_KEY}, + "invalid": {"access_key": "INVALIDKEY", "secret_key": "INVALIDSECRET"}, + } + ) + def test_profile_credentials(bucket): + """Test that profile-based credentials work without environment variables""" + print("\n=== Testing Profile-Based Credentials ===") + + store_url = make_s3_url(bucket, profile="valid") + + # Verify store info works with profile credentials (no env vars) + client.succeed(f"HOME=/root nix store info --store '{store_url}' >&2") + print(" ✓ nix store info works with profile credentials") + + # Verify we can copy from the store using profile + verify_packages_in_store(client, PKGS['A'], should_exist=False) + client.succeed(f"HOME=/root nix copy --no-check-sigs --from '{store_url}' {PKGS['A']}") + verify_packages_in_store(client, PKGS['A']) + print(" ✓ nix copy works with profile credentials") + + # Clean up the package we just copied so we can test invalid profile + client.succeed(f"nix store delete --ignore-liveness {PKGS['A']}") + verify_packages_in_store(client, PKGS['A'], should_exist=False) + + # Verify invalid profile fails when trying to copy + invalid_url = make_s3_url(bucket, profile="invalid") + client.fail(f"HOME=/root nix copy --no-check-sigs --from '{invalid_url}' {PKGS['A']} 2>&1") + print(" ✓ Invalid profile credentials correctly rejected") + + @setup_s3( + populate_bucket=[PKGS['A']], + profiles={ + "wrong": {"access_key": "WRONGKEY", "secret_key": "WRONGSECRET"}, + } + ) + def test_env_vars_precedence(bucket): + """Test that environment variables take precedence over profile credentials""" + print("\n=== Testing Environment Variables Precedence ===") + + # Use profile with wrong credentials, but provide correct creds via env vars + store_url = make_s3_url(bucket, profile="wrong") + + # Ensure package is not in client store + verify_packages_in_store(client, PKGS['A'], should_exist=False) + + # This should succeed because env vars (correct) override profile (wrong) + output = client.succeed( + f"HOME=/root {ENV_WITH_CREDS} nix copy --no-check-sigs --debug --from '{store_url}' {PKGS['A']} 2>&1" + ) + print(" ✓ nix copy succeeded with env vars overriding wrong profile") + + # Verify the credential chain shows Environment provider was added + if "Added AWS Environment Credential Provider" not in output: + print("Debug output:") + print(output) + raise Exception("Expected Environment provider to be added to chain") + print(" ✓ Environment provider added to credential chain") + + # Clean up the package so we can test again without env vars + client.succeed(f"nix store delete --ignore-liveness {PKGS['A']}") + verify_packages_in_store(client, PKGS['A'], should_exist=False) + + # Without env vars, same URL should fail (proving profile creds are actually wrong) + client.fail(f"HOME=/root nix copy --no-check-sigs --from '{store_url}' {PKGS['A']} 2>&1") + print(" ✓ Without env vars, wrong profile credentials correctly fail") + + @setup_s3( + populate_bucket=[PKGS['A']], + profiles={ + "testprofile": {"access_key": ACCESS_KEY, "secret_key": SECRET_KEY}, + } + ) + def test_credential_provider_chain(bucket): + """Test that debug logging shows which providers are added to the chain""" + print("\n=== Testing Credential Provider Chain Logging ===") + + store_url = make_s3_url(bucket, profile="testprofile") + + output = client.succeed( + f"HOME=/root nix store info --debug --store '{store_url}' 2>&1" + ) + + # For a named profile, we expect to see these providers in the chain + expected_providers = ["Environment", "Profile", "IMDS"] + for provider in expected_providers: + msg = f"Added AWS {provider} Credential Provider to chain for profile 'testprofile'" + if msg not in output: + print("Debug output:") + print(output) + raise Exception(f"Expected to find: {msg}") + print(f" ✓ {provider} provider added to chain") + + # SSO should be skipped (no SSO config for this profile) + if "Skipped AWS SSO Credential Provider for profile 'testprofile'" not in output: + print("Debug output:") + print(output) + raise Exception("Expected SSO provider to be skipped") + print(" ✓ SSO provider correctly skipped (not configured)") + # ============================================================================ # Main Test Execution # ============================================================================ @@ -822,6 +924,9 @@ in test_multipart_upload_basic() test_multipart_threshold() test_multipart_with_log_compression() + test_profile_credentials() + test_env_vars_precedence() + test_credential_provider_chain() print("\n" + "="*80) print("✓ All S3 Binary Cache Store Tests Passed!")