API Key Overview
API keys provide secure, token-based authentication for programmatic access to OWASP Nest data. Key characteristics:- Each user can have up to 3 active API keys
- Keys are generated with 32 bytes of cryptographic randomness
- Keys are stored as SHA-256 hashes for security
- Keys have configurable expiration dates
- Keys can be revoked at any time
backend/apps/api/models/api_key.py:12-14
Creating API Keys
API keys must be created through the GraphQL API using an authenticated session.GraphQL Mutation
backend/apps/api/internal/mutations/api_key.py:44-78
Validation Rules
API key creation enforces the following rules: Name validation:- Name is required and cannot be empty
- Maximum length: 100 characters
- Returns
INVALID_NAMEerror if validation fails
- Expiration date must be in the future
- Returns
INVALID_DATEerror if date is in the past
- Maximum 3 active (non-revoked, non-expired) keys per user
- Returns
LIMIT_REACHEDerror if limit exceeded
backend/apps/api/internal/mutations/api_key.py:46-69, backend/apps/api/models/api_key.py:14
Using API Keys
API keys authenticate requests by including them in the request headers.- REST API
- GraphQL API
Include the API key in the With filters and pagination:Example response:
X-API-Key header:backend/apps/api/rest/auth/api_key.py:14
Authentication Flow
When a request includes an API key, the following authentication process occurs:- Header extraction: API key is extracted from the
X-API-Keyheader - Key hashing: Raw key is hashed using SHA-256
- Database lookup: Hash is used to find the corresponding API key record
- Validation: Key is checked for:
- Existence in database
- Not revoked (
is_revoked = false) - Not expired (
expires_at > now())
- Last used update: On successful authentication,
last_used_atis updated - Request proceeds: User context is attached to the request
backend/apps/api/models/api_key.py:77-88, backend/apps/api/rest/auth/api_key.py:16-35
Authentication Errors
Missing or Invalid API Key
If the API key is missing or invalid, you’ll receive a401 Unauthorized response:
- No
X-API-Keyheader provided - Invalid or non-existent key
- Key has been revoked
- Key has expired
backend/apps/api/rest/auth/api_key.py:27-35
Rate Limit Exceeded
When you exceed the rate limit (10 requests/second), you’ll receive a429 Too Many Requests response.
Source: backend/apps/api/rest/v0/__init__.py:46
Managing API Keys
Listing Your API Keys
Query your active API keys using GraphQL:Only non-revoked, non-expired keys are returned by the
apiKeys query and counted in activeApiKeyCount.backend/apps/api/internal/queries/api_key.py:14-30, backend/apps/api/internal/nodes/api_key.py:9-21
Revoking API Keys
Revoke an API key using its UUID:backend/apps/api/internal/mutations/api_key.py:91-110
Security Best Practices
Key Storage
- Never commit API keys to source control
- Store keys in environment variables or secret management systems
- Use different keys for different environments (development, staging, production)
Key Rotation
- Set reasonable expiration dates (e.g., 6-12 months)
- Rotate keys before they expire
- Revoke old keys after rotating
- Monitor
last_used_atto identify unused keys
Key Limits
The 3-key limit encourages:
- Production key - For production integrations
- Staging key - For testing environments
- Development key - For local development
backend/apps/api/models/api_key.py:13
Monitoring
Track API key usage through thelast_used_at field:
Implementation Details
Key Generation
API keys are generated using Python’ssecrets module for cryptographic security:
backend/apps/api/models/api_key.py:96-98
Key Hashing
Raw keys are hashed using SHA-256 before storage:backend/apps/api/models/api_key.py:91-93
Only the hash is stored in the database. Raw keys are never persisted, making stolen database dumps useless without the original keys.
Key Validation
API keys are validated on each request:backend/apps/api/models/api_key.py:48-55
Troubleshooting
Key Creation Fails
Error:LIMIT_REACHED
- Cause: You already have 3 active API keys
- Solution: Revoke unused keys before creating new ones
INVALID_DATE
- Cause: Expiration date is in the past
- Solution: Use a future date for
expiresAt
INVALID_NAME
- Cause: Name is empty or exceeds 100 characters
- Solution: Provide a valid name (1-100 characters)
Authentication Fails
Error:401 Unauthorized
- Cause: Missing, invalid, revoked, or expired key
- Solutions:
- Verify the
X-API-Keyheader is included - Check the key hasn’t been revoked
- Verify the key hasn’t expired
- Ensure the full raw key is used (not truncated)
- Verify the
Rate Limit Issues
Error:429 Too Many Requests
- Cause: Exceeded 10 requests per second
- Solutions:
- Implement request throttling in your client
- Use exponential backoff for retries
- Cache responses when possible
- Consider batching requests using GraphQL
Next Steps
API Overview
Learn about REST and GraphQL APIs
REST Endpoints
Explore available REST endpoints
GraphQL Schema
Browse GraphQL queries and mutations
Rate Limits
Understand rate limiting policies