---
title: "Authentication"
description: "Log in to ezgh with your account, or use an API key for code and CI."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ezghcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

`ezgh` sends one credential with every request: an OAuth login for people, or an [API key](/iam/api-keys) for code and CI. Either one acts with exactly its owner's IAM access. Each [profile](/cli/profiles) keeps its own credential.

Commands use, in order:

1. `EZGH_API_KEY`, when it's set.
2. The active profile's stored credential: its login, or an API key stored with `ezgh auth set-api-key`.

Without either, commands exit with code `3`.

## Log in

```sh
ezgh login
```

`ezgh login` opens your browser at the EZGH Cloud sign-in page, where you sign in and approve access for `ezgh`. The browser then returns to `ezgh` on your computer, at `http://127.0.0.1` on a random port. `ezgh` also prints the URL it opens, and waits up to 5 minutes for you to finish.

- `--no-browser` prints the URL without opening a browser.
- Use `--device` over SSH, or on any machine without a browser.

### Log in on another device

```sh
ezgh login --device
```

`ezgh` prints `https://login.ezghcloud.com/device` and a code. Open the URL on any device where you can sign in, enter the code, and approve. The code expires after 15 minutes.

### What a login can do

A login acts as you, with your IAM access, like the console. It can also do what API keys can't:

- Create API keys (`ezgh iam api-keys create`).
- See, accept and decline your own invitations (`ezgh invitations`), and leave your organization (`ezgh orgs leave`).

Deleting an organization and handing over the root user are available only in the console.

### How long a login lasts

`ezgh` refreshes the login's access token by itself when it expires, which is every hour. A login stays valid while you use `ezgh` with it at least once every 30 days, until you log out or the login is revoked.

## Check which credential is used

```sh
ezgh auth status
```

```text
Profile:     ci (from --profile)
Domain:      ezghcloud.com
Credential:  API key ezgh_Ab3dE6… stored in the profile
Stored in:   the macOS Keychain
```

`ezgh auth status` reads only what's stored on your computer. `ezgh whoami` asks the platform who the credential acts as: the organization, the user or bot, and whether it's the root user.

`ezgh` never prints a credential. It shows at most an API key's first 11 characters.

## Use an API key

Create a key while logged in, in the console or with the CLI. For CI, create a [bot](/iam/bots) with only the policies it needs, and a key for the bot:

```sh
ezgh iam bots create deployer
ezgh iam policies attach ReadOnlyAccess --bot deployer
ezgh iam api-keys create ci --bot deployer --expires-in-days 90 > ci-key.txt
```

The key is printed once, on standard output. See [API keys](/iam/api-keys).

### In an environment variable

Set `EZGH_API_KEY`. It takes precedence over the active profile's credential:

```yaml
# GitHub Actions
- run: ezgh projects list -o json
  env:
    EZGH_API_KEY: ${{ secrets.EZGH_API_KEY }}
```

### In a profile

`ezgh auth set-api-key` stores a key as a profile's credential. It reads the key from standard input, never from an argument, and checks it before storing it unless you pass `--no-verify`:

```sh
ezgh auth set-api-key --profile ci < ci-key.txt
```

On a terminal, it asks you to paste the key and doesn't echo it. The profile is created if it doesn't exist.

## Where credentials are stored

| System | Store |
| --- | --- |
| macOS | The macOS Keychain |
| Linux | The Secret Service keyring |
| Windows | The Windows Credential Manager |

Entries use the service name `ezgh-cli` and the profile's name as the account. Where no keychain is available, such as in CI, containers or SSH sessions without a desktop session, credentials go in `credentials.json` in the [configuration directory](/cli/profiles#configuration-directory), readable only by you.

`EZGH_CREDENTIAL_STORE` chooses the store:

| Value | Store |
| --- | --- |
| `auto` | The keychain when it's available, otherwise the file. The default |
| `keychain` | The keychain only. Commands fail if it isn't available |
| `file` | `credentials.json` only |

## Log out

```sh
ezgh logout
```

`ezgh logout` revokes the active profile's login, which ends it on every computer it was copied to, and deletes its stored tokens. If revoking fails, for example because the platform can't be reached, the tokens are still deleted, and `ezgh` exits with code `1`.

- `--profile <name>` logs out of one profile, and `--all` logs out of every profile.
- For a profile with a stored API key, `ezgh logout` only deletes the key from your computer. The key keeps working until you revoke it with `ezgh iam api-keys delete`.
- `ezgh logout` doesn't change `EZGH_API_KEY`. Unset it yourself.

Source: https://docs.ezghcloud.com/cli/authentication/index.mdx
