feat(agent): device identity enrollment and channel - #2000
Draft
Benoît Cortier (CBenoit) wants to merge 50 commits into
Draft
Benoît Cortier (CBenoit) wants to merge 50 commits into
Benoît Cortier (CBenoit) wants to merge 50 commits into
Conversation
Adds the approved agent identity contract (v0.3), the gRPC channel definition as a shared crate, and RFC 9421 / channel-proof test vectors. Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds Devolutions.AgentIdentity.Channel, a NuGet package generated from the same channel.proto as the Rust crate, so server implementers get the gRPC service base and client types without copying the schema. Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
In-memory implementation of the agent identity contract used as the conformance oracle: agent-facing API, admin API, gRPC channel with the challenge/proof handshake, root rotation and a fault-injection API. The RFC 9421 profile is verified by hand and pinned by the shared test vectors. Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds the conformance tester binary (protocol tests acting as a raw client, agent tests spawning the real agent and standing in for the MSI) and wires it into the testsuite against two mock instances. Hardens the mock's signature parameter parsing. Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds live digest-integrity and revoked-before-Hello channel checks, anchors certificate chains to published roots, distinguishes an absent channel_url from null, guards Windows machine-key cleanup with the server-issued authority ID, and gives a cold agent more time to enroll. Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Member
Author
|
Implementation notes (Phase 1: contract and conformance suite) Contents
Current results (Windows, local)
Dependencies
Suite decisions
Review Note LLM-assisted content (no human feedback). |
GitHub-hosted Windows runners run as the RID 500 administrator, which SDDL renders as LA, so the literal SID comparison rejected a correct DACL. Also declare the uuid serde feature the tester relies on. Issue: TBD Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Applies the Phase 1 gate clarifications C1-C13: enroll and renew key reuse, strict signature window, framework error bodies, creation-ordered listing, rotation limits, pending-file ownership and mock controls. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Implements contract v0.4 (C1-C14) in the mock: key-reuse rules, strict signature window, framework error bodies, creation-ordered listing, bounded rotation pushes, response-failure injection and channel events. Strengthens the tester per the Phase 1 gate verdict, including wire-level negatives, admin write authorization, boundary deadlines, make-before-break from event ordering, restart durability and C14 metadata checks. An incomplete run now fails unless --allow-incomplete. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The enrollment key must exist before enroll returns the authority ID and NCrypt keys cannot be renamed, so key names use a random key UUID. Also records the enrollment key across retries so a lost enroll response is recovered through idempotence. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Uses a per-run key name prefix for cleanup and orphan audits, adds the enrollment-key retry and revocation cases, source-valid cross-tag probes, full admin authorization coverage, per-send metadata overrides, exact rotation deadline checks with a frozen mock clock, and process-tree cleanup on outer timeouts. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…(C9) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Lets the Windows and Linux test jobs both finish while the agent identity conformance tests are expected to fail. To be reverted before the pull request leaves draft status. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Moves the hand-written RFC 9421 profile verifier, the channel-proof check and the CSR check into a pure oracle module with a narrow API and a small dependency set, independent of the httpsig crate used by the agent. Removes two unit tests already covered end to end by protocol tests, and creates the Unix key fixtures with mode 0600. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
C17 replaces promote-on-first-use with a POST confirm signed by the new key, the only operation that promotes a pending certificate. C18 moves the channel URL under config. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adopts contract C19 (config revisions, ConfigUpdate and the GET config fallback) and C20: the crate is now agent-channel-proto, the proto package devolutions.agent.channel.v1 and the NuGet package Devolutions.Agent.Channel. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Covers expiry recovery within grace, confirm-expiry recovery with the pending key, server concurrency guarantees, exact covered components, side-effect-free replay, deleted-token tombstones, per-token pending files, transport hardening, debug-build-only knobs, size caps and a 16 KiB metadata ceiling. Adds a two-digest-member renew vector. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
C32 makes check-in the only HTTP fallback for devices without a working agent channel; C29 is revised so the debug knobs apply in every build with a start-up warning. Replaces the config vectors with check-in ones. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…rding Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The agent identity crates that only have an INTENT.md so far would break the crates/* workspace glob; the exclusions go away when the crates land. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ue items Updates the mock and the conformance tester to contract v0.7: confirm as the only promotion point, check-in as the channelless fallback, config revisions pushed over the channel, early rotation completion, server concurrency and replay guarantees, per-token pending files, transport hardening and size caps. Removes the debug-build guard so the suite also runs against release builds, and a redundant Windows unit test. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Runs HTTP probes and channelless renewal and rotation independently of the channel, proves an invalid channel URL behaves as absent, tolerates unknown response fields and DVLS admin nulls, and checks lastSeenAt and config revision behavior without timing races. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fixes unused_mut on Linux: the agent process and the key set are only mutated in Windows-specific code. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds over-covered, reordered and duplicated component cases with the correct tag for each operation, all correctly signed and rejected. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Refreshes metadata on renew replays, checks key ACL principals instead of exact ACEs, narrows the identity tree audit to key material and leftover temporary files, and adds the missing pending-file, pending-key, channelless confirm, per-send metadata, transient-error, rotation, negative-matrix, covered-component and original-token cases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds the agent-identity-keys crate: P-256 device keys that never leave their backend, either non-exportable Microsoft Software KSP machine keys restricted to SYSTEM on Windows, or owner-only PKCS#8 files elsewhere. Keys expose typed RFC 9421 and CSR signers. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds the four valid requests with alg before keyid, the order the agent's signing library emits. RFC 9421 verifiers build the signature parameters from the received member, so the order is not significant. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Makes the elevated-only spike test fail with its observations so the result is visible in the CI log; to be reverted once read. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
RFC 9421 verifiers build the signature parameters from the received member, and the agent's signing library emits a non-template order. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds the agent-identity-httpsig crate: the RFC 9421 signing profile for renew, confirm, check-in and the agent channel opening, built on the httpsig crate with the device key, plus a tower layer that signs each channel opening and applies the authority's base path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…t in CI" The spike result is recorded: a non-SYSTEM administrator can read a SYSTEM-only machine key's DACL only through the creating handle, and cannot reopen the key by name afterwards. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Device keys can fail in the Windows key store, where Signer::sign would panic; a crate-level clippy rule makes try_sign mandatory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds the agent-identity crate: token parsing and redaction, CSR building, metadata collection, per-authority identity.json storage, pending enrollment files (Unix 0600, Windows DPAPI with protected DACLs and an administrator write-only drop box), rejected-token markers for permanent enroll outcomes, and the state lock. Removes its workspace exclude entry. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…din enrollment Runs the knob-off key-store subcase as SYSTEM through a scheduled task when the tester is an elevated administrator (not applicable otherwise), submits the token through the CLI, and audits keys, pending state and logs as SYSTEM before cleanup. Adds same-token replay cases after exhausted, invalid, malformed and revoked enrollments, and the interim identity enroll - case. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Adds the agent identity REST client (OS trust store plus an optional extra root, no redirects, typed contract errors) and a service task that enrolls each pending token independently with backoff, records permanent failures, and stores the resulting identity. Adds the Identity configuration section, the __debug__.identity controls with a start-up warning, and the identity enroll <token> command, which also reads the token from stdin when given -. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Devolutions Agent can obtain its own device identity from a management server such as Devolutions Server: a server-issued device ID and an X.509 certificate whose private key never leaves the machine.
One reusable enrollment token, deployable through
msiexecor Microsoft Intune, enrolls any number of machines.After enrolling, the agent renews its certificate on its own and keeps an authenticated, bidirectional gRPC channel to the server, so the server can reach the agent (for example, to ask it to renew).
This draft contains the product-neutral contract and its conformance suite; the agent implementation follows in the same PR:
docs/agent-identity/CONTRACT.md: the agent-facing HTTP API, the RFC 9421 request-signature profile, the gRPC channel and its proof-of-possession handshake, and the agent's local files and configuration.docs/agent-identity/test-vectors.json: shared signature, channel-proof and CSR vectors for every implementation.agent-identity-channel-proto: the channel schema for Rust, also published as theDevolutions.AgentIdentity.ChannelNuGet package for server implementers.agent-identity-mockandagent-identity-conformance: a mock server and a conformance tester that checks a server (the mock, or a real DVLS) and the agent against the contract; the testsuite runs both.