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

pigeonidp

v0.0.2

Published

P2P SAML identity provider using PeerPigeon 1.0.6 WebDHT and UnSEA

Readme

🕊️ PigeonIdP

P2P SAML Identity Provider using PeerPigeon WebDHT and UnSEA

A decentralized identity provider (IdP) solution that works in browsers using PeerPigeon's WebDHT for storage and UnSEA for cryptographic operations. Built for integration with PigeonHub and supports custom namespaces.

Built with PeerPigeon 1.0.6 - Latest stable release with improved WebRTC mesh networking and DHT performance.

Features

  • 🔐 Decentralized Authentication - No central authority required
  • 🌐 Browser-First - Works natively in modern browsers
  • 🔑 UnSEA Cryptography - Uses UnSEA for signing, encryption, and key management
  • 💾 WebDHT Storage - Distributed hash table for identity storage
  • 🏷️ Custom Namespaces - Support for namespace-specific authentication
  • 🤝 PigeonHub Integration - Designed to work with PigeonHub servers
  • 📦 NPM Module - Easy to import and use in any project
  • 🔒 Secure Key Storage - Password-encrypted key storage in IndexedDB
  • JWT-like Tokens - Generate and verify authentication tokens
  • 🏢 SAML 2.0 Support - Full SAML IdP for enterprise SSO (Salesforce, AWS, Google, etc.)
  • 🚀 Deploy to Fly.io - One-command deployment with automated CI/CD

Installation

npm install pigeonidp

Quick Start

Node.js Usage

import { PigeonIdP } from 'pigeonidp';

// Create an IdP instance with custom namespace
const idp = new PigeonIdP({
  namespace: 'my-app-namespace',
  signalingServers: ['wss://pigeonhub.fli.dev']
});

// Initialize the IdP
await idp.init();

// Create a new identity
const keys = await idp.createIdentity('alice', 'secure-password');

// Sign a message
const signature = await idp.sign('Hello World');

// Generate an authentication token
const token = await idp.generateAuthToken({
  username: 'alice',
  role: 'user'
}, 3600); // expires in 1 hour

// Verify the token
const verification = await idp.verifyAuthToken(token);
console.log('Token valid:', verification.valid);

// Disconnect when done
await idp.disconnect();

Browser Usage

<!DOCTYPE html>
<html>
<head>
  <title>PigeonIdP Demo</title>
</head>
<body>
  <script type="module">
    import { PigeonIdP } from './node_modules/pigeonidp/index.js';
    
    const idp = new PigeonIdP({
      namespace: 'my-namespace'
    });
    
    await idp.init();
    await idp.createIdentity('user1', 'password123');
    
    const token = await idp.generateAuthToken({ user: 'user1' });
    console.log('Token:', token);
  </script>
</body>
</html>

See examples/browser-example.html for a full interactive demo.

Note on Password Storage: The password parameter for createIdentity() enables encrypted key storage using IndexedDB, which is only available in browsers. In Node.js environments, omit the password parameter or keys will not be persisted. For server-side key persistence, implement your own storage solution using the exportKeys() and importKeys() methods.

SAML 2.0 Identity Provider

PigeonIdP includes full SAML 2.0 support for enterprise Single Sign-On integration.

Quick SAML Setup

import { PigeonIdP } from 'pigeonidp';
import { PigeonIdPSAML } from 'pigeonidp/saml';

const idp = new PigeonIdP({ namespace: 'my-org' });
await idp.init();
await idp.createIdentity('admin');

// Add SAML support
const saml = new PigeonIdPSAML(idp, {
  entityId: 'https://myidp.example.com',
  ssoUrl: 'https://myidp.example.com/saml/sso',
  organizationName: 'My Organization'
});

// Generate SAML assertion for user
const user = {
  id: '[email protected]',
  username: 'alice',
  attributes: {
    email: '[email protected]',
    roles: ['admin']
  }
};

const assertion = await saml.generateAssertion(
  user,
  'https://sp.example.com/acs',
  'https://sp.example.com'
);

Deploy as SAML IdP

