Skip to main content
The CLI keeps two separate things on disk, deliberately in different places: the credential, which belongs to a machine, and the link, which belongs to a repository.

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
The directory follows XDG_CONFIG_HOME when set, so the default is ~/.config/sink/ on Linux and macOS. sink init writes .sink.json into the current directory:
.sink.json
Ids and display names, no values — safe to commit, and meant to be. 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

0600 keeps a pulled .env away from other users on the machine. It does nothing about version control or Docker build contexts — add .env to .gitignore and .dockerignore yourself.

Installing without the installer

The one-line installer verifies the wheel against the deployment’s manifest and links sink 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.