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

# Creating Developer Keys

> Issue new developer keys for workspace automation.

Developer keys authenticate console actions and Starter Kit deployments that need elevated access. You can create multiple keys for different environments, applications, or team members.

(((REPLACE\_THIS\_WITH\_IMAGE: console-developer-keys-overview\.png: Cloud Admin developer keys management page showing list of keys)))

## Key Format

Developer Keys use the following format:

**Prefix:** `dk_` (Developer Key)

**Full format:** `dk_` + 32 URL-safe characters (generated using Python's `secrets.token_urlsafe(32)`)

**Example:** `dk_abc123XYZ-_789def456ghi012jkl345`

**Total length:** 35 characters (3 character prefix + 32 character key)

<Note>
  The `dk_` prefix is generated in the backend using `secrets.token_urlsafe(32)` for cryptographically strong randomness.
</Note>

## Key Properties

* **Hashing:** Keys are hashed with SHA-256 before storage for security (`hashlib.sha256`)
* **Prefix storage:** First 8 characters + "..." stored in `key_prefix` for identification (e.g., `dk_abc12...`)
* **One-time display:** The full key is shown once during generation; only the hash is persisted
* **Developer scoping:** Each key is bound to a specific developer account via `developer_id` (UUID)
* **Active status:** Keys can be revoked by setting `is_active` to false
* **Database model:** Stored in `developer_keys` table with columns: `id`, `developer_id`, `key_hash`, `key_prefix`, `name`, `is_active`, `last_used_at`, `created_at`, `updated_at`

## Managing Developer Keys

### Accessing the Developer Keys Page

Navigate to **Developer Keys** from the Cloud Admin console sidebar:

1. Log in to Cloud Admin at [devkit4ai.com/console](https://devkit4ai.com/console) or [vibecoding.ad/console](https://vibecoding.ad/console)
2. Click **Developer Keys** in the left sidebar
3. View your existing keys and their usage statistics

(((REPLACE\_THIS\_WITH\_IMAGE: console-developer-keys-list.png: Developer keys list showing name, prefix, created date, and last used columns)))

### Creating a New Developer Key

<Steps>
  <Step title="Open Generation Dialog">
    Click the **Generate Key** button in the top right corner
  </Step>

  <Step title="Enter Key Name">
    Enter an optional descriptive name (max 255 characters) like "Production API" or "Staging Environment" to help identify the key's purpose
  </Step>

  <Step title="Generate and Copy">
    Click **Generate** and immediately copy the full key. **This is your only chance to see the complete key!**
  </Step>

  <Step title="Store Securely">
    Save the key in your environment variables or secret management system
  </Step>
</Steps>

(((REPLACE\_THIS\_WITH\_IMAGE: console-generate-developer-key-dialog.png: Dialog showing name input field and generate button)))

(((REPLACE\_THIS\_WITH\_IMAGE: console-developer-key-created-success.png: Success message showing full key with copy button)))

### Backend Implementation Flow

1. Frontend calls `POST /api/v1/auth/developer-keys` with optional `name` parameter
2. Backend validates developer role via `validate_developer_role()`
3. `GenerateDeveloperKeyCommand` is sent to command bus with `developer_id`, `name`, and `max_keys=10`
4. `GenerateDeveloperKeyHandler` loads user aggregate from event store
5. `UserActions.generate_developer_key()` validates:
   * User role is DEVELOPER
   * Active key count \< 10 (raises ValueError if limit reached)
6. `DeveloperKey.generate_developer_key()` static method generates:
   * `key_suffix = secrets.token_urlsafe(32)`
   * `full_key = f"dk_{key_suffix}"`
   * `key_hash = hashlib.sha256(full_key.encode("utf-8")).hexdigest()`
   * `key_prefix = full_key[:8] + "..."`
7. `DeveloperKeyWasGenerated` event is raised with `developer_key_id`, `developer_id`, `key_hash`, `key_prefix`, `name`
8. Event is persisted to event store
9. `UserReadModel` projector handles event and creates `DeveloperKey` record in database
10. Full key is returned in `DeveloperKeyCreatedResponse` (only time it's available)
11. Key becomes valid immediately for API requests

### Viewing Key Details

Each key in the list displays:

* **Name**: Descriptive label you provided (or null)
* **Key Prefix**: First 8 characters + "..." (e.g., `dk_abc12...`) for identification
* **Created**: ISO 8601 timestamp when the key was generated
* **Last Used**: Most recent authentication timestamp (or null if "Never used")
* **Active Status**: Boolean flag (`is_active`)
* **Actions**: Revoke button

### Revoking a Developer Key

To revoke a key:

1. Locate the key in the Developer Keys list
2. Click the **Revoke** button in the Actions column
3. Confirm the revocation in the dialog
4. The key is immediately deactivated

(((REPLACE\_THIS\_WITH\_IMAGE: console-revoke-developer-key-confirm.png: Confirmation dialog for key revocation)))

<Tip>
  Before revoking a key, check the **Last Used** timestamp to ensure it's not actively in use.
</Tip>

#### Backend Revocation Flow

1. Frontend calls `DELETE /api/v1/auth/developer-keys/{key_id}` with JWT token
2. Backend validates:
   * Developer role via `validate_developer_role()`
   * Key exists and belongs to current developer via database query
   * Returns 404 if key not found or doesn't belong to developer
3. `RevokeDeveloperKeyCommand` is sent to command bus with `developer_id` and `developer_key_id`
4. `RevokeDeveloperKeyHandler` loads user aggregate from event store
5. `UserActions.revoke_developer_key()` validates:
   * Key exists in aggregate's `developer_keys` dict (raises ValueError if not found)
   * Key is not already revoked (raises ValueError if already revoked)
6. `DeveloperKeyWasRevoked` event is raised with `developer_key_id` and `developer_id`
7. Event is persisted to event store
8. `UserReadModel` projector handles event and sets `is_active=False` on `DeveloperKey` record
9. Endpoint returns 204 No Content on success
10. Future authentication attempts with revoked key fail

## Key Limits

Each developer account is limited to **10 active keys** at a time.

### Limit Enforcement

The limit is enforced in `UserActions.generate_developer_key()`:

* Counts active keys: `sum(1 for is_active in self.developer_keys.values() if is_active)`
* Raises `ValueError` with message if `active_key_count >= max_keys`
* Error message: "Maximum number of developer keys (10) reached. Please revoke an existing key before creating a new one."
* Constant defined in `app/features/auth/api/endpoints.py`: `MAX_DEVELOPER_KEYS_PER_DEVELOPER = 10`

When you reach the limit:

* The **Generate Key** button displays "Limit Reached (10/10)"
* Backend returns 400 Bad Request with error message
* Revoke unused keys before creating new ones
* Consider which keys are no longer needed by checking last usage dates

(((REPLACE\_THIS\_WITH\_IMAGE: console-developer-keys-limit-reached.png: Generate button disabled with limit message)))

### Managing Key Limits

Best practices for staying within limits:

1. **Regular Audits**: Review your keys monthly and revoke unused ones
2. **Descriptive Names**: Use clear names to identify key purposes
3. **Environment-Based**: Use one key per environment (dev, staging, prod)
4. **Application-Based**: Separate keys for different applications or services
5. **Team Member Keys**: Individual keys for team members who need API access

## Use Cases

### Local Development

Use a development-specific key for local testing:

```bash theme={null}
# .env.local
DEVKIT4AI_DEVELOPER_KEY=dk_dev_environment_key_here
```

### CI/CD Pipelines

Create a dedicated key for automated deployments:

```bash theme={null}
# GitHub Actions Secret
DEVKIT4AI_DEVELOPER_KEY=dk_cicd_pipeline_key_here
```

### Team Member Access

Issue individual keys for team members working with the API:

* **Frontend Developer**: Key for Starter Kit development
* **Backend Developer**: Key for API integration testing
* **DevOps Engineer**: Key for deployment automation

### Multi-Environment Setup

Separate keys for each environment:

```bash theme={null}
# Production
DEVKIT4AI_DEVELOPER_KEY=dk_production_key_here

# Staging
DEVKIT4AI_DEVELOPER_KEY=dk_staging_key_here

# Development
DEVKIT4AI_DEVELOPER_KEY=dk_development_key_here
```

## Environment Variable

In your Starter Kit or Cloud Admin deployment, set the generated key as:

```bash theme={null}
DEVKIT4AI_DEVELOPER_KEY=dk_abc123XYZ-_789def456ghi012jkl345
```

## Database Schema

Developer keys are stored in the `developer_keys` table:

```sql theme={null}
CREATE TABLE developer_keys (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    developer_id UUID NOT NULL,
    key_hash VARCHAR(255) NOT NULL UNIQUE,
    key_prefix VARCHAR(20) NOT NULL,
    name VARCHAR(255),
    is_active BOOLEAN NOT NULL DEFAULT TRUE,
    last_used_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE
);

CREATE INDEX ix_developer_keys_developer_id ON developer_keys(developer_id);
```

**Relationships:**

* No foreign key constraints (event-sourced architecture pattern)
* Relationship defined in SQLAlchemy: `developer = relationship("User", primaryjoin="foreign(DeveloperKey.developer_id)==User.id")`

## Security

<Warning>
  * Store the full key securely - it cannot be retrieved again
  * Never commit keys to version control
  * Rotate keys regularly (every 90 days recommended)
  * Revoke compromised keys immediately
  * Full key only returned in `DeveloperKeyCreatedResponse` during creation
  * Subsequent API calls return `DeveloperKeyResponse` without full key
</Warning>

### Security Implementation

* **Hashing algorithm**: SHA-256 (`hashlib.sha256`)
* **Random generation**: `secrets.token_urlsafe(32)` (cryptographically strong)
* **Storage**: Only hash and prefix stored in database, never plain text
* **Validation**: Via `app/system/auth/rbac.py::validate_developer_key()`
* **Request state**: Validated key attaches `developer_id` and `developer_key_id` to `request.state`

## API Reference

See the [Developer Keys API endpoint](/cloud-api/auth/developer-keys) for complete request/response details.

## Related Pages

<CardGroup cols={2}>
  <Card title="Developer Keys API" icon="code" href="/cloud-api/auth/developer-keys">
    API documentation for key management
  </Card>

  <Card title="Project API Keys" icon="folder-key" href="/cloud-admin/api-keys/creating-project-keys">
    Managing project-scoped keys
  </Card>

  <Card title="Security Practices" icon="shield" href="/cloud-admin/api-keys/security-practices">
    Best practices for key security
  </Card>

  <Card title="Rotating Keys" icon="arrows-rotate" href="/cloud-admin/api-keys/revoking-rotating">
    Key rotation strategies
  </Card>
</CardGroup>