# Deploy to Fly.io (no prompts)
npm run deploy

# Your IdP will be available at:
# https://your-app-name.fly.dev

# SAML Metadata URL:
# https://your-app-name.fly.dev/saml/metadata

Note: Replace your-app-name with your chosen app name during deployment. The default name is pigeonidp, but you should use a unique name for your deployment (e.g., mycompany-idp).

Compatible Service Providers

  • ✅ Salesforce
  • ✅ Google Workspace
  • ✅ AWS IAM
  • ✅ Azure AD
  • ✅ Okta
  • ✅ OneLogin
  • ✅ Most enterprise SaaS applications

Full SAML Documentation

See SAML.md for complete guide including:

  • SAML configuration
  • Service provider setup
  • Attribute mapping
  • Testing and troubleshooting
  • Security best practices

Deployment

Deploy PigeonIdP as a server with REST API and SAML endpoints.

Deploy to Fly.io

# One-command deployment (no prompts)
npm run deploy

# Or use the deployment script
./deploy.sh

Your server will be available at: https://your-app-name.fly.dev

Important: Before deploying, edit fly.toml and change the app name from pigeonidp to a unique name for your deployment (e.g., mycompany-idp, acme-idp). The app name must be globally unique across all Fly.io applications.

Available Endpoints

Replace your-app-name with your actual Fly.io app name:

  • GET /health - Health check
  • GET /api/info - Server information
  • GET /api/identity/:alias - Lookup identity from DHT
  • POST /api/verify - Verify a signature
  • POST /api/verify-token - Verify auth token
  • GET /saml/metadata - SAML IdP metadata
  • GET /saml/sso - SAML Single Sign-On
  • POST /saml/sso - SAML authentication

GitHub Actions CI/CD

Automatic deployment on push to main:

  1. Get Fly.io token: flyctl auth token
  2. Add to GitHub secrets as FLY_API_TOKEN
  3. Push to main branch = auto-deploy

See DEPLOYMENT.md for detailed deployment guide.

API Reference

Constructor

new PigeonIdP(options)

Options:

  • namespace (string, default: 'default') - Custom namespace for the IdP
  • signalingServers (array, default: ['wss://pigeonhub.fli.dev']) - Signaling servers for WebRTC (uses PeerPigeon 1.0.6)
  • meshOptions (object) - Additional options for PeerPigeonMesh

Methods

init()

Initialize the IdP with mesh network and WebDHT.

await idp.init();

createIdentity(alias, password)

Create a new identity with cryptographic keypair.

const keys = await idp.createIdentity('alice', 'secure-password');

Parameters:

  • alias (string) - Alias for the identity
  • password (string, optional) - Password for encrypted storage

Returns: Keypair object with pub, priv, epub, epriv

loadIdentity(alias, password)

Load an existing identity from encrypted storage.

const keys = await idp.loadIdentity('alice', 'secure-password');

sign(message)

Sign a message or authentication token.

const signature = await idp.sign('Hello World');

verify(message, signature, publicKey)

Verify a signed message.

const isValid = await idp.verify('Hello World', signature, publicKey);

encrypt(message, recipientKeys)

Encrypt a message for a recipient.

const encrypted = await idp.encrypt('Secret message', recipientKeys);

decrypt(encryptedMessage)

Decrypt a message.

const decrypted = await idp.decrypt(encrypted);

generateAuthToken(claims, expiresIn)

Generate an authentication token (JWT-like).

const token = await idp.generateAuthToken({
  username: 'alice',
  role: 'user'
}, 3600); // expires in 1 hour

Parameters:

  • claims (object) - Claims to include in the token
  • expiresIn (number, default: 3600) - Expiration time in seconds

Returns: Token object with claims and signature

verifyAuthToken(token)

Verify an authentication token.

const result = await idp.verifyAuthToken(token);
if (result.valid) {
  console.log('User:', result.claims.username);
}

Returns: Object with valid (boolean), claims (if valid), or error (if invalid)

registerIdentity(profile)

Register an identity in the DHT for discovery.

