saveConfig in src/config.js:84-87 persists the credentials file with whatever the process umask yields (typically 0644, world-readable):
export function saveConfig(config) {
ensureConfigDir();
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
}
The file contains the raw apiKey (a sk-... secret). On a shared machine any other local user can read ~/.tuya-cli/config.json. Tools that store tokens (npm, gh, aws) all create the file 0600 and the directory 0700. Two small tweaks would close the gap:
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
(Note mode on writeFileSync only applies when the file is created, so an explicit fs.chmodSync(CONFIG_FILE, 0o600) afterwards is safer for the overwrite case.)
Minor related point: tuya init (src/commands/init.js:63,67) calls saveConfig({ apiKey, baseUrl }), which silently drops any other keys already in the config rather than merging onto existing. Worth considering if more settings land here later.
saveConfiginsrc/config.js:84-87persists the credentials file with whatever the process umask yields (typically0644, world-readable):The file contains the raw
apiKey(ask-...secret). On a shared machine any other local user can read~/.tuya-cli/config.json. Tools that store tokens (npm, gh, aws) all create the file0600and the directory0700. Two small tweaks would close the gap:(Note
modeonwriteFileSynconly applies when the file is created, so an explicitfs.chmodSync(CONFIG_FILE, 0o600)afterwards is safer for the overwrite case.)Minor related point:
tuya init(src/commands/init.js:63,67) callssaveConfig({ apiKey, baseUrl }), which silently drops any other keys already in the config rather than merging ontoexisting. Worth considering if more settings land here later.