The credential
sink login stores your API key in the OS keychain — Keychain on macOS, Secret Service on Linux, Credential Manager on Windows. Nothing about it goes into the config file.
Where no keychain backend is available, the key falls back into the config file itself, which is written mode 0600. sink login says which of the two happened, and sink whoami reports it under Credential.
~/.config/sink/config.json
XDG_CONFIG_HOME when set, so the default is ~/.config/sink/ on Linux and macOS.
The link file
sink init writes .sink.json into the current directory:
.sink.json
pull, push and diff find it by walking up from the working directory, so it can live at the repository root and still serve a command run three folders down.
If the file is missing an id, the CLI says which section and tells you to re-run sink init rather than guessing.
Environment variables
Provider tokens are read for the one request that needs them and are never written to the config file or the keychain.
Resolution order
1
API key
SINK_API_KEY → config file (when the key lives there) → OS keychain. Nothing found means “not logged in”, and the command stops.2
API URL
SINK_API_URL → --api-url as stored by sink login → the built-in default.3
Scope
Command flags →
.sink.json from this directory or a parent — and, for the environment, the argument you passed → the linked default.Files the CLI writes
Installing without the installer
The one-line installer verifies the wheel against the deployment’s manifest and linkssink into ~/.local/bin. To manage it yourself instead, install the published wheel with your own Python tooling:
GET /cli/manifest.json names the current version and its checksum.