---
title: "Authentication"
description: "Sign in to the BankSync CLI with a browser OAuth flow or an API key, use the BANKSYNC_API_KEY env var, manage profiles, and understand where credentials are stored."
section: "CLI"
canonical: "https://banksync.io/docs/cli/cli-authentication"
---

The CLI supports two ways to authenticate. Run `banksync login` with no flags to sign in through your browser using OAuth 2.1 (Authorization Code with PKCE over a loopback redirect); there is no key to copy. For CI, containers, scripts, and AI agents, use an API key instead by passing `--api-key` or setting `BANKSYNC_API_KEY`. An API key is the same credential the REST API and MCP server use, so a key that works for one works for all three.

[![Authenticate the BankSync CLI](https://cdn.banksync.io/videos/cli-quickstart.poster.5f7c1b212f341fe5.png)](https://cdn.banksync.io/videos/cli-quickstart.beab24a10f6ffdb2.mp4)

[Watch: Authenticate the BankSync CLI](https://cdn.banksync.io/videos/cli-quickstart.beab24a10f6ffdb2.mp4)

> **API keys are created in the dashboard:** The CLI never creates or revokes keys. Create one in the app under Settings > Developers, choosing the least-privilege scopes the command needs. See the API keys guide for scopes, expiration, and rotation. Every key starts with the bsk\_ prefix.

## Log in

Run `login` with no flags to sign in through your browser. The CLI starts a temporary loopback listener, opens the BankSync authorization page, and finishes once you approve:

```bash
banksync login
```

```text
Opening your browser to authorize BankSync CLI.
If it does not open, visit this URL:
  https://auth.banksync.io/authorize?...
Waiting for approval...
Logged in to Acme Inc (profile: default).
```

On a headless or SSH host with no browser, add `--no-browser` to print the URL so you can open it on another device:

```bash
banksync login --no-browser
```

### Log in with an API key

For CI, scripts, and agents, authenticate with an API key instead of the browser flow. The CLI validates it against your workspace, then stores it encrypted:

```bash
banksync login --api-key bsk_your_api_key_here
```

Only the `bsk_` prefix is validated locally, so a mistyped or non-BankSync key is rejected before anything is stored. You can also skip `login` entirely and set `BANKSYNC_API_KEY` (see below).

## The BANKSYNC\_API\_KEY environment variable

For CI, containers, and one-off invocations you do not have to run `login` at all. Set `BANKSYNC_API_KEY` and every command picks it up:

```bash
export BANKSYNC_API_KEY="bsk_your_api_key_here"
banksync banks list
```

You can also pass `--api-key` on a single command to override whatever is stored:

```bash
banksync banks list --api-key bsk_a_different_key
```

Credentials resolve in this precedence order:

1. The `--api-key` flag
2. The `BANKSYNC_API_KEY` environment variable
3. The stored credential for the active profile

## Check who you are

`whoami` shows the active credential's workspace, plan, and scopes:

```bash
banksync whoami
```

```text
authMethod    apiKey
workspaceId   ws_a1b2c3
workspaceName Acme Inc
planTier      professional
scopes        banks:read, feeds:read, jobs:write
```

Add `--json` for a machine-readable version, or run `banksync status` for a one-screen overview that also counts your banks and feeds.

## Log out

Remove the stored credential for the active profile:

```bash
banksync logout
```

This clears only the local credential; it does not revoke the key. To revoke a key, do it in the dashboard.

## Profiles

Profiles let you keep separate credentials and output preferences side by side, for example a personal workspace and a client workspace. Use `--profile` on any command, or set `BANKSYNC_PROFILE`:

```bash
banksync login --api-key bsk_client_key --profile client
banksync banks list --profile client

export BANKSYNC_PROFILE=client
banksync banks list
```

Profiles also carry non-sensitive display preferences (default output format, locale, time zone, color, telemetry). Manage them with `banksync config`:

```bash
banksync config set output json --profile client
banksync config list
```

> **The environment cannot be changed:** Config holds display preferences and profiles only. There is deliberately no base URL or
> environment setting: the released CLI always targets production. Attempting to set one is
> rejected.

## Where credentials are stored

Credentials live in an encrypted file, never in the plaintext config:

- Directory: `~/.config/banksync` on macOS and Linux (honoring `XDG_CONFIG_HOME`), and `%APPDATA%\banksync` on Windows. Override with `BANKSYNC_CONFIG_DIR`.
- `credentials.json`: your credential, encrypted with AES-256-GCM and written with `0600` permissions (owner read/write only). The encryption key is derived at runtime from a machine-bound value (your host name and user) via scrypt; no key material is written to disk. Because the key is machine-bound, a credentials file copied or backed up to another machine or user account cannot be decrypted there.
- `config.json`: profiles and display preferences (no secrets).

Secrets never touch the config file or logs. Under `--verbose`, the `X-API-Key` and `Authorization` headers are redacted.

> **API keys for headless use:** The browser flow is the quickest way to sign in interactively, but API key auth remains the
> recommended path for CI, scripts, and AI agents, which run headless. Pass --api-key or set
> BANKSYNC\_API\_KEY.

## Next steps

- [API keys](/docs/api/api-keys): create, scope, and rotate keys in the dashboard.
- [Scripting and CI](/docs/cli/scripting-and-ci): non-interactive usage and exit codes.
- [For agents](/docs/cli/for-agents): hand an agent the CLI plus a key.
