api-token-manager
v1.1.0
Published
Comprehensive API Token Manager with server, SDK, and dashboard
Readme
🔐 Keyshare
A secure, developer-friendly CLI tool and backend service for sharing secrets with colleagues using short-lived, one-time codes.
🎯 What is Keyshare?
Keyshare lets you securely share API keys, tokens, and other secrets with teammates without using insecure channels like Slack or email.
How it works:
- Sender runs
keyshare initwith a secret → gets an 8-character code (e.g.,AB12XY9Q) - Sender shares the code via any channel
- Receiver runs
keyshare fetchwith the code → secret is written to their.envfile - Code expires after 10 minutes (configurable) and can only be used once
✨ Features
- 🔒 Secure by default: AES-256-GCM encryption, HMAC-SHA256 code hashing
- ⏱️ Short-lived: Configurable TTL (default 10 minutes)
- 🎫 One-time use: Shares are deleted after retrieval
- 🛡️ Rate limited: Protection against brute-force attacks
- 📝 Audit logs: Track all share creation, retrieval, and revocation
- 🚀 Easy to use: Simple CLI with beautiful output
- 📋 Clipboard support: Auto-copy share codes
- 🔍 QR codes: Optional QR code display for mobile sharing
- 🐳 Docker ready: Full Docker Compose setup included
🚀 Quick Start
Prerequisites
- Node.js 18.x or higher
- MongoDB 6.x (or use Docker Compose)
- npm or yarn
Installation
Option 1: Using Docker Compose (Recommended)
# Clone the repository
git clone https://github.com/yourusername/keyshare.git
cd keyshare
# Generate a master key
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Create .env file for docker-compose
echo "KEYSHARE_MASTER_KEY=<your-generated-key>" > .env
# Start the services
docker compose up -d
# Install CLI globally
cd packages/cli
npm install -g .Option 2: Manual Installation
# Install dependencies
npm run bootstrap
# Start MongoDB (if not using Docker)
mongod --dbpath /path/to/data
# Configure server
cd packages/server
cp .env.example .env
# Edit .env and set KEYSHARE_MASTER_KEY
# Start server
npm start
# Install CLI (in another terminal)
cd packages/cli
npm linkUsage
Create a share
# Interactive mode
keyshare init
# From file
keyshare init --from-file ./secret.txt
# Custom TTL (5 minutes)
keyshare init --ttl 5
# With QR code
keyshare init --qr
# Custom API URL
keyshare init --api-url https://keyshare.yourcompany.comOutput:
✓ Share created successfully!
Share code (give this to your colleague):
AB12XY9Q
Expires: 10/4/2025, 9:23:32 AM
TTL: 10 minutes
✓ Code copied to clipboard
⚠ Warning: Share this code securely (encrypted chat, password manager, etc.)
The code can only be used once and will expire automatically.Retrieve a share
# Interactive mode
keyshare fetch
# With code
keyshare fetch --code AB12XY9Q
# Custom env file
keyshare fetch --env-file .env.local
# Custom variable name
keyshare fetch --var-name DATABASE_URL
# Just display (don't write to file)
keyshare fetch --no-writeOutput:
✓ Share retrieved successfully!
✓ Secret written to /path/to/project/.env
Variable: API_KEY
Backup created
Permissions: 600 (owner read/write only)
⚠ Remember to add .env to your .gitignore file!Revoke a share
keyshare revoke --code AB12XY9Q🏗️ Architecture
Monorepo Structure
keyshare/
├── packages/
│ ├── server/ # Express API + MongoDB
│ │ ├── src/
│ │ │ ├── controllers/
│ │ │ ├── models/
│ │ │ ├── routes/
│ │ │ ├── services/
│ │ │ └── middlewares/
│ │ └── test/
│ └── cli/ # Commander-based CLI
│ ├── src/
│ └── test/
├── docker-compose.yml
└── .github/workflows/Security Model
Encryption at Rest
- Secrets are encrypted using AES-256-GCM before storage
- Encryption key derived from
KEYSHARE_MASTER_KEY(32 bytes) - Each secret has unique IV and authentication tag
- Server never stores plaintext secrets
Share Code Protection
- 8-character codes provide ~47 bits of entropy (62^8 combinations)
- Codes are hashed using HMAC-SHA256 before storage
- Database compromise doesn't reveal valid codes
- Timing-safe comparison prevents timing attacks
Mitigations
- Short TTL: Default 10 minutes (configurable)
- One-time use: Shares deleted after retrieval
- Rate limiting: Max 5 attempts per IP per minute
- Attempt tracking: Shares locked after 5 failed attempts
- Audit logging: All actions logged with IP and timestamp
Transport Security
- Use HTTPS/TLS in production (documented in deployment guide)
- Server supports helmet.js security headers
- CORS configured for trusted origins
API Endpoints
POST /api/shares
Create a new share.
Request:
{
"secret": "my-api-key-12345",
"ttlMinutes": 10,
"meta": {
"project": "my-app"
}
}Response:
{
"shareCode": "AB12XY9Q",
"expiresAt": "2025-10-04T09:33:32.000Z",
"ttlMinutes": 10
}POST /api/shares/retrieve
Retrieve a share by code.
Request:
{
"shareCode": "AB12XY9Q"
}Response:
{
"secret": "my-api-key-12345",
"meta": {
"project": "my-app"
}
}Error Responses:
400- Invalid input401- Invalid code404- Share not found410- Share expired or already used429- Too many attempts / rate limited
POST /api/shares/revoke
Revoke a share before it's used.
Request:
{
"shareCode": "AB12XY9Q"
}Response:
{
"message": "Share revoked successfully",
"shareCode": "AB12XY9Q"
}🧪 Testing
# Run all tests
npm test
# Run server tests only
npm run test:server
# Run CLI tests only
npm run test:cli
# Watch mode
cd packages/server && npm run test:watchTest Coverage
- Server: Controllers, models, crypto service, rate limiting
- CLI: Env writer, file permissions, backup creation
- Integration: End-to-end share creation and retrieval
🚢 Deployment
Environment Variables
Server (packages/server/.env)
| Variable | Description | Required | Default |
|----------|-------------|----------|---------|
| MONGO_URI | MongoDB connection string | Yes | mongodb://127.0.0.1:27017/keyshare |
| KEYSHARE_MASTER_KEY | 32-byte encryption key (64 hex chars) | Yes | - |
| KEYSHARE_PORT | Server port | No | 4000 |
| KEYSHARE_TTL_MINUTES | Default share TTL | No | 10 |
| KEYSHARE_RATE_LIMIT_WINDOW_MS | Rate limit window | No | 60000 |
| KEYSHARE_RATE_LIMIT_MAX | Max requests per window | No | 5 |
| NODE_ENV | Environment | No | development |
CLI (.env or environment)
| Variable | Description | Default |
|----------|-------------|---------|
| KEYSHARE_API_URL | API server URL | http://localhost:4000 |
Generate Master Key
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"⚠️ Important:
- Store the master key securely (use a secrets manager in production)
- Never commit the master key to version control
- Rotating the key will invalidate all existing shares
Docker Deployment
# Build and run with Docker Compose
docker compose up -d
# View logs
docker compose logs -f server
# Stop services
docker compose downProduction Considerations
- Use HTTPS: Always run behind a reverse proxy (nginx, Caddy) with TLS
- Secure MongoDB: Use authentication and network isolation
- Rotate keys: Plan for master key rotation
- Monitor logs: Set up log aggregation and alerting
- Backup database: Regular backups of MongoDB
- Rate limiting: Adjust based on your usage patterns
- Firewall: Restrict API access to trusted networks if possible
📚 Development
Project Setup
# Install dependencies
npm run bootstrap
# Start server in dev mode
npm run dev:server
# Run linting
npm run lintAdding Features
- Server changes: Edit files in
packages/server/src/ - CLI changes: Edit files in
packages/cli/src/ - Add tests for new features
- Update documentation
Publishing CLI to npm
cd packages/cli
# Update version
npm version patch # or minor, major
# Publish
npm publish
# Users can then install with:
npm install -g keyshare-cli🔒 Security Considerations
What Keyshare IS
- ✅ A convenient way to share secrets with teammates
- ✅ Secure for short-term, one-time secret sharing
- ✅ Better than Slack, email, or unencrypted channels
- ✅ Suitable for API keys, tokens, passwords
What Keyshare IS NOT
- ❌ A replacement for enterprise secret managers (Vault, AWS Secrets Manager)
- ❌ Suitable for long-term secret storage
- ❌ A password manager
- ❌ Cryptographically strong for high-security environments (8-char codes)
Threat Model
Protected against:
- Database compromise (secrets encrypted, codes hashed)
- Network eavesdropping (use HTTPS in production)
- Brute force attacks (rate limiting, TTL, one-time use)
- Timing attacks (constant-time comparison)
Not protected against:
- Compromised master key
- Malicious server operator
- Man-in-the-middle (without HTTPS)
- Social engineering
Recommendations
- Use for: Sharing API keys during onboarding, emergency access, temporary credentials
- Don't use for: Long-term secrets, highly sensitive data, compliance-regulated secrets
- Best practices:
- Share codes through encrypted channels when possible
- Use shortest TTL practical for your use case
- Revoke shares if recipient doesn't need them anymore
- Monitor audit logs for suspicious activity
- Use strong master keys (generated with crypto.randomBytes)
🤝 Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for new features
- Ensure all tests pass (
npm test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- Built with Node.js, Express, MongoDB, and Commander
- Inspired by the need for secure, simple secret sharing
- Thanks to all contributors and users
📞 Support
Made with ❤️ for developers who care about security
