---
title: Sign in and configure
description: Device login, choosing a project, tokens, the config file and the variables that override it.
order: 1
---

## Log in

```sh
ops login
```

`ops` prints a code and a link. Open the link in a browser where you are signed in to the
console, check that the code matches, choose the role the machine gets and, if you like,
pin it to one project, then approve. The terminal prints who you are signed in as, whether
the token is pinned, and when it expires. The token is written to the config file and
printed nowhere.

| option | effect |
| --- | --- |
| `--project <slug>` | asks for a token pinned to one project. The approver decides |
| `--mcp` | marks the token as one for an MCP client, see [MCP](mcp.md) |
| `--url <base>` | signs in to another ops than the default |

A token never carries more than the person who approved it holds.

## Choose a project

```sh
ops use rungholt
```

Most commands act in one project. `ops use` checks the slug against your projects and
writes it to the config file. `OPS_PROJECT` overrides it in a shell that sets it.

## Who am I

```sh
ops whoami
```

Prints who the token acts as, what it may do, and the memberships of the person behind it.
On a build machine this is how you see what its token really carries.

## Tokens

```sh
ops tokens                 # the tokens you hold: id, name, kind, project, expiry, last use
ops tokens revoke <id>     # revoke one
ops logout                 # revoke this machine's token and forget it
```

## The config file

`~/.config/ops/config.json`, readable by you alone, holds three keys:

```json
{ "url": "https://ops.syncronet.dev", "token": "opst_...", "project": "rungholt" }
```

| variable | what it does |
| --- | --- |
| `OPS_API_URL` | the address of ops. Overrides the file's `url` |
| `OPS_TOKEN` | the token. Overrides the file's `token`, so CI needs no file |
| `OPS_PROJECT` | the project. Overrides the file's `project` |
| `OPS_CONFIG_FILE` | another config file, named as a file and not a directory |
| `XDG_CONFIG_HOME` | moves the config directory, so the file is `$XDG_CONFIG_HOME/ops/config.json` |
| `OPS_TIMEOUT_SECS` | how long one call waits for ops before it gives up |

The environment always wins over the file.

## In CI

Mint a token for the pipeline in the console and set it as a CI secret:

```sh
export OPS_TOKEN="$OPS_TOKEN_FROM_CI"
export OPS_PROJECT=rungholt
ops deploy web --commit "$GIT_SHA"
```
