# First user and admin

> Sign up the first user of a self-hosted Nodaro and promote an admin on the Business edition with one SQL statement, with or without a Supabase dashboard.

Source: https://nodaro.ai/docs/self-hosting/first-admin

The **first user** of a self-hosted Nodaro signs up in the app like everyone else, and becomes the install's operator. On the Community Edition that is all: there is no admin role in the product. On the Business edition, you then promote an account to **admin** with one SQL statement, because no admin exists yet to do it in the app.

## Create the first account

Open `/setup` and follow step 1, **Create your server login**. This account belongs to your server only. It is not a Nodaro Cloud account: that one comes in step 2, and only if you connect to Nodaro Cloud.

The sign-in service creates the user, and Nodaro creates the user's profile automatically. On the bundled compose stack, no confirmation email is sent, so the account works at once.

## Roles

A profile has one of three roles. The roles matter on the Business edition, which has the admin panel.

| Role | What it adds |
| --- | --- |
| `user` | The default. Uses the editor. |
| `admin` | Opens the admin panel and manages the install's provider keys. |
| `super_admin` | Also changes the roles of other users in the admin panel. |

On the Community Edition, every user is unrestricted, and any signed-in user can manage the provider keys.

## Promote an account

### Open a SQL session

On a **managed Supabase project**, open the Supabase dashboard and choose **SQL editor**.

On the **bundled stack**, which has no dashboard, open `psql` in the database container:

```bash
docker compose -f docker-compose.community.yml exec db sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" psql -U supabase_admin -d postgres'
```

### Find the user's ID

In the Supabase dashboard, the ID is under **Authentication › Users**. In `psql`, list the users:

```sql
SELECT id, email FROM auth.users;
```

### Set the role

```sql
UPDATE profiles
SET role = 'admin'
 WHERE id = '<user_uuid>';
```

Use `'super_admin'` instead of `'admin'` for the account that should manage other users' roles.

### Wait, or restart

The change applies within 5 minutes, because Nodaro caches each user's admin status for that long. To apply it at once, restart the app:

```bash
docker compose -f docker-compose.community.yml restart nodaro
```

## Protect the owner account

On a Business install, set `PLATFORM_OWNER_EMAIL` to the email address of the owner's account. No other admin can then change that account's role. When it is empty, the default, no account is protected.

The compose file does not pass `PLATFORM_OWNER_EMAIL` from `.env`. Add it under `environment:` of the `nodaro` service:

```yaml
nodaro:
environment:
# ...the variables already listed...
PLATFORM_OWNER_EMAIL: owner@example.com
```

## The admin panel needs the Business edition

The published image and the compose file run the Community Edition, which has no admin panel. To get one, switch the install to the Business edition first: see [Editions and surface profiles](https://nodaro.ai/docs/self-hosting/editions-and-profiles#switch-a-self-hosted-install-to-business). The Business edition's admin features are Enterprise features: read [License](https://nodaro.ai/docs/self-hosting/license) before you use them in production.

## Frequently asked questions

### How do I make a user an admin on self-hosted Nodaro?

After the user signs up, set the role column of their profile to admin with one SQL statement, in the Supabase SQL editor or with psql in the database container. The admin panel exists only on the Business edition.

### Does the Community Edition have admins?

No. The Community Edition has no admin panel and no admin role in the product. Every user is unrestricted, and any signed-in user can manage the provider keys.

### How long does an admin promotion take to apply?

Up to 5 minutes, because Nodaro caches each user's admin status for 5 minutes. Restart the app container to apply it at once.

### What is PLATFORM_OWNER_EMAIL for?

It names the owner account on a Business install. No other admin can change the role of that account. Leave it empty and no account is protected.
