Skip to content

fix(agent): stop identities only on a failed check - #2159

Merged
Benoît Cortier (CBenoit) merged 3 commits into
masterfrom
fix/agent-identity-transient-check
Oct 28, 2026
Merged

Benoît Cortier (CBenoit) merged 3 commits into
masterfrom
fix/agent-identity-transient-check

Conversation

@CBenoit

Copy link
Copy Markdown
Member

The pending-enrollment poll stopped every identity runner and its agent channel streams whenever the stored-identity check returned any error, and logged nothing. An I/O error that only kept the check from running, rather than a stored identity failing it, therefore restarted all identity processing, for example in the middle of a renewal, which can reorder its confirm, new channel authentication and old stream close.

The check now reports an authority directory or identity.json as untrusted only when it fails the check itself or denies the agent access; any other I/O error stays an ordinary error. The poll stops every identity only for an untrusted stored identity and otherwise retries at the next poll, logging the error in both cases. The check still runs without the state lock, since it changes nothing and every state change repeats it under the lock.

When the tests job fails, CI now uploads the Agent Identity conformance directories the suite keeps, so that a failure seen once leaves its agent data directories and logs.

Issue: DGW-478

🤖 Generated with Claude Code

The pending-enrollment poll stopped every identity runner and its
agent channel streams whenever the stored-identity check returned any
error, and logged nothing. An I/O error that only kept the check from
running therefore restarted all identity processing, for example in
the middle of a renewal, which can reorder its confirm, new channel
authentication and old stream close.

The check now reports an authority directory or identity.json as
untrusted only when it fails the check itself or denies the agent
access; any other I/O error stays an ordinary error. The poll stops
every identity only for an untrusted stored identity and otherwise
retries at the next poll, logging the error in both cases. The check
still runs without the state lock, since it changes nothing and every
state change repeats it under the lock.

When the tests job fails, CI now uploads the Agent Identity
conformance directories the suite keeps, so that a failure seen once
leaves its agent data directories and logs.

Issue: DGW-478
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CBenoit

Benoît Cortier (CBenoit) commented Oct 26, 2026 •

Copy link
Copy Markdown
Member Author

Lines changed

Area Added Removed
Production code (private_file.rs, identity/mod.rs outside tests) 47 5
Tests 120 16
Other (CI workflow) 29 0

Untested properties

  • devolutions-agent/src/identity/mod.rs, pending poll: both outcomes of a failed check, a stop for an untrusted stored identity and a retry for any other error, are logged with the error. No test captures service logs.
  • .github/workflows/ci.yml, tests job: the collect and upload steps run only after a failure, so no run has exercised them. They look for agent-identity-integration* under target, the temporary directory and ProgramData, which covers the conformance work directories on every platform. The collection script was dry-run locally on a fake layout.

Decision: no state lock around the poll's check

crates/agent-identity/INTENT.md ("Local state") requires the lock for every state change. The check changes nothing, read_identity and list_identities already run it unlocked, and every state change repeats it under the lock (Store::lock). Writes are atomic renames, so an unlocked check sees the old or the new identity.json, or an I/O error, which the poll now retries. Taking the lock on every poll would make the poll wait behind renewals (up to 30 s on Windows), and on Linux and macOS state_lock::acquire also provisions the identity directories each time.

Verification

  • The new poll test fails without the fix on Windows and Linux (the poll returns Untrusted while identity/authorities is unlistable) and passes with it.
  • The new Windows test holds an authority directory open without sharing; the check fails with a sharing violation (os error 32), which master reported as an untrusted stored identity and which is now an ordinary error. It fails with the classification reverted and passes with it.
  • cargo test -p agent-identity -p devolutions-agent passes on Windows and Linux (WSL) after merging master. On Windows the tests ran with TEMP pointing at a directory with owner-only access, because private-fs refuses the local user temporary directory, which grants sandbox accounts modify access; this is unrelated to this change.
  • cargo clippy -p agent-identity -p devolutions-agent --all-targets -- -D warnings is clean on Windows and Linux.

Note

LLM-assisted content (no human feedback).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CBenoit
Benoît Cortier (CBenoit) merged commit 3187467 into master Oct 28, 2026
53 checks passed
@CBenoit
Benoît Cortier (CBenoit) deleted the fix/agent-identity-transient-check branch October 28, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant