Stop keeping client credentials in Notes
If you freelance or work at an agency, you probably have a note for each client. The staging URL, the SSH host, the database password, the Stripe test key, the WordPress admin login, the name of the person who approves deploys. It is quick to write, easy to search and always open.
It is also where credentials go to leak. Here is why, and what to do instead. Most of it needs nothing but the tools you already have.
What goes wrong
The note is plain text. Most note apps sync your notes in a form the provider can decrypt, unless you turn on an extra setting or lock the note. Check yours. A leak at the provider, a stolen laptop with the account signed in, or a shared folder you forgot about all expose every client at once.
It ends up on screen. You open the note on a call to read out a hostname, and the database password is two lines below it. Screen recordings and screenshots keep it.
It ends up in your shell history. You copy the password, then type export DB_PASSWORD=… to run a migration.
Now it is in ~/.bash_history or ~/.zsh_history, in plain text, for as long as you keep that file.
It goes stale. The client rotates a key and tells you in a chat message. The note still has the old one, and the new one lives in the chat.
It is hard to give back. When the contract ends you should delete what you hold. If it is spread across notes,
chats and .env files in old project folders, you will miss some.
Six changes you can make today
1. Put real secrets in a password manager
Passwords, API keys and tokens belong in 1Password, Bitwarden or KeePassXC. Make one vault or folder per client. Their CLIs can hand a secret to a command without you copying it:
op read "op://Acme/Staging DB/password"
# .env holds op:// references, not values
op run --env-file=.env -- php artisan migrate
bw get password "Acme staging DB"
2. Keep secrets out of your shell history
Read a value without echoing it, and start a line with a space when you must type a secret:
read -rs DB_PASSWORD && export DB_PASSWORD
# ~/.bashrc: lines that start with a space are not saved
HISTCONTROL=ignoreboth
# ~/.zshrc: the same for zsh
setopt HIST_IGNORE_SPACE
3. Keep .env files out of Git everywhere
Add a global ignore file once, so a new project cannot commit one by accident. Git reads
~/.config/git/ignore without any setup:
mkdir -p ~/.config/git
printf '.env\n.env.*\n!.env.example\n' >> ~/.config/git/ignore
4. Turn on clipboard clearing
Most password managers can clear the clipboard a short time after you copy a secret. Turn it on. If you use a clipboard history tool, exclude your password manager from it, or every copied password stays in the history.
5. Keep the rest of the context next to the work
Not everything in that note is secret. URLs, hostnames, deploy commands, the contract end date and who to ask
are context, and they are most useful next to the task that needs them. A short README in the repo or a
section in your task list works. The point is to split the note in two: secrets go in the vault, context goes
where you work.
6. Plan the offboarding on day one
One vault per client and one place for its context means the end of a contract is one delete. When it ends, delete both, remove your SSH keys from their servers and ask the client to rotate anything you had.
Where ShellTasks fits
We are building ShellTasks for the gap between steps 1 and 5: keyboard-first tasks where each one can carry its
context in a #pack. A pack per client environment holds typed fields: text, URLs, commands, dates and secrets.
tsk env acme-staging prints them as a .env, and tsk exec acme-staging -- php artisan migrate passes them to
a command without writing a file.
The apps and tsk are not released yet. In them, secret fields will be encrypted on your device before they sync, so our
server only ever stores ciphertext. That ships with the beta. Until then, keep real secrets in your password
manager. The security page says what the server will and will not see, and what is not built yet.
You can try the input bar, packs and a simulated tsk now, in your browser, with no account. The
client project template is a good place to start.
Try ShellTasks in your browser. If it fits how you work, join the waitlist and we will email you when the beta opens.