# Projects and credentials

Every CLI call relies on two things: your **account session** (who you are) and a **project's credentials** (which app you act on). This page explains where each comes from and how they work together.

```mermaid
graph LR
    login["getstream login<br/>once per machine"] --> session["account session<br/>who you are"]
    session --> init["getstream init<br/>once per project"]
    init --> creds["project credentials<br/>which app you act on"]
    creds --> cmds["everyday commands<br/>api, token, env, open"]
```

## Account session

`getstream login` runs a browser authentication flow with the [Stream Dashboard](https://getstream.io/signin/) and writes a session to `~/.stream/auth.yaml`. The session refreshes itself, so you only have to log in once per machine.

`getstream login --guest` creates a temporary guest account instead, backed by a throwaway app. It needs no browser or email, so it works for agents in non-interactive terminals and for trying the CLI before you sign up. Convert it to a real account later with `getstream login --upgrade`.

The account session is what lets the CLI find the organizations and apps you own. `getstream init` uses it to list your apps, and `getstream api --app-id <id>` uses it to act on any other app you own.

## Project credentials

`getstream init` links the current directory to one app and writes `.stream/creds.yaml`:

```yaml
# Stream app: acme-chat (1608483)
key: <api key>
secret: <api secret>
app_id: 1608483
```

`api`, `token`, `env` and `open` read this file. It holds the app's secret, so `init` adds `.stream/` to `.gitignore`. Do not commit it.

The CLI finds the credentials file `.stream/creds.yaml` the way git finds the `.git` folder: it starts in the current working directory and walks up, using the first file it finds.

## How credentials are resolved

The app-scoped commands (`api`, `token`, `env`, `import`) resolve their credentials in this order, first match wins:

1. **`--app-id <id>`** - act on any app your account session can reach, no project link needed.
2. **`STREAM_API_KEY` and `STREAM_API_SECRET`** - when both are set, the pair authenticates the command directly, with no project and no login. This is the natural fit for CI, where the key and secret already live in the secret store.
3. **The linked project** - `.stream/creds.yaml`, found by walking up from the working directory.

## Headless and CI

The interactive browser login flow can't run in CI, and a guest session can't reach your app. Export `STREAM_API_KEY` and `STREAM_API_SECRET` from your CI provider's secrets and the app-scoped commands work with no login and no project link. See [Use the CLI in CI](https://getstream.io/cli/docs/ci/).

The CLI also reads [`STREAM_BASE_URL`](https://getstream.io/cli/docs/commands/api/) and [`STREAM_HTTP_TIMEOUT`](https://getstream.io/cli/docs/commands/api/) for API calls, [`STREAM_CLI_CHANNEL`](https://getstream.io/cli/docs/installation/) for updates, `NONINTERACTIVE` to suppress every prompt (prompts are already suppressed when stdin is not a terminal), and `NO_COLOR` to disable colored output.

## See also

- [Authenticate the CLI](https://getstream.io/cli/docs/authentication/): the login flow and guest accounts
- [Use the CLI in CI](https://getstream.io/cli/docs/ci/): the headless credential path
- [Uninstall](https://getstream.io/cli/docs/uninstall/): remove everything the CLI wrote

---

For the most recent version of this documentation, visit [https://getstream.io/cli/docs/concepts/projects-and-credentials/](https://getstream.io/cli/docs/concepts/projects-and-credentials/).