A simple, flexible API key management system with generation, validation, and rate limiting.
- Generate and manage API keys
- Validate API keys
- Rate limiting
- Customizable storage adapters (memory, Redis, database)
- Permission-based access control
- Key expiration
- Express/Connect/Hono middleware
npm install @profullstack/api-key-manager
import { createApiKeyManager } from '@profullstack/api-key-manager';
// Create an API key manager with default options (in-memory storage)
const apiKeyManager = createApiKeyManager();
// Create an API key
const apiKey = await apiKeyManager.createKey({
userId: 'user123',
name: 'Development API Key',
permissions: {
read: true,
write: true
}
});
console.log(`API Key: ${apiKey.key}`);
// Validate an API key
const keyInfo = await apiKeyManager.validateKey('api_1234567890abcdef');
if (keyInfo) {
console.log(`Valid API key for user: ${keyInfo.userId}`);
console.log(`Permissions: ${JSON.stringify(keyInfo.permissions)}`);
} else {
console.log('Invalid API key');
}
import { createApiKeyManager, MemoryAdapter } from '@profullstack/api-key-manager';
// With default options (in-memory storage)
const apiKeyManager = createApiKeyManager();
// With custom options
const customApiKeyManager = createApiKeyManager({
adapter: new MemoryAdapter(), // Or use a custom adapter
prefix: 'myapp_', // Custom API key prefix
keyLength: 24, // Custom key length in bytes
rateLimit: {
windowMs: 60 * 1000, // 1 minute
maxRequests: 100 // 100 requests per minute
}
});
const apiKey = await apiKeyManager.createKey({
userId: 'user123', // Required
name: 'Development API Key', // Required
permissions: { // Optional
read: true,
write: true,
admin: false
},
expiresAt: '2025-12-31T23:59:59Z', // Optional
metadata: { // Optional
environment: 'development',
createdBy: 'admin'
}
});
const keys = await apiKeyManager.getKeys('user123');
keys.forEach(key => {
console.log(`${key.name} (${key.id})`);
console.log(`Active: ${key.isActive}`);
console.log(`Created: ${key.createdAt}`);
console.log(`Permissions: ${JSON.stringify(key.permissions)}`);
});
const key = await apiKeyManager.getKeyById('key123', 'user123');
if (key) {
console.log(`Found key: ${key.name}`);
} else {
console.log('Key not found or does not belong to user');
}
const updatedKey = await apiKeyManager.updateKey('key123', 'user123', {
name: 'Updated API Key',
isActive: true,
permissions: {
read: true,
write: false
},
expiresAt: new Date('2026-01-01'),
metadata: {
environment: 'production'
}
});
const deleted = await apiKeyManager.deleteKey('key123', 'user123');
if (deleted) {
console.log('API key deleted successfully');
} else {
console.log('API key not found or does not belong to user');
}
const keyInfo = await apiKeyManager.validateKey('api_1234567890abcdef');
if (keyInfo) {
// API key is valid
console.log(`User ID: ${keyInfo.userId}`);
console.log(`Permissions: ${JSON.stringify(keyInfo.permissions)}`);
// Check specific permissions
if (keyInfo.permissions.admin) {
// Allow admin actions
}
} else {
// API key is invalid, expired, or inactive
}
// Check if a request is within rate limits
const allowed = await apiKeyManager.checkRateLimit('key123');
if (allowed) {
// Process the request
} else {
// Return rate limit exceeded error
}
import express from 'express';
import { createApiKeyManager } from '@profullstack/api-key-manager';
const app = express();
const apiKeyManager = createApiKeyManager();
// Add API key middleware to routes that require authentication
app.use('/api', apiKeyManager.middleware());
app.get('/api/data', (req, res) => {
// The API key info is available in req.apiKey
const userId = req.apiKey.userId;
const permissions = req.apiKey.permissions;
// Check permissions
if (!permissions.read) {
return res.status(403).json({ error: 'Permission denied' });
}
// Process the request
res.json({ data: 'Some protected data' });
});
app.listen(3000);
Stores API keys in memory. Suitable for development or testing.
import { createApiKeyManager, MemoryAdapter } from '@profullstack/api-key-manager';
const apiKeyManager = createApiKeyManager({
adapter: new MemoryAdapter()
});
Stores API keys in Redis. Suitable for production use.
import { createApiKeyManager } from '@profullstack/api-key-manager';
import { RedisAdapter } from '@profullstack/api-key-manager/redis';
import { createClient } from 'redis';
const redisClient = createClient({
url: 'redis://localhost:6379'
});
await redisClient.connect();
const apiKeyManager = createApiKeyManager({
adapter: new RedisAdapter(redisClient)
});
Stores API keys in a database. Suitable for production use.
import { createApiKeyManager } from '@profullstack/api-key-manager';
import { DatabaseAdapter } from '@profullstack/api-key-manager/database';
import { Pool } from 'pg';
const pool = new Pool({
connectionString: 'postgresql://user:password@localhost:5432/database'
});
const apiKeyManager = createApiKeyManager({
adapter: new DatabaseAdapter(pool)
});
You can create custom adapters by implementing the adapter interface:
class CustomAdapter {
async saveKey(apiKey) { /* ... */ }
async getKeyById(keyId) { /* ... */ }
async getKeyByValue(keyValue) { /* ... */ }
async getKeysByUserId(userId) { /* ... */ }
async updateKey(keyId, updatedKey) { /* ... */ }
async deleteKey(keyId) { /* ... */ }
async checkRateLimit(keyId, rateLimit) { /* ... */ }
}
See the examples directory for complete usage examples.
MIT