diff --git a/desktop/src-tauri/src/commands/identity.rs b/desktop/src-tauri/src/commands/identity.rs
index 9abecbd2c..45ae33d99 100644
--- a/desktop/src-tauri/src/commands/identity.rs
+++ b/desktop/src-tauri/src/commands/identity.rs
@@ -285,7 +285,7 @@ pub async fn save_ncryptsec_copy(
let dest = match crate::commands::export_util::pick_save_path(
&app_handle,
crate::key_backup::BACKUP_FILE_NAME,
- "Keycase",
+ "Password-protected key backup",
&["ncryptsec"],
)
.await?
diff --git a/desktop/src-tauri/src/key_backup.rs b/desktop/src-tauri/src/key_backup.rs
index 0a19fb143..418be3bb0 100644
--- a/desktop/src-tauri/src/key_backup.rs
+++ b/desktop/src-tauri/src/key_backup.rs
@@ -106,7 +106,7 @@ pub fn decrypt_ncryptsec(input: &str, password: &str) -> Result {
let encrypted = parse_ncryptsec(input)?;
let secret_key = encrypted
.decrypt(password)
- .map_err(|_| "wrong Keycase password or damaged Keycase".to_string())?;
+ .map_err(|_| "wrong backup password or damaged key backup".to_string())?;
Ok(Keys::new(secret_key))
}
@@ -125,7 +125,7 @@ pub fn recover_keys_from_input(input: &str, password: Option<&str>) -> Result([]);
// Owned here (not by DownloadKeyStep) so Back navigation — which unmounts
- // the step — keeps the created Keycase, entered password, and test progress.
+ // the step — keeps the created backup, entered password, and test progress.
const backupSession = useEncryptedBackupSession();
const handleReadyRuntimeIdsChange = React.useCallback(
(runtimeIds: readonly string[]) => {
diff --git a/desktop/src/features/onboarding/ui/NostrKeyImportForm.tsx b/desktop/src/features/onboarding/ui/NostrKeyImportForm.tsx
index 90eb1f368..900b7b932 100644
--- a/desktop/src/features/onboarding/ui/NostrKeyImportForm.tsx
+++ b/desktop/src/features/onboarding/ui/NostrKeyImportForm.tsx
@@ -96,7 +96,7 @@ export function NostrKeyImportForm({
if (file.size > NOSTR_KEY_FILE_MAX_BYTES) {
setImportError(
- "That file is too large to be a Keycase or private key. Choose another file.",
+ "That file is too large to be a key backup or private key. Choose another file.",
);
return;
}
@@ -126,7 +126,7 @@ export function NostrKeyImportForm({
if (!isValid) {
setImportError(
isEncryptedInput
- ? "Enter the password for this Keycase."
+ ? "Enter the password for this key backup."
: "That doesn't look like a valid nsec. Paste an nsec1 key.",
);
return;
@@ -244,8 +244,8 @@ export function NostrKeyImportForm({
{/* Hidden file input shared by both variants: the default drop zone and
- the spotlight "Use a Keycase" button both open it. Accepts the
- .ncryptsec archives our own save flow emits alongside raw .key files. */}
+ the spotlight "Choose a backup file" button both open it. Accepts the
+ .ncryptsec backups our own save flow emits alongside raw .key files. */}
- Use a Keycase
+ Choose a backup file
) : (
@@ -358,7 +358,7 @@ export function NostrKeyImportForm({
className="text-sm font-medium text-foreground"
htmlFor="nostr-import-passphrase"
>
- Keycase password
+ Backup password
- Your Keycase and password stay on this device.
+ Your backup file and password stay on this device.
) : null}
@@ -396,7 +396,8 @@ export function NostrKeyImportForm({
data-testid="nostr-import-encrypted-badge"
>
- Keycase · Private — enter its password to restore
+ Password-protected key backup · Private — enter its password to
+ restore
) : previewNpub ? (
variant === "spotlight" ? (
diff --git a/desktop/src/features/onboarding/ui/onboardingFlowSteps.test.mjs b/desktop/src/features/onboarding/ui/onboardingFlowSteps.test.mjs
index c28be1386..622db610a 100644
--- a/desktop/src/features/onboarding/ui/onboardingFlowSteps.test.mjs
+++ b/desktop/src/features/onboarding/ui/onboardingFlowSteps.test.mjs
@@ -53,7 +53,7 @@ test("currentStep_falls_back_to_1_for_pages_outside_the_step_list", () => {
});
// ---------------------------------------------------------------------------
-// BackupStep gating: saving a Keycase is recommended, not required
+// BackupStep gating: saving a password-protected backup is recommended, not required
// ---------------------------------------------------------------------------
test("backup_next_is_always_enabled", () => {
diff --git a/desktop/src/features/settings/ui/ProfileSettingsCard.tsx b/desktop/src/features/settings/ui/ProfileSettingsCard.tsx
index bec4d2e4a..8066ba6db 100644
--- a/desktop/src/features/settings/ui/ProfileSettingsCard.tsx
+++ b/desktop/src/features/settings/ui/ProfileSettingsCard.tsx
@@ -178,9 +178,9 @@ function NsecRevealRow() {
}
/**
- * Collapsible row for saving a portable Keycase on demand. The raw
- * private key never reaches this flow — the passphrase goes to Rust, which
- * returns the persisted `ncryptsec1…` blob.
+ * Collapsible row for creating and testing a password-protected key backup.
+ * The raw private key never reaches this flow — the password goes to Rust,
+ * which returns the persisted `ncryptsec1…` blob.
*/
function EncryptedBackupRow() {
const [isOpen, setIsOpen] = React.useState(false);
@@ -189,28 +189,34 @@ function EncryptedBackupRow() {
-
Keycase
+
Password-protected key backup
- Save a portable, password-protected copy of your identity. Keep it
- private.
+ Download an encrypted copy of your identity key, then test the file
+ and password before relying on it.
{isOpen ? (
- Buzz cannot reset the password. Saving a new Keycase does not
- invalidate copies you saved before.
+ Keep the downloaded file private and save its password somewhere
+ safe. Buzz cannot reset the password. Creating another backup does
+ not invalidate copies you saved before.
) : null}
diff --git a/desktop/src/features/settings/ui/SignOutSection.tsx b/desktop/src/features/settings/ui/SignOutSection.tsx
index 8d4dc1c48..7379a4a4b 100644
--- a/desktop/src/features/settings/ui/SignOutSection.tsx
+++ b/desktop/src/features/settings/ui/SignOutSection.tsx
@@ -31,9 +31,9 @@ export const SIGNOUT_CONFIRM_PHRASE = "wipe all my data";
* Signing out wipes the identity key and all local data, so the confirm
* dialog gates the delete button behind two explicit steps:
*
- * 1. Back up the key — the nsec is shown inline (masked, with reveal/copy);
- * the "I have saved my private key" checkbox unlocks only after the user
- * actually reveals or copies the key.
+ * 1. Confirm recovery — Settings offers a tested password-protected backup;
+ * the dialog also shows the raw nsec as a last-chance fallback. The
+ * checkbox unlocks only after the user reveals or copies that key.
* 2. Typed confirmation — the user must type the exact phrase
* "wipe all my data".
*
@@ -137,7 +137,8 @@ export function SignOutSection() {
Sign out
Removes your identity key and all local app data from this device.
- Back up your private key (nsec) first — this cannot be undone.
+ Before signing out, create and test a password-protected key backup
+ above — this cannot be undone.