fix(worker): stop leaking credential secret trees and allow multi-line secret entry #351
No reviewers
Labels
No labels
Epic 5
MCP
P1
PR-0
PR-1
api
api-layer
architecture
area:backend
area:frontend
arrow
authentication
backend
bug
chat
client
clipboard
common-module
compose
cross-cutting
cross-cutting-requirement
data-layer
data-models
database
desktop-client
documentation
duplicate
enhancement
epic
epic-1
epic-2
epic-3
epic-4
epic-5
epic-6
epic-7
epic-llm-config
error-handling
feature
frontend
good first issue
help wanted
implementation
infrastructure
installer
invalid
kotlin
ktor
llm
medium-priority
message
multiplatform
needs-review
needs-triage
packaging
performance
phase-1
phase-2
phase-3
phase-4
phase-5
phase3
phase:3
priority: high
question
refactor
refactoring
resource-sharing
security
server
server-module
services
session
session-management
settings
setup
shutdown
state
storage
streaming
sub-issue
tests
tooling
type:task
ui
ui/ux
user-accounts
user-management
ux
viewmodel
websocket
windows
windows-integration
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Torvian.eu/chatbot!351
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/credential-secret-tree-removal"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Two independent changes: a fix for a defect in the already-merged credential attach feature, and a small app usability change that lets operators enter multi-line secrets.
Secret trees were never actually removed
/run/torvian/secretsis ownedtorvian:torvianwith mode0711, so the credential account can traverse it but not write to it.rmdir(2)requires write permission on the parent directory, sorun-as-vault --clear-secret-diralways failed when it reached its finalrmdirof a<token>entry: it had already dropped to thevaultaccount by then, the call returnedEACCES, and the helper exited with code 14. Tree contents were unlinked successfully because the tree directory itself is0700 vault, so no secret material survived; the empty directories accumulated instead, and the startup sweep warned about each one on every restart.remove_treetakes aremove_selfflag, which is0for the root of the walk and1for recursive children, so normdiris attempted on the tree root. Validation still runs beforedrop_privileges, and only the bounded unlink walk runs after it.DirectoryNotEmptyExceptionor any otherIOExceptionbecomes a typedPreparationFailed, and no recursive delete is ever attempted.closepaths instead of being discarded until the next startup sweep.deploy/worker/README.mddocuments the split ownership of the secret root.Deletion is tied to the profile target's lifetime, not to
detachalone: auto-detach on profile exit, thedetachaction, session close, worker shutdown, attach failure or cancellation before registration, and the startup sweep all converge on the same two-step removal.Multi-line credential secrets
The credential secret value field was declared
singleLine = true, so a long secret could not be inspected and a truncated paste would have been invisible. It is now a bounded multi-line field (minLines = 1,maxLines = 8) with masking, the show/hide toggle, the reveal-state keying and the byte-limit hint all unchanged. The value still reaches the request body untransformed; onlyreferenceis trimmed, which is pre-existing behaviour.This is a usability and risk-reduction change, not a bug fix: the failure that prompted it was a passphrase-protected private key, which OpenSSH cannot unlock non-interactively. The stored value was intact.
Verification
./gradlew :worker:test— 799 tests, 0 failures, 4 skipped../gradlew :app:desktopTest— 1120 tests, 0 failures, 2 skipped.file-channel profile no longer leaves a directory behind under/run/torvian/secrets, and the startup sweep is silent after a restart.file-channel profile with its line structure intact.Limitations