# Authentication

Every API call except a few public ones needs an API key, sent as a bearer token:

```
Authorization: Bearer gf_...
```

```bash
curl -s "https://api.gpuforge.io/v1/billing" -H "Authorization: Bearer $GF_KEY"
```

## Signing in

You sign in to the console at [console.gpuforge.io](https://console.gpuforge.io) with **Google** or **GitHub**. GPU Forge never sees your Google or GitHub password. A returning sign-in is matched on the identity provider's own account id, not on your email address, so changing your email changes nothing.

A console sign-in lasts 30 days.

## API keys

An API key lets a script, an agent or the CLI act for your account.

| Property | Value |
|---|---|
| Format | `gf_` followed by a random string |
| Shown | Once, when it is created. It cannot be read back. |
| Stored by GPU Forge | Only as a fingerprint (a one-way hash) |
| Expires | No; it works until you revoke it |
| Sees | Only your own account's programs, machines, jobs, billing and notifications |

### Create a key

Keys are created by you, signed in on the console: **API keys → Create**, or **Guide → Make a key for my agent**. Give each project or agent its own key, so you can revoke one without touching the others.

### Revoke a key

Revoke a key on the console (**API keys**). Revocation stops every new request made with that key at once. Work already accepted (a running machine, a queued job) is not stopped by revoking the key; stop it separately if needed.

A key can also revoke **itself**:

```bash
curl -s -X POST "https://api.gpuforge.io/v1/cli/logout" -H "Authorization: Bearer $GF_KEY"
```

```json
{"revoked": true, "key_id": "key_..."}
```

### Check which account a key belongs to

```bash
curl -s "https://api.gpuforge.io/v1/cli/whoami" -H "Authorization: Bearer $GF_KEY"
```

```json
{"admin": false, "user_id": "usr_...", "key_id": "key_...", "name": "Ada Example", "email": "ada@example.com"}
```

You need the `user_id` when you create a capability.

## What a key may and may not do

There are no per-key scopes: every API key has the same rights over its own account. Some actions are reserved for **you, signed in on the console**, so that an agent holding a key can never do them:

| Action | API key | Signed in on the console |
|---|---|---|
| Run jobs, start, scale, park, wake, release and destroy machines | Yes | Yes |
| Create and change capabilities | Yes | Yes |
| Read balance, usage, top-ups, notifications | Yes | Yes |
| Top up from the saved card (`POST /v1/billing/top-up`) | Yes, within the daily cap | Yes, not capped |
| Save or remove a card | No | Yes |
| Set automatic top-up and the daily cap | No | Yes |
| Create, list or revoke API keys | No (a key may revoke only itself) | Yes |
| Approve a CLI login | No | Yes |

## The CLI login

The `gpuforge` command-line tool signs in through your browser, like other developer CLIs:

1. `gpuforge login` starts a login (`POST /v1/cli/login`, no key needed) and opens a page on the console showing a short code such as `ABCD-EF23`.
2. You check the code matches, and press **Approve** while signed in.
3. The CLI polls `POST /v1/cli/login/poll`. After approval it receives a new API key, once, and saves it to `~/.config/gpuforge/config.json` (readable only by you).

A login code expires after 10 minutes. `gpuforge logout` revokes the key on this computer. See [Command-line tool](cli.md).

## Program keys (on your own machine)

When you add a ready program to your account (`POST /v1/catalog/{program_id}/add`), you also get a **program key** (`gf_api_key`, starting with `gfv_`). It is different from your API key:

| | API key (`gf_...`) | Program key (`gfv_...`) |
|---|---|---|
| Opens | The GPU Forge API | The program's own API on your machine |
| Sent to | `https://api.gpuforge.io` | `<capability_url>` of your machine |

The program key is shown once. You can set a new one on your copy of the program; machines started after the change use it:

```bash
curl -s -X PATCH "https://api.gpuforge.io/v1/capabilities/<your copy id>" \
  -H "Authorization: Bearer $GF_KEY" -H "Content-Type: application/json" \
  -d '{"secrets": {"env": {"GF_API_KEY": "<a long random string>"}}}'
```

You can also make a program key on the console (**Guide → New program key**).

## Keeping keys safe

- Never put a key in client-side code, a public repository or a URL.
- Use one key per project or agent, and revoke keys you no longer use.
- If you think a key has leaked, revoke it on the console at once and tell [support@gpuforge.io](mailto:support@gpuforge.io).

## Authentication errors

| Status | Meaning |
|---|---|
| `401` | No bearer token was sent (`missing bearer token`). |
| `403` | The key is unknown or revoked (`invalid API key`, `invalid or revoked API key`), the console sign-in has expired, or the action is reserved for the person signed in on the console. |
| `404` | The resource does not exist **or belongs to another account**. GPU Forge does not reveal which. |
