# Service Tokens

Setting up service tokens for CI/CD.

Source: https://keyenv.dev/docs/web-app/service-tokens/

Service tokens provide secure access for automated systems like CI/CD pipelines.

## What Are Service Tokens?

Service tokens are API keys that:

- Authenticate without user interaction
- Have configurable scope (one or more projects, optional environment restriction)
- Support three permission levels: `read`, `write`, and `admin`
- Can optionally expire after a set number of days
- Are logged separately in the audit trail
- Track last usage time for security auditing

## Token Scopes

Every service token requires at least one scope. Scopes control what the token is allowed to do:

| Scope | Description |
|-------|-------------|
| `read` | View and pull secrets (read-only access) |
| `write` | Create, update, and delete secrets; create, rotate, and revoke tokens |
| `admin` | Full administrative access to projects and environments |

You can assign multiple scopes to a single token. For example, a CI/CD deploy token might need both `read` and `write`, while a monitoring tool only needs `read`.

## Creating a Service Token

1. Navigate to **Tokens** in the project navigation
2. Click **Create Token**
3. Enter a name (e.g., "GitHub Actions - Production")
4. Select one or more projects to grant access to
5. Optionally restrict access to a specific environment within the selected projects
6. Choose the scopes the token should have
7. Optionally set an expiration (in days)
8. Click **Create**

> **Warning**
>
> Copy the token immediately! It's only shown once.

### Multi-Project Scoping

Tokens can be scoped to **multiple projects** simultaneously, as long as all projects belong to the same team. This is useful when a single CI/CD pipeline deploys across several related projects.

### Environment Scoping

By default, a token has access to all environments within its scoped projects. You can optionally restrict a token to a **single environment** (e.g., only `production`). This is recommended for production deploy tokens that should not be able to read staging or development secrets.

### Token Expiration

By default, tokens never expire. When creating a token, you can set `expires_in_days` to have the token automatically expire after a given number of days. This is useful for:

- Temporary CI tokens for short-lived feature branches
- Contractor access that should automatically end
- Compliance requirements that mandate periodic credential rotation

For example, a token with `expires_in_days: 7` will stop working 7 days after creation.

## Token Format

Service tokens start with `env_` followed by a random string:

```
env_abc123def456...
```

## Using Service Tokens

### In CI/CD

Set the token as an environment variable:

```yaml
# GitHub Actions
env:
  KEYENV_TOKEN: ${{ secrets.KEYENV_TOKEN }}

steps:
  - run: keyenv pull -e production
```

### With the CLI

```bash
# Set the token
export KEYENV_TOKEN="env_abc123..."

# Now use CLI commands
keyenv pull
```

### Programmatic Access

```bash
# Login with token
keyenv login --token "env_abc123..."
```

## Managing Tokens

### View Tokens

The tokens list shows:
- Token name
- Projects and environments it can access
- Scopes assigned
- When it was created
- Last used date

> **Note**
>
> Tokens track `last_used_at` timestamps automatically. Use this to identify unused tokens that can be safely revoked.

### Revoke a Token

1. Find the token in the list
2. Click **Revoke**
3. Confirm revocation

Revoked tokens immediately stop working.

### Rotate a Token

Token rotation creates a new token while keeping the old one valid during a grace period. This allows zero-downtime updates across your CI/CD pipelines.

1. Find the token in the list
2. Click **Rotate**
3. Choose a grace period (default: 5 minutes, max: 60 minutes)
4. Copy the new token and update your systems
5. The old token automatically expires after the grace period

> **Note**
>
> During the grace period, both old and new tokens are valid. This prevents CI/CD job failures while you update your secrets.

**Via API:**

```bash
curl -X POST https://api.keyenv.dev/tokens/{token_id}/rotate \
  -H "Authorization: Bearer $KEYENV_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"grace_period_minutes": 10}'
```

Response:
```json
{
  "new_token": {
    "token": "env_newtoken123...",
    "id": "tok_abc123"
  },
  "old_token_expires_at": "2026-01-23T12:10:00Z"
}
```

## Security Notifications

Team admins receive email notifications when service tokens are created, rotated, or revoked. These alerts include the token name and the email of the user who performed the action, helping teams stay aware of credential changes.

## Service Token Limitations

Service tokens are designed for automated access to secrets and cannot perform all operations available to authenticated users. Specifically, service tokens **cannot**:

- Manage team members or invitations
- Access billing endpoints
- Change team-level permission defaults

These operations require a user session with the appropriate team admin role.

## Security Best Practices

1. **One token per use case** - Create separate tokens for different CI/CD workflows
2. **Limit scope** - Only grant access to needed projects and environments
3. **Use the narrowest scope** - Prefer `read` over `write` when the token only needs to pull secrets
4. **Set expiration for temporary access** - Use `expires_in_days` for short-lived tokens
5. **Rotate regularly** - Use the rotation feature for zero-downtime updates
6. **Never commit tokens** - Use your CI/CD's secret management
7. **Monitor usage** - Check `last_used_at` timestamps and audit logs for unexpected access
8. **Restrict to specific environments** - Use environment scoping to limit blast radius
