npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

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.

CI License: MIT

🎯 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:

  1. Sender runs keyshare init with a secret → gets an 8-character code (e.g., AB12XY9Q)
  2. Sender shares the code via any channel
  3. Receiver runs keyshare fetch with the code → secret is written to their .env file
  4. 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 link

Usage

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.com

Output:

✓ 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-write

Output:

✓ 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 input
  • 401 - Invalid code
  • 404 - Share not found
  • 410 - Share expired or already used
  • 429 - 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:watch

Test 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 down

Production Considerations

  1. Use HTTPS: Always run behind a reverse proxy (nginx, Caddy) with TLS
  2. Secure MongoDB: Use authentication and network isolation
  3. Rotate keys: Plan for master key rotation
  4. Monitor logs: Set up log aggregation and alerting
  5. Backup database: Regular backups of MongoDB
  6. Rate limiting: Adjust based on your usage patterns
  7. 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 lint

Adding Features

  1. Server changes: Edit files in packages/server/src/
  2. CLI changes: Edit files in packages/cli/src/
  3. Add tests for new features
  4. 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

  1. Use for: Sharing API keys during onboarding, emergency access, temporary credentials
  2. Don't use for: Long-term secrets, highly sensitive data, compliance-regulated secrets
  3. 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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Write tests for new features
  4. Ensure all tests pass (npm test)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. 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