-
Have just come across this issue - tauri-apps/plugins-workspace#1959 - and would also be interested in additional examples or guidance for using stronghold. We have one initial use case, which is securely storing API access tokens after a user has authenticated with an API. At the moment the user will authenticate on every launch of the Tauri app - and so we were considering using the user API credentials to create the password for the stronghold vault. But, the user may change their account credentials in the future - in which case we would need to change the password to the stronghold vault as well. There's doesn't appear to be an API method for this, in which case we would need to manually retrieve all secrets from the old vault, create a new vault with the new user credentials, save the new vault, and then remove the old one. Even if we prompt the user for a separate vault passphrase etc., as far as we can tell, it appears we have to manually implement the vault password change as above. It seems reasonable that the user should be able to change the password to the stronghold vault. We're not 100% sure on either our initial use case (storing API tokens - although this seems like a valid use case stronghold) or on a password management strategy for the stronghold vault. Any thoughts or suggestions greatly appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
If this helps - for us the key (pun intended) to everything was the keyring crate https://crates.io/crates/keyring We setup stronghold in Tauri like this... use rand::RngCore;
use std::fs;
use std::io::Write;
use tauri::Manager;
use tauri_plugin_stronghold;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
// Determine salt path
let salt_path = app
.path()
.app_local_data_dir()
.expect("could not resolve app local data path")
.join("your-salt-file.txt");
// Ensure the directory exists
if let Some(parent_dir) = salt_path.parent() {
fs::create_dir_all(parent_dir)?;
}
// If salt.txt doesn't exist, generate a new random salt for this installation
if !salt_path.exists() {
let mut salt = [0u8; 32]; // 256-bit salt
rand::rng().fill_bytes(&mut salt);
let mut file = fs::File::create(&salt_path)?;
file.write_all(&salt)?;
}
// Register the Stronghold plugin using Argon2 + the salt
app.handle()
.plugin(tauri_plugin_stronghold::Builder::with_argon2(&salt_path).build())?;
Ok(())
})
.invoke_handler(tauri::generate_handler![
get_stronghold_password
])
.run(tauri::generate_context!())
.expect("error while running tauri application")
} .. which creates a per-installation salt file. We then registered a Our stronghold front-end JS API looks like this.... import { invoke } from '@tauri-apps/api/core';
import { appDataDir } from '@tauri-apps/api/path';
import { Stronghold } from '@tauri-apps/plugin-stronghold';
import type { Client } from '@tauri-apps/plugin-stronghold';
let stronghold: Stronghold | null = null;
let client: Client | null = null;
const VAULT_FILENAME = 'vault.hold';
const CLIENT_NAME = 'some-client-name';
export async function loadVault() {
const vaultPassword = await invoke('get_stronghold_password') as string;
const vaultPath = `${await appDataDir()}${VAULT_FILENAME}`;
stronghold = await Stronghold.load(vaultPath, vaultPassword);
try {
client = await stronghold.loadClient(CLIENT_NAME);
} catch {
client = await stronghold.createClient(CLIENT_NAME);
}
}
function getStoreOrThrow() {
if (!client) throw new Error("Stronghold client not initialized");
return client.getStore();
}
...
// other stronghold client functions to set and retrieve secrets Of course this is just one use case and scenario, where we want a per-application installation stronghold password that the user never sees. If your secrets are not large (for example, not larger than Windows Credential Manager's limit of 2560 characters), then you could simply use keyring for all your secrets. |
Beta Was this translation helpful? Give feedback.
If this helps - for us the key (pun intended) to everything was the keyring crate https://crates.io/crates/keyring
We setup stronghold in Tauri like this...