Skip to content

feat(agent): encrypt the token with DPAPI on Windows (#1) - #240

Open
Stephanya Casanova (savacano28) wants to merge 3 commits into
sca/secret-store-with-importfrom
sca/windows-dpapi-token
Open

Stephanya Casanova (savacano28) wants to merge 3 commits into
sca/secret-store-with-importfrom
sca/windows-dpapi-token

Conversation

@savacano28

@savacano28 Stephanya Casanova (savacano28) commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Proposed changes

Plugs a Windows DPAPI store into #245. Only active with [secrets] / os_store = true. Off by default: nothing changes for users (same as #239).

  • DpapiStore: the token is encrypted with DPAPI (user scope) in openaev-agent-token.dpapi, next to the exe. Only the account the agent runs as can decrypt it (SYSTEM for the service).
  • Flag on: at start, the agent moves the token from the config into .dpapi, reads it back, then removes the token line from the config.
  • The agent creates .dpapi with a restricted ACL: SYSTEM, Administrators and its own account, not inherited.
  • Installers: unchanged (same as main).
Flag Token Agent
off (default) config reads it on each request, as in #239; writes nothing
on moved to .dpapi decrypts it on each request; config line removed
off again, after a move .dpapi keeps reading .dpapi
sequenceDiagram
  participant A as Agent
  participant C as Config
  participant D as .dpapi
  A->>C: read token (os_store = true)
  A->>D: encrypt with DPAPI, read back
  A->>C: remove token line
  Note over A,D: each request decrypts .dpapi
Loading

Testing

Windows VM, PowerShell as Administrator, one clean VM per mode (service, service-user, session-user).

  1. Build: cargo build --release --locked, then makensis on installer/windows/*.nsi (or the CI artifacts). Pin the agent version on the platform (executor.openaev-agent.binaries.version).
  2. Flag off: install, or upgrade from main. Same as main: token in the config, no .dpapi, agent online, whoami inject OK.
  3. Flag on: add to the config, then restart the agent:
    [secrets]
    os_store = true
    Log Token moved to the OS secret store; .dpapi not empty, ACL without (I); no token line in the config; online.
  4. Restart: online, no new Token moved line.
  5. Flag off again: online (still reads .dpapi).
  6. Security: as Administrator (not SYSTEM), [Security.Cryptography.ProtectedData]::Unprotect([IO.File]::ReadAllBytes("<dpapi>"), $null, 'CurrentUser') fails with Key not valid. Searching the token in the log and the install folder returns nothing.
  7. Uninstall: the install folder is deleted, .dpapi included.

Full step-by-step plan: Notion "Manual tests: DPAPI (FF)".

Related issues

Checklist

  • I consider the submitted work as finished
  • I tested the code for its functionality
  • I wrote test cases for the relevant uses case
  • I added/update the relevant documentation (either on github or on notion)
  • Where necessary I refactored code to improve the overall quality
  • For bug fix -> I implemented a test that covers the bug

Further comments

Edge case Result
DPAPI fails during the move stays online on clear text, retries next start
DPAPI breaks after the move offline until reinstall
Service-user upgrade (exe swap only) token stays in config, error logged
Config read-only for the agent token moved, config line kept, warning
  • Limitations: admins and code running as the agent can still decrypt. A full disk copy without BitLocker can be decrypted offline. Resetting a local service-user password loses the key. Downgrade is not safe.
  • Attention: service-user ACLs are tighter than before, please test them.
  • Not included: Linux (systemd-creds), macOS (Keychain), migration for exe-swap upgrades.

Generated with Claude Code

@savacano28
Stephanya Casanova (savacano28) changed the base branch from main to sca/agent-secret-store October 12, 2026 13:47
@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 49.95%. Comparing base (def9b46) to head (79a76f6).

Additional details and impacted files

Impacted file tree graph

@@                      Coverage Diff                      @@
##           sca/secret-store-with-import     #240   +/-   ##
=============================================================
  Coverage                         49.95%   49.95%           
=============================================================
  Files                                16       16           
  Lines                              1011     1011           
=============================================================
  Hits                                505      505           
  Misses                              506      506           
Flag Coverage Δ
agent 49.95% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/secrets/mod.rs 57.14% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@savacano28
Stephanya Casanova (savacano28) changed the base branch from sca/agent-secret-store to sca/secret-store-with-import October 18, 2026 15:51
@savacano28 Stephanya Casanova (savacano28) changed the title feat(agent): encrypt the token with DPAPI on Windows feat(agent): encrypt the token with DPAPI on Windows (#1) Oct 18, 2026
@savacano28 Stephanya Casanova (savacano28) added the filigran team Item from the Filigran team. label Oct 19, 2026
@savacano28
Stephanya Casanova (savacano28) marked this pull request as ready for review October 19, 2026 07:12
Copilot AI balanced review requested due to automatic review settings October 19, 2026 07:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Security-sensitive DPAPI migration and file permissions require human validation across all three Windows installation modes.

No open issues 🎉

What changed in this PR

Adds Windows DPAPI token encryption using the secret-store migration flow introduced in #245.

Changes:

  • Enables account-scoped DPAPI storage on Windows.
  • Updates all three Windows installers to create restricted bootstrap and encrypted-token files instead of storing tokens in config.
  • Adds tests for encryption, tampering, in-place writes, and bootstrap migration.
File Description
src/​tests/​secrets/​mod.rs Registers DPAPI tests.
src/​tests/​secrets/​dpapi_tests.rs Tests DPAPI storage and migration.
src/​secrets/​mod.rs Enables the Windows secret store.
src/​secrets/​dpapi.rs Implements account-scoped encryption and storage.
installer/​windows/​agent-installer.nsi Creates restricted token files for SYSTEM.
installer/​windows/​agent-installer-session-user.nsi Creates token files accessible to the session user.
installer/​windows/​agent-installer-service-user.nsi Grants service-account access to token files.
Cargo.toml Enables required Windows API features.

Review effort: Balanced

@savacano28
Stephanya Casanova (savacano28) force-pushed the sca/windows-dpapi-token branch 6 times, most recently from edda1ff to ef6f801 Compare October 19, 2026 13:47
@savacano28
Stephanya Casanova (savacano28) force-pushed the sca/windows-dpapi-token branch 3 times, most recently from 0c68a02 to 5fb23f2 Compare October 19, 2026 15:48
@savacano28
Stephanya Casanova (savacano28) force-pushed the sca/windows-dpapi-token branch 4 times, most recently from 5d08817 to ad266c3 Compare October 20, 2026 13:11

@damgouj damgouj (damgouj) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will test but code seems OK to me. 1 question and 1 remark:

  • is the performance still the same because it gets each time the token from the secret store?
  • the agent size is now 200ko bigger, be careful if we do this for the implant because it's downloaded for each attack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

filigran team Item from the Filigran team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants