We've been building CLIs for a while now, and one challenge that consistently comes up is securely storing user credentials. While you can definitely roll your own, we've found that the tried-and-true `.netrc` file offers a robust and widely-supported solution.

## Why .netrc?

We chose `.netrc` for our CLI implementations because:

1. It's a well-established standard that's been around since the Unix days
2. It has built-in support in many tools (curl, git, etc.)
3. Most programming languages have libraries for handling it
4. It provides a consistent user experience across different platforms

## Understanding .netrc

The `.netrc` file lives in your home directory:

- Unix/Linux/macOS: `~/.netrc`
- Windows: `~/_netrc`

The file follows a simple, machine-oriented format:

```bash
machine api.example.com
    login your-username
    password your-secret-token

machine api2.example.com
    login different-user
    password different-token
```

You can also write it in a single line if you prefer:

```
machine api.example.com login your-username password your-secret-token
```

## Programmatically mutating the .netrc file

Most major languages have libraries supporting accessing and mutating a .netrc file. If you’re using golang, I can recommend [jdxcode/netrc](https://github.com/jdxcode/netrc), as the standard library implementation is only internal.

However, since this is just a file, you can easily echo and append (>>) as well.

[Here's](https://gist.github.com/nadeesha/0df80eebf27fd1056d57084e4e39c7c4) a straight-forward, zero-dependency gist on how we use this in our CLI.

## Safety

The obvious disclaimer here is that storing sensitive data in clear-text anywhere in your computer is inherently unsafe than some other means.

And anyone accessing your computer being able to cat ~/.netrc is going to get access to your credentials.

In any case, it’s a good practice to maintain the file with the minimum required permissions, as you’d with your SSH keys. (Typically chmod 600)
