# Authenticating

Connect with a profile: your API key, base URL and workspace, stored in the config file that
Nominal’s other clients also read.

If Nominal’s Python client or CLI already works on this machine, you have a profile already, so
skip to [Connecting](https://dev.nominal.io/matlab/guides/authenticating.md#connecting). Otherwise, set one up.

There is a one-time setup of API-keys required to use Nominal clients. There are 2 steps:

## 1. Copy your keys

Visit your [API keys](https://app.gov.nominal.io/settings/org/api-keys) page in the cloud Nominal app, and copy three values.

[![The API keys page in Nominal settings, with the Create key button marked 1, the Copy URL button marked 2, and a workspace's Copy RID button marked 3](https://dev.nominal.io/matlab/_images/api-keys.png)](https://dev.nominal.io/matlab/_images/api-keys.png)

There are 3 values:

1. **API key:** Click **CREATE KEY**, give the key a name, set an expiration, and click **GENERATE KEY**. Note, this is only shown once.
2. **Base URL:** Find **API URL** and click **COPY URL**.
3. **Workspace RID:** Find your workspace and click **COPY RID**.

## 2. Store them with a command line tool

Nominal provides two command line tools, a [Rust-based](https://github.com/nominal-io/nominal-client-rs#nomctl-cli) one, `nomctl`, and a [Python-based](https://github.com/nominal-io/nominal-client#-install) one. Use `nomctl` unless you already use the Python client or IT restrictions make the Python CLI easier to install.

**Rust: nomctl**

To install, run:

**Windows**

In PowerShell:

```powershell
irm https://raw.githubusercontent.com/nominal-io/nominal-client-rs/main/scripts/install.ps1 | iex
```

The installer also adds nomctl to your `PATH`.

**Linux**

```bash
curl -fsSL https://raw.githubusercontent.com/nominal-io/nominal-client-rs/main/scripts/install.sh | sh
```

If you get an error that `nomctl` is not found when running the steps below, either call `~/.local/bin/nomctl` directly or add `~/.local/bin` to your `PATH` and open a new terminal:

```bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
```

**macOS**

```zsh
curl -fsSL https://raw.githubusercontent.com/nominal-io/nominal-client-rs/main/scripts/install.sh | sh
```

If you get an error that `nomctl` is not found when running the steps below, either call `~/.local/bin/nomctl` directly or add `~/.local/bin` to your `PATH` and open a new terminal:

```zsh
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
```

Finally, to create the credential file using the three credentials collected above, run:

```shell
nomctl config profile add default -t <1:api-key> -u <2:base-url> -w <3:workspace-rid>
```

To check the profile was saved:

```shell
nomctl config profile list
```

> **Tip**
>
> `nomctl config init` creates the profile interactively instead, and lets you pick your workspace from a list rather than pasting its RID.

**Python: nominal.cli**

To install, run `pip install nominal`. If your system Python blocks `pip install`, as on some Linux distributions and with Homebrew’s Python on macOS, install into a virtual environment, or use `uv tool install nominal` or `pipx install nominal` and run `nom` in place of `python -m nominal.cli` below.

Then, using the three credentials collected above, run the first command below. The second checks the profile was saved.

**Windows**

```powershell
python -m nominal.cli config profile add default -t <1:api-key> -u <2:base-url> -w <3:workspace-rid>
python -m nominal.cli config profile list
```

**Linux**

```bash
python3 -m nominal.cli config profile add default -t <1:api-key> -u <2:base-url> -w <3:workspace-rid>
python3 -m nominal.cli config profile list
```

**macOS**

```zsh
python3 -m nominal.cli config profile add default -t <1:api-key> -u <2:base-url> -w <3:workspace-rid>
python3 -m nominal.cli config profile list
```

The credential file holds your API key in plain text, so keep it out of version control and shared folders!

## Details

Create the config file by hand

Instead of using a command line tool, you can save the file yourself, with the three values from step 1:

**Windows**

Save it as `%USERPROFILE%\.config\nominal\config.yml`:

```yaml
version: 2
profiles:
  default:
    token: API_KEY
    base_url: BASE_URL
    workspace_rid: WORKSPACE_RID
```

**Linux**

Save it as `~/.config/nominal/config.yml`:

```yaml
version: 2
profiles:
  default:
    token: API_KEY
    base_url: BASE_URL
    workspace_rid: WORKSPACE_RID
```

**macOS**

Save it as `~/.config/nominal/config.yml`:

```yaml
version: 2
profiles:
  default:
    token: API_KEY
    base_url: BASE_URL
    workspace_rid: WORKSPACE_RID
```

Profiles

Each key under `profiles` (`default` in the template above) is a profile name, and you can add more profiles to connect to other workspaces or instances.

Create one profile for each workspace, each with its own name. Profiles in the same organization can usually share an API key.

## Connecting

```matlab
c = nominal.Client.fromProfile();            % the profile called "default"
c = nominal.Client.fromProfile("staging");   % any other profile
```

## With an API key in code

A key written into a script ends up in version control, so use a profile where you can.
Without a profile, pass all three values:

```matlab
c = nominal.Client.fromToken("<api-key>", BaseUrl="<base-url>", Workspace="<workspace-rid>");
```

## In CI

`connect` reads the profile when there is one, and otherwise the API key in the
`NOMINAL_TOKEN` environment variable:

```matlab
c = nominal.Client.connect();
```

`NOMINAL_TOKEN` holds only the key, so without a profile the client reaches Nominal production
with no workspace. `connect` raises a `nominal:profileFallback` warning when it falls back.

Migrating from the old config file

If this machine still has `~/.nominal.yml` with an `environments:` block, `fromProfile`
detects it and tells you to run:

```shell
nom config migrate
```

## Checking the connection

`whoAmI` makes a request to Nominal, so a bad key fails here instead of at the first real call.

```matlab
c.whoAmI()
```
