keyrotate

Security Posture

Document 01 of 5 · Last reviewed:

This document explains what keyrotate does with your secrets and what it explicitly does not do.

What keyrotate does

What keyrotate never does

Where secrets travel during a rotation

  1. From your terminal's hidden-input prompt into the running keyrotate process (in memory).
  2. To the provider's verification endpoint, over HTTPS, via a single authenticated request (e.g. GET https://api.openai.com/v1/models).
  3. To each destination's API or CLI: 1Password (via op CLI with stdin pipe), GitHub (via gh secret set with stdin pipe), Supabase, Netlify, Fly.io (via their CLIs), .env files (written with mode 0600).
  4. Out of memory when the process exits.

Some destination CLIs (Supabase, Fly.io) accept secrets as command-line arguments rather than stdin; that means the value is briefly visible to ps on the local machine while the destination CLI is running. This is a limitation of the upstream CLI, not keyrotate. Patches to use management APIs directly are welcome.

1Password integration

keyrotate uses the official op CLI, which authenticates via your system's biometrics (Touch ID on macOS, Windows Hello on Windows). keyrotate never sees your 1Password master password or session token; it shells out to op and pipes the secret over stdin.

Local file permissions

Threat model — what keyrotate is and isn't designed to defend against

Designed for: reducing the number of manual steps in a rotation, eliminating the "I forgot to update Supabase" failure mode, and verifying the new key actually works before the old one is revoked.

Not designed for: defending against a compromised local machine. If an attacker has root or code execution on the machine running keyrotate, they can read the audit log, read .env files, and intercept secrets as they pass through memory. keyrotate assumes a trusted local environment.