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

# Service Accounts

> Setting up automated system access with API keys

# Service Accounts

Service accounts enable automated systems (robots, scripts, integrations) to authenticate with Switchyard using API keys.

## Overview

Service accounts provide:

* **API Key Authentication**: No user interaction required
* **Role-based Permissions**: Inherit permissions from assigned role
* **Audit Trail**: Track last usage timestamp
* **Secure Storage**: API keys are hashed before storage

## Creating a Service Account

Use the CLI tool:

```bash theme={null}
npx ts-node scripts/create-service-account.ts create \
  --name "Inventory Scanner Bot" \
  --role robot
```

Output:

```
=== Service Account Created ===
ID: 123e4567-e89b-12d3-a456-426614174000
Name: Inventory Scanner Bot
Role: robot

API Key (save this - it will not be shown again):

  sk_robot_a1b2c3d4e5f6...

================================
```

<Warning>
  The API key is only shown once at creation. Store it securely - it cannot be retrieved later.
</Warning>

## Managing Service Accounts

```bash theme={null}
# List all service accounts
npx ts-node scripts/create-service-account.ts list

# Revoke a service account (deactivate)
npx ts-node scripts/create-service-account.ts revoke <id>

# Delete a service account
npx ts-node scripts/create-service-account.ts delete <id>
```

## Using a Service Account

### Authentication

```bash theme={null}
# Authenticate with the API key
curl -X POST 'https://api.switchyard.run/auth/user/supabase' \
  -H "Content-Type: application/json" \
  -d '{"api_key": "sk_robot_a1b2c3d4e5f6..."}'
```

### Making API Calls

```bash theme={null}
# Use the returned token for subsequent requests
curl 'https://api.switchyard.run/scanner/inventory/scan' \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"barcode": "012345678901"}'
```

## Database Schema

```sql theme={null}
CREATE TABLE public.service_accounts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name VARCHAR(100) NOT NULL,
  api_key_hash VARCHAR(255) NOT NULL,
  role_id UUID REFERENCES public.roles(id),
  is_active BOOLEAN DEFAULT TRUE,
  last_used_at TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT NOW()
);
```

| Column         | Description                     |
| -------------- | ------------------------------- |
| `id`           | Unique identifier               |
| `name`         | Human-readable name             |
| `api_key_hash` | SHA-256 hash of the API key     |
| `role_id`      | Associated role for permissions |
| `is_active`    | Set to false to revoke access   |
| `last_used_at` | Tracks last authentication      |

## Security Best Practices

<AccordionGroup>
  <Accordion title="Rotate Keys Regularly">
    Create new service accounts periodically and revoke old ones to minimize exposure from compromised keys.
  </Accordion>

  <Accordion title="Use Least Privilege">
    Assign the minimum role required. Use `robot` role for automated systems instead of `superadmin`.
  </Accordion>

  <Accordion title="Monitor Usage">
    Regularly check `last_used_at` to identify unused accounts that should be revoked.
  </Accordion>

  <Accordion title="Secure Storage">
    Store API keys in environment variables or secrets managers, never in code.
  </Accordion>
</AccordionGroup>

## Troubleshooting

### API Key Not Working

**Possible causes:**

* Typo in API key
* Service account is inactive (`is_active = false`)
* Role not assigned

**Solutions:**

1. Verify the key is correct (only shown once at creation)
2. Check `is_active` in the database
3. Verify `role_id` is set
