Implementation:OpenHands OpenHands ApiKeyStore
| Knowledge Sources | |
|---|---|
| Domains | Authentication, API_Security, Storage |
| Last Updated | 2026-02-11 21:00 GMT |
Overview
Concrete tool for full CRUD lifecycle management of API keys with the sk-oh- prefix, expiration handling, and organization scoping, provided by the OpenHands enterprise storage layer.
Description
The ApiKeyStore class provides a complete API key management system for the OpenHands SaaS platform. All generated keys use the API_KEY_PREFIX constant 'sk-oh-' as a recognizable prefix, making it easy to identify OpenHands API keys in logs and configuration.
The generate_api_key method produces a cryptographically random API key string with the sk-oh- prefix. The key material is generated using a secure random source and encoded for safe transport and storage.
The create_api_key method persists a new API key record in the database. It stores the key hash (never the raw key), associates it with a user and organization, sets an optional expiration timestamp, and records metadata such as a human-readable name and creation time.
The validate_api_key method authenticates an incoming API request by hashing the provided key and looking up the hash in the database. It verifies that the key exists, has not been revoked, and has not expired. If valid, it returns the associated user and organization context.
The delete_api_key method revokes an existing API key by removing its record from the database. This is an immediate, irreversible operation.
The list_api_keys method returns all API keys associated with a given user and organization, including metadata such as name, creation time, expiration, and last-used timestamp. The raw key material is never returned in list operations.
The retrieve_mcp_api_key method fetches the API key specifically designated for MCP (Model Context Protocol) server authentication, enabling programmatic access to MCP endpoints.
Usage
Use ApiKeyStore for all API key operations in the SaaS platform. It is the single source of truth for key generation, validation, and revocation. Integrate with authentication middleware to validate incoming API requests bearing sk-oh- prefixed keys.
Code Reference
Source Location
- Repository: OpenHands
- File: enterprise/storage/api_key_store.py
- Lines: 1-208
Signature
API_KEY_PREFIX: str = 'sk-oh-'
class ApiKeyStore:
def generate_api_key(self) -> str:
...
async def create_api_key(
self,
user_id: str,
org_id: str,
name: str,
expires_at: datetime | None = None,
) -> dict:
...
async def validate_api_key(
self,
api_key: str,
) -> dict | None:
...
async def delete_api_key(
self,
key_id: str,
user_id: str,
org_id: str,
) -> bool:
...
async def list_api_keys(
self,
user_id: str,
org_id: str,
) -> list[dict]:
...
async def retrieve_mcp_api_key(
self,
user_id: str,
org_id: str,
) -> dict | None:
...
Import
from enterprise.storage.api_key_store import ApiKeyStore
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| user_id | str |
Yes | The user who owns the API key |
| org_id | str |
Yes | The organization the API key is scoped to |
| name | str |
Yes | A human-readable label for the API key (for create_api_key) |
| expires_at | datetime or None |
No | Optional expiration timestamp; None means the key does not expire (for create_api_key)
|
| api_key | str |
Yes | The raw API key string to validate (for validate_api_key) |
| key_id | str |
Yes | The unique identifier of the API key to delete (for delete_api_key) |
Outputs
| Name | Type | Description |
|---|---|---|
| api_key | str |
The generated raw API key with sk-oh- prefix (from generate_api_key; only returned once at creation time)
|
| key_record | dict |
API key metadata including key_id, name, created_at, expires_at, and last_used (from create_api_key) |
| auth_context | dict or None |
User and organization context if the key is valid; None if invalid or expired (from validate_api_key)
|
| deleted | bool |
True if the key was successfully deleted (from delete_api_key)
|
| keys | list[dict] |
List of API key metadata records (from list_api_keys) |
| mcp_key | dict or None |
The MCP-designated API key record, or None if not found (from retrieve_mcp_api_key)
|
Constants
| Constant | Value | Description |
|---|---|---|
| API_KEY_PREFIX | 'sk-oh-' |
Prefix prepended to all generated API keys for identification |
Usage Examples
from enterprise.storage.api_key_store import ApiKeyStore
from datetime import datetime, timedelta
store = ApiKeyStore(db_session=session)
# Generate and create a new API key
raw_key = store.generate_api_key()
key_record = await store.create_api_key(
user_id="user-123",
org_id="org-456",
name="CI/CD Pipeline Key",
expires_at=datetime.utcnow() + timedelta(days=90),
)
# Validate an incoming API key
auth_context = await store.validate_api_key(api_key="sk-oh-abc123xyz...")
if auth_context:
print(f"Authenticated as user {auth_context['user_id']}")
# List all keys for a user
keys = await store.list_api_keys(user_id="user-123", org_id="org-456")
# Delete a key
await store.delete_api_key(
key_id=key_record["key_id"],
user_id="user-123",
org_id="org-456",
)
# Retrieve MCP-specific key
mcp_key = await store.retrieve_mcp_api_key(user_id="user-123", org_id="org-456")