await idp.registerIdentity({
  username: 'alice',
  displayName: 'Alice Wonderland',
  email: '[email protected]'
});

lookupIdentity(publicKey)

Lookup an identity from the DHT.

const identity = await idp.lookupIdentity(publicKey);
console.log('Profile:', identity.profile);

authenticateWithHub(hubNamespace, credentials)

Authenticate with a PigeonHub namespace.

const result = await idp.authenticateWithHub('my-hub', {
  username: 'alice'
});
console.log('Auth token:', result.token);

exportKeys()

Export keys to JWK format.

const jwkKeys = await idp.exportKeys();

importKeys(jwkKeys)

Import keys from JWK format.

await idp.importKeys(jwkKeys);

clearIdentity(alias)

Clear stored identity.

await idp.clearIdentity('alice');

getPublicKeys()

Get current identity public keys.

const pubKeys = idp.getPublicKeys();
// Returns { pub, epub }

disconnect()

Disconnect from the mesh network.

await idp.disconnect();

Examples

Basic Usage

See examples/basic-usage.js for a comprehensive example covering:

  • Creating and loading identities
  • Signing and verifying messages
  • Generating and verifying tokens
  • DHT registration and lookup
  • Encryption and decryption

Run with:

node examples/basic-usage.js

PigeonHub Integration

See examples/pigeonhub-integration.js for:

  • Namespace-specific authentication
  • Cross-user discovery
  • Encrypted messaging between users
  • Multiple namespace support

Run with:

node examples/pigeonhub-integration.js

Browser Demo

See examples/browser-example.html for an interactive browser demo with UI controls.

Architecture

PigeonIdP is built on three key technologies:

  1. PeerPigeon (v1.0.4) - Provides WebRTC mesh networking and WebDHT for distributed storage
  2. UnSEA - Cryptographic toolkit for key generation, signing, encryption (using WebCrypto and noble-curves)
  3. WebDHT - Distributed hash table for storing and discovering identities

Data Flow

User Identity
    ↓
UnSEA (Key Generation)
    ↓
Local Storage (Encrypted with Password)
    ↓
WebDHT (Public Keys & Profiles)
    ↓
PeerPigeon Mesh (P2P Network)

Integration with PigeonHub

PigeonIdP is designed to integrate seamlessly with PigeonHub:

  1. Namespace Isolation - Each PigeonHub server can have its own namespace

  2. Authentication Flow:

    • User creates/loads identity in IdP
    • IdP generates authentication request
    • Request is stored in DHT under the hub's namespace
    • Hub server verifies and processes authentication
    • Token is issued for authenticated sessions
  3. Discovery - Users can discover other users in the same namespace through DHT lookups

Security Considerations

  • 🔐 Private keys are encrypted with user passwords before storage
  • 🔑 Uses P-256 ECDSA for signatures and ECDH for encryption
  • 🛡️ AES-GCM for message encryption
  • ⏰ Tokens include expiration timestamps
  • ✅ All identity data in DHT is cryptographically signed
  • 🔒 Constant-time operations for sensitive comparisons

Dependencies

  • peerpigeon (^1.0.4) - Includes:
    • UnSEA for cryptography
    • WebDHT for distributed storage
    • PigeonRTC for WebRTC support

Browser Compatibility

  • ✅ Chrome/Edge (88+)
  • ✅ Firefox (78+)
  • ✅ Safari (14+)
  • ✅ Opera (74+)

Requires WebRTC and WebCrypto API support.

Node.js Compatibility

  • Node.js 16.0.0 or higher
  • Uses native WebCrypto API (crypto.webcrypto)

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For issues and questions:

  • GitHub Issues: https://github.com/PeerPigeon/PigeonIdP/issues
  • PeerPigeon Docs: https://github.com/PeerPigeon/PeerPigeon

Related Projects

  • PeerPigeon - WebRTC mesh networking library
  • UnSEA - Cryptographic toolkit
  • PigeonHub - P2P hub server (planned integration)

Author

PigeonIdP is part of the PeerPigeon ecosystem.