Feather API

Team vault

Your secrets travel through us. We still cannot read them

Team shares environment variables between teammates, encrypted end to end. Every value is locked on your laptop and unlocked only on an approved teammate's device. Our server stores and relays ciphertext. It never holds a private key, an unwrapped environment key, or a single plaintext variable.

What the server sees, and what your team sees

stored on featherapi.comenv 3f2c… k=4 v=17
{
  "payload": "{\"id\":\"3f2c9a1e-…\",\"k\":4,\"v\":17,
    \"nonce\":\"u8Qw1xVb0kN3pZr7Ye5cTgH2mLa9sDfJ\",
    \"ct\":\"q3Vx9Lk0+aRZt7fW2mYc1EhN8pQ4bG6s
    J0vXk5T/wIoL3yRe9UaPd7Mz2nHc4Bq1Sf8
    Kx6Wg0Nt5Ev3Ly9Oj2Ci7Ap4Ds1Fu8Hr6Zm0\"}",
  "signer": "Vd3Kp9xQ2mT7…",
  "sig": "Hq8Zr1Ln4Wc6Yb0Tf3Xs…"
}

XChaCha20-Poly1305 ciphertext, signed by the author. The server checks version numbers, nothing more.

on an approved devicestaging
STRIPE_SECRET_KEY=sk_live_51NxQ2aLk…
DATABASE_URL=postgres://app:h7Tq…@db.internal/app
SENDGRID_API_KEY=SG.x4Vq…
API_BASE=https://staging.example.com

Decrypted locally and merged into your git-ignored env.sqlite. Never written into the repo.

Approve with a code, not with trust in us

A new laptop, or a new teammate, shows a 10-character code. Read it to someone already on the team, in person or over chat. They type it in and the device is in.

  • The code never goes to our server. Only a MAC keyed by it does.
  • If a server swapped in its own keys, the MAC would not match and the approval fails.
  • The code is hardened with Argon2id at 64 MiB per guess. Brute-forcing 250 of those is out of reach, for anyone, including us.
  • Membership is a signed, hash-chained log. Every app replays it and rejects the whole team state if one entry fails.
Approve devicepending

ada-thinkpad (Linux) wants to join acme

K7QM-3XRP-2W

Fingerprint 9f2a 41c7 e0b3 5d18 a6f4

ApproveReject

When someone leaves, the key rotates

Remove a teammate, or revoke a lost laptop, and the next app to sync generates a new environment key, re-encrypts the contents and wraps the new key only to the devices still on the team. Usually that is the remover's app, at once.

Honestly: nothing can make someone forget a value they already saw. The app tells you which secrets they had, so you can rotate them at the source.

  1. seq 12 remove bob, signed by admin
  2. env staging k=4 wrap found for a removed device
  3. rotate generate k=5, re-encrypt
  4. wrap k=5 to 6 devices of 3 members
  5. done bob's devices receive nothing new

The primitives

UsePrimitiveWhere it lives
Identity signaturesEd25519One per person, in the OS keychain
Key agreementX25519One per device, never leaves it
EncryptionXChaCha20-Poly1305Random 24-byte nonce per message
Key derivationHKDF-SHA256Wrapping env keys to each device
Hash chain, fingerprintsSHA-256Team membership log
Human codesArgon2id, m=64 MiB, t=3, p=1Approval codes and the recovery code

Lose every device? At setup the app shows a 26-character recovery code (128 bits). Your identity is stored on our server encrypted under it, so only the code opens it.

Threat model, plainly

What we protect against
  • A breach of our database, or us, reading your secrets
  • A server forging values or handing out a key it made up
  • A server quietly adding itself or anyone else to your team
  • A removed teammate or revoked laptop receiving new values
What no one can
  • A teammate forgetting values they already saw. Rotate them at the source
  • A compromised teammate device
  • Traffic analysis: the server sees sizes, times and who is on which team
  • The server withholding or delaying data. It cannot read it, but it can stall

Share secrets without sharing them with us

Team is $10 per user a month, billed annually ($120 a year per user). Everything in Basic for everyone on the team, plus the vault.