Repository navigation
fix: implement chunked Windows secret storage functionality - #108
saschajohn wants to merge 1 commit into
Conversation
Add support for Windows secret storage with chunking and manifest validation.
| if let Some(existing_chunks) = &existing_chunks { | ||
| delete_windows_chunks(service, account, 0..existing_chunks.len())?; |
| let chunk_count = chunk_count | ||
| .parse::<usize>() | ||
| .context("parse Windows secret chunk manifest")?; | ||
| if chunk_count < 2 { | ||
| bail!("Windows secret chunk manifest must contain at least two chunks"); | ||
| } | ||
| Ok(Some(chunk_count)) |
| #[test] | ||
| fn windows_secret_helpers_preserve_utf8_boundaries() { | ||
| let secret = format!("{}🙂tail", "a".repeat(WINDOWS_SECRET_CHUNK_SIZE - 1)); | ||
| let chunks = utf8_chunks(&secret, WINDOWS_SECRET_CHUNK_SIZE).collect::<Vec<_>>(); |
peterj
left a comment
There was a problem hiding this comment.
thanks for the PR! can you address the comments please?
|
Tested this on a Windows 11 Enterprise VM (build 26300, not domain-joined) with the daemon installed as the
Building on the chunking here, I tried an approach for the three review points, as one commit on top of 58bc554: LutzLange@3804cd8
On the VM the tests pass as SYSTEM, including the Credential Manager round trip, and the service enrolls on the first attempt and reconnects after a restart without a new sign-in. Happy to adjust, or to open it against your branch if that's easier. |
|
is chunking really the best approach? or store a key (small) in the storage and encrypt the data (arbitrary size) on the disk? |
|
@howardjohn Agreed, chunking is much more complicated. I implemented your suggestion in #171: each secret is an AES-256-GCM file in the private state directory, and Credential Manager keeps only its 32-byte key. The Windows service enrolls as LocalSystem against Keycloak ( @saschajohn this builds on your analysis in #107. |
…ntial Manager Windows Credential Manager limits a credential to 2560 bytes, and OAuth credentials with refresh tokens exceed it, so enrolling the Windows service failed (agentdesktop-dev#107). Store each secret as an AES-256-GCM file in the daemon's private state directory and keep only its 32-byte random key in Credential Manager, as suggested in agentdesktop-dev#108. - The key is created once per secret and reused, so replacing the file atomically is the only step that changes a stored secret. - The file is bound to its service and account (AAD), so a file moved to another entry's path does not open. - Values stored directly in Credential Manager by earlier versions are still read, and are replaced on the next write. Delete removes such a value first, so a delete that stops halfway never brings an old value back. - The envelope logic sits behind a small key-store trait and is tested on every platform with an in-memory store and injected failures; one Windows test round-trips a 10,000-character secret through Credential Manager. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>



Add support for Windows secret storage with chunking and manifest validation.
Fixes #107