Skip to content

Biometric gate for high-security master CLI actions (pairing, revocation, restore) #11

@hanwencheng

Description

@hanwencheng

Summary

On the master CLI side, high-security actions should require biometric confirmation (Touch ID / Windows Hello / fprintd) before proceeding. This applies to actions that have irreversible or high-blast-radius consequences. On the child/agent side, all operations stay silent (no biometric prompts — agents run unattended).

Actions that should be biometric-gated

Action Why it's high-security Current auth Proposed auth
agentkeys approve <pair-code> Creates a new child session with credential access. A social-engineering attack could trick the user into approving a malicious daemon. Interactive y/N prompt Biometric + y/N
agentkeys revoke <agent> Immediately kills an agent's session. Irreversible — the agent loses all access. Accidental revocation is disruptive. Session bearer only Biometric confirmation
agentkeys teardown <agent> Deletes all credentials and revokes all sessions for an agent. Destructive and irreversible. Session bearer only Biometric confirmation
agentkeys init --force Replaces the current master session. If done accidentally, the old session is orphaned. Session bearer only Biometric confirmation
Recovery flow (future) Re-associates credentials with a new daemon. High-value because it grants access to all previously-stored credentials. TBD Biometric required

Actions that stay silent (no biometric)

Action Why it's OK to stay silent
agentkeys store Writing a credential — the user is actively providing the value
agentkeys read Reading a credential — gated by session scope + rate limit + audit
agentkeys run Injecting credentials into a child process — same as read
agentkeys usage Read-only audit query
agentkeys whoami Read-only session metadata
agentkeys link Adding an alias — low blast radius
All daemon/agent MCP operations Must be silent for unattended agent execution

Implementation

macOS

Use kSecAttrAccessControl = kSecAccessControlUserPresence or LocalAuthentication framework (LAContext.evaluatePolicy(.deviceOwnerAuthentication)). Touch ID prompt with fallback to device passcode.

Linux

Use fprintd via D-Bus, or polkit for password-based confirmation. Gracefully degrade to interactive password prompt if fingerprint reader is not available.

Windows

Use Windows Hello via KeyCredentialManager API. Fallback to PIN.

Cross-platform abstraction

The biometric check should be a single function: require_biometric(reason: &str) -> Result<()> that:

  • Returns Ok(()) if the user confirms
  • Returns Err if denied or unavailable
  • On unsupported platforms or in --yes / CI mode: skips with a warning

Child/agent side

No biometric. Period. Agents run unattended. The daemon authenticates via its session bearer token (TEE-verified). Biometric gating is master-CLI-only.

Priority

This is a post-MVP hardening item, not required for v0 or v0.1 initial deployment. Should ship before the master CLI is used by non-technical users in production, where social engineering attacks (fake pair codes, accidental revocations) become a real risk.

Dependencies

  • Requires LocalAuthentication framework on macOS (Rust bindings via security-framework or core-foundation)
  • Requires fprintd / polkit on Linux
  • Can be implemented as a standalone crate (agentkeys-biometric) to keep platform-specific code isolated

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions