Skip to content

Revoke Access

Remove an identity from a secret’s recipient set, and understand why rotation is what actually invalidates the value.

  1. Check who can decrypt the secret

    The recipient set lives in the available_to field, which --all --json exposes (newest entry first):

    Terminal window
    dotsecenv secret get API_KEY --all --json | jq '.[0].available_to'
    # ["YOUR_FINGERPRINT", "TEAMMATE_FINGERPRINT"]
  2. Revoke the identity

    Remove a fingerprint from the recipient set for future writes:

    Terminal window
    dotsecenv secret revoke API_KEY TEAMMATE_FINGERPRINT

    Revoke from every vault that holds the secret with --all:

    Terminal window
    dotsecenv secret revoke API_KEY TEAMMATE_FINGERPRINT --all
  3. Rotate the value

    Store a fresh value. The new entry is encrypted only to the remaining recipients:

    Terminal window
    echo "new-secret-value" | dotsecenv secret store API_KEY
  4. Confirm the new entry excludes them

    Terminal window
    dotsecenv secret get API_KEY --all --json | jq '.[0].available_to'
    # ["YOUR_FINGERPRINT"]
  5. Update systems and commit

    Roll the new value out to whatever consumes it, then commit:

    Terminal window
    git add vault
    git commit -m "Revoke API_KEY access and rotate"
    git push
  • The revoked teammate cannot decrypt the new value.
  • The revoked teammate can still decrypt the old value from vault history.
  • secret get for the revoked teammate falls back to the most recent entry they were a recipient of (the pre-rotation value), and secret get --all produces decryption errors for the rotated entry they no longer hold a key for.

Example 02 shows exactly this: after revoke + rotate, Bob’s secret get prints the old value, and his secret get --all warns it cannot decrypt the rotated entry that was only ever encrypted to Alice.

Revocation preventsRevocation does NOT prevent
Decrypting future valuesDecrypting values already shared
Membership in new entriesReading old entries from vault history
Reading rotated valuesCopies of values they already decrypted
  1. GPG is asymmetric: once a value is encrypted to a key, only that key decrypts it.
  2. The vault is append-only: old entries stay readable to their original recipients, including in the repo’s git history.
  3. There is no time travel: you cannot retroactively change who could decrypt a past value.
  1. Rotate the secret after revoking.
  2. Treat revocation as the trigger to change the value at its source.
  3. Update downstream systems with the new credentials.

secret revoke takes one secret name per call. To strip an identity from all of them, loop over the key list that secret get (no arguments) prints:

Terminal window
for s in $(dotsecenv secret get); do
dotsecenv secret revoke "$s" FINGERPRINT --all
done

Then rotate each value, since the revoke alone leaves prior ciphertext intact.

The vault keeps full history. Inspect who was a recipient of each version:

Terminal window
dotsecenv secret get API_KEY --all --json | jq '.[] | {added_at, available_to, signed_by}'

For the full runbook covering scope inventory, batch revoke, source rotation, and error handling, see Offboard a Departing Team Member.

At a glance:

Terminal window
FINGERPRINT="THEIR_FINGERPRINT"
# 1. Revoke from every secret in every vault
for s in $(dotsecenv secret get); do
dotsecenv secret revoke "$s" "$FINGERPRINT" --all
done
# 2. Rotate each secret at its source (production-critical first)
echo "new-prod-db-password" | dotsecenv secret store DATABASE_PASSWORD
echo "new-prod-api-key" | dotsecenv secret store API_KEY
# ... continue for staging and dev
# 3. Confirm the leaver is gone from every current recipient set
dotsecenv vault describe --json \
| jq --arg fp "$FINGERPRINT" \
'.[].secrets[] | select((.available_to // []) | index($fp)) | .key'
# (empty output means the revoke took effect)
# 4. Commit
git add vault
git commit -m "Offboard: revoke access for $FINGERPRINT"
git push

Can they still read secrets?

If they kept the old vault file, they can still decrypt every entry their fingerprint was a recipient of. That is the append-only contract, and it is why rotating the value is the real fix.

Vault getting large?

Old entries accumulate. Check vault health and optionally defragment:

Terminal window
dotsecenv vault doctor