fix(ssh): state what installing a key actually costs, and ask before doing it (v0.23.25-beta)
v0.23.24 shipped the SSH key feature with a warning that undersold it and a confirmation flow that was the wrong way round. Five gaps, all in how the change was presented rather than in what it does. **Installing was one click; revoking asked for confirmation.** Backwards. Revoking restores password SSH, while installing takes it away — the consequential action was the unguarded one. Installation now requires an explicit acknowledgement naming the account that will lose password access. **The warning disappeared once a key existed.** Whoever arrives at a device later and finds their password refused over SSH is exactly the person who needs the explanation, and they were the one person not shown it. The notice is now permanent, worded for the current state rather than only the impending one. **It said "this user" rather than naming the account**, which is the difference between a caution and a fact someone can act on. **It never mentioned losing the database.** That is the serious one. Password SSH is already refused once a key is bound, so a manager that loses its database or encryption key leaves SSH recoverable only through the API or WinBox. That consequence outlives the session, the operator, and quite possibly the person who clicked the button, and it went unstated. **Fleet-wide deployment had no guard whatsoever.** One request would disable password SSH on every device it touched, while the single-device path asked for an acknowledgement — an endpoint that can do a thing sixty times should not be easier to trigger than the one that does it once. It now refuses without an explicit confirm and explains why in the refusal. The notice also spells out what was previously left implicit: colleagues, scripts and other tools that SSH in with a password will stop working. On a shared fleet that is a change to announce, not to discover. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1ab2e6547e
commit
864ca40427
@@ -1663,7 +1663,19 @@ router.delete('/:id/ssh-key', requireWrite, async (req: Request, res: Response)
|
||||
* ends by proving the key, and running sixty of those at once would be a
|
||||
* thundering herd against the fleet for no wall-clock gain worth having.
|
||||
*/
|
||||
router.post('/ssh-keys/deploy-all', requireWrite, async (_req: Request, res: Response) => {
|
||||
router.post('/ssh-keys/deploy-all', requireWrite, async (req: Request, res: Response) => {
|
||||
// This is the most consequential call in the feature: it disables password SSH
|
||||
// across an entire fleet in one request. The per-device path asks for an
|
||||
// acknowledgement in the UI, and an endpoint that can do it sixty times over
|
||||
// should not be easier to trigger than the one that does it once.
|
||||
if ((req.body as { confirm?: boolean })?.confirm !== true) {
|
||||
return res.status(400).json({
|
||||
error: 'Refusing to deploy fleet-wide without confirmation. This disables password ' +
|
||||
'SSH for the configured user on every device it touches; the API and WinBox ' +
|
||||
'are unaffected. Repeat with {"confirm": true} once that is understood.',
|
||||
});
|
||||
}
|
||||
|
||||
const targets = await query<any>(
|
||||
`SELECT ${SSH_TARGET_COLS} FROM devices d
|
||||
WHERE d.status != 'disabled' AND d.ssh_username IS NOT NULL
|
||||
|
||||
Reference in New Issue
Block a user