Skip to content

bahbah94/p2p-secrets

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

P2P Secrets CLI

A decentralized peer-to-peer secret sharing system with granular access control, built on libp2p and RocksDB. Share secrets securely across a distributed network without any central authority.

Table of Contents

Features

  • Fully Decentralized: No central server or authority - peers communicate directly
  • Access Control: Owner-based permissions with explicit grant/revoke capabilities
  • Encrypted Transport: All network traffic secured via libp2p Noise protocol
  • Persistent Storage: Local RocksDB database per peer with metadata tracking
  • Peer Discovery: Automatic peer finding via Kademlia DHT
  • IPC Communication: CLI communicates with daemon via Unix sockets
  • Cross-Platform: Supports Linux and macOS (Intel & Apple Silicon)

Architecture

System Overview

┌─────────────────────────────────────────────────────────────────┐
│                     P2P Secrets System                           │
│                                                                   │
│  ┌──────────┐                                                    │
│  │   CLI    │  User commands (store, get, share, request, etc.) │
│  └────┬─────┘                                                    │
│       │ IPC (Unix Socket)                                        │
│       ▼                                                           │
│  ┌─────────────────────────────────────────────┐                │
│  │              DAEMON PROCESS                  │                │
│  │                                               │                │
│  │  ┌─────────────┐       ┌──────────────┐    │                │
│  │  │ IPC Server  │◄─────►│  P2P Swarm   │    │                │
│  │  │             │ mpsc  │              │    │                │
│  │  │  - Handle   │channel│ - Network    │◄───┼──► Peer A     │
│  │  │    CLI reqs │       │   events     │    │                │
│  │  │  - Manage   │       │ - Request/   │◄───┼──► Peer B     │
│  │  │    requests │       │   Response   │    │                │
│  │  └──────┬──────┘       └──────┬───────┘    │                │
│  │         │                     │             │                │
│  │         └──────────┬──────────┘             │                │
│  │                    ▼                         │                │
│  │         ┌──────────────────────┐            │                │
│  │         │   Protocol Layer     │            │                │
│  │         │  - Access Control    │            │                │
│  │         │  - Secret Management │            │                │
│  │         │  - Request Handler   │            │                │
│  │         └──────────┬───────────┘            │                │
│  │                    ▼                         │                │
│  │         ┌──────────────────────┐            │                │
│  │         │   Storage Layer      │            │                │
│  │         │   (RocksDB)          │            │                │
│  │         │  - Secrets           │            │                │
│  │         │  - ACLs              │            │                │
│  │         │  - Metadata          │            │                │
│  │         └──────────────────────┘            │                │
│  └───────────────────────────────────────────┘                │
└─────────────────────────────────────────────────────────────────┘

Component Details

1. CLI Layer

The command-line interface is a thin client that:

  • Parses user commands
  • Connects to the daemon via Unix socket (.sock file in db directory)
  • Sends IpcRequest messages and receives IpcResponse messages
  • Formats and displays results to the user

2. Daemon Process

The daemon is a long-running background process that manages two concurrent async tasks:

IPC Server:

  • Listens on Unix socket for CLI connections
  • Deserializes incoming requests
  • For local operations (store, get, list, delete): directly calls protocol layer
  • For network operations (request): sends commands to P2P swarm via mpsc channel
  • Serializes and returns responses to CLI

P2P Swarm:

  • Manages libp2p network stack with these behaviors:
    • Ping: Keep-alive and connectivity testing
    • Identify: Peer discovery and address exchange
    • Kademlia DHT: Distributed peer routing and discovery
    • Request-Response: Custom protocol for secret exchange
  • Listens for incoming network requests from remote peers
  • Processes outgoing requests triggered by CLI request command
  • Handles peer connections and disconnections

Communication Flow:

CLI → Unix Socket → IPC Server → mpsc channel → P2P Swarm → Network
                        ↓                            ↓
                   Protocol Layer              Protocol Layer
                        ↓                            ↓
                   Local Storage              Remote Peer Check

3. Protocol Layer

Implements the core business logic:

Access Control:

  • Owner-based permission model
  • Each secret has one owner (the creator)
  • Owner can grant access to specific peers via their PeerID
  • Owner can revoke access at any time
  • Permissions persist in RocksDB alongside secrets

Secret Management:

  • Store secrets with automatic ownership assignment
  • Retrieve secrets with permission validation
  • Delete secrets (owner-only operation)
  • Handle network requests with ACL enforcement

Request Handler: When a peer requests a secret, the handler:

  1. Receives SecretRequest::Get { key, requester }
  2. Checks if requester has permission via ACL
  3. Returns SecretResponse::GetResponse with data or access denied error

4. Storage Layer (RocksDB)

Key-value pairs stored per peer:

secret:{key}      → Vec<u8>      (encrypted secret data)
owner:{key}       → PeerId        (owner's peer ID)
acl:{key}         → Vec<PeerId>   (list of authorized peers)
metadata:{key}    → Metadata      (creation time, etc.)
peer_id           → String        (this peer's ID)

Each peer has its own isolated database directory, ensuring complete data separation.

5. Network Layer (libp2p)

Transport Stack:

Application (Secret Protocol)
         ↓
Request-Response Protocol
         ↓
Multiplexing (Yamux)
         ↓
Encryption (Noise)
         ↓
TCP Transport

Protocols Used:

  • Noise Protocol: Provides transport encryption and peer authentication
  • Yamux: Multiplexes multiple streams over a single connection
  • Kademlia DHT: Enables peer discovery without central registry
  • Custom /secrets/1.0.0: Request-response protocol for secret exchange

Peer Discovery:

  1. Bootstrap peer provided on startup
  2. Identify protocol exchanges peer addresses
  3. Kademlia DHT builds routing table
  4. Periodic bootstrap maintains network connectivity

Data Flow Examples

Example 1: Storing a Secret Locally

User: p2p-secrets store "api_key" "sk-12345" --db-path "./peer_a_db"
                    ↓
CLI creates IpcRequest::Store { key: "api_key", value: "sk-12345" }
                    ↓
Sends to daemon via Unix socket
                    ↓
IPC Server receives and calls protocol.store_secret()
                    ↓
Protocol Layer:
  - storage.store_secret("api_key", "sk-12345")
  - access_control.set_owner("api_key", peer_a_id)
  - Persist ACL to RocksDB
                    ↓
Returns IpcResponse::Success
                    ↓
CLI displays: ✅ Secret 'api_key' stored successfully

Example 2: Requesting Secret from Remote Peer

User: p2p-secrets request "api_key" "12D3Koo...PeerA" --db-path "./peer_b_db"
                    ↓
CLI: IpcRequest::Request { key: "api_key", peer_id: "12D3Koo...PeerA" }
                    ↓
IPC Server (Peer B):
  - Creates oneshot channel for response
  - Sends SwarmCommand::SendRequest via mpsc to P2P Swarm
  - Waits on oneshot receiver
                    ↓
P2P Swarm (Peer B):
  - Receives SwarmCommand from channel
  - Creates SecretRequest::Get { key: "api_key", requester: peer_b_id }
  - Sends network request to Peer A via libp2p
  - Stores oneshot sender in pending_requests HashMap
                    ↓
               [Network Transit]
                    ↓
P2P Swarm (Peer A):
  - Receives network request
  - Calls protocol.handle_request(request, peer_b_id)
                    ↓
Protocol Layer (Peer A):
  - Checks access_control.can_access("api_key", peer_b_id)
  - If authorized: storage.get_secret("api_key")
  - Returns SecretResponse::GetResponse { data: Some("sk-12345") }
                    ↓
P2P Swarm (Peer A):
  - Sends response back over network to Peer B
                    ↓
               [Network Transit]
                    ↓
P2P Swarm (Peer B):
  - Receives network response
  - Looks up oneshot sender by request_id
  - Sends response through oneshot channel
                    ↓
IPC Server (Peer B):
  - Receives response from oneshot channel
  - Returns IpcResponse::Success { data: "sk-12345" }
                    ↓
CLI displays: ✅ Secret 'api_key': sk-12345

Installation

Download Pre-built Binaries

Linux (x86_64):

# Download binary
curl -L https://github.com/bahbah94/p2p-secrets/releases/latest/download/p2p-secrets-linux-x64 -o p2p-secrets

# Make executable
chmod +x p2p-secrets

# Move to PATH
sudo mv p2p-secrets /usr/local/bin/

macOS (Intel):

curl -L https://github.com/bahbah94/p2p-secrets/releases/latest/download/p2p-secrets-macos-x64 -o p2p-secrets
chmod +x p2p-secrets
sudo mv p2p-secrets /usr/local/bin/

macOS (Apple Silicon):

curl -L https://github.com/bahbah94/p2p-secrets/releases/latest/download/p2p-secrets-macos-arm64 -o p2p-secrets
chmod +x p2p-secrets
sudo mv p2p-secrets /usr/local/bin/

Verify Installation:

p2p-secrets --help

Build from Source

Prerequisites:

  • Rust 1.70 or later
  • Cargo
# Clone repository
git clone https://github.com/bahbah94/p2p-secrets.git
cd p2p-secrets

# Build release binary
cargo build --release

# Binary location
./target/release/p2p-secrets

# Optionally install
cargo install --path .

Quick Start

Step 1: Start Bootstrap Peer (Terminal 1)

p2p-secrets daemon --db-path "./peer_a_db"

Output will show:

Local Peer ID: 12D3KooWLhtLikHJ1zkunuvPkiGMPP5oBw5K9vvNWiWbGeHFUwsT
Listening on /ip4/0.0.0.0/tcp/4001
Bootstrap address: /ip4/127.0.0.1/tcp/4001/p2p/12D3KooWLhtLikHJ1zkunuvPkiGMPP5oBw5K9vvNWiWbGeHFUwsT

Copy the bootstrap address for the next step.

Step 2: Start Second Peer (Terminal 2)

p2p-secrets daemon --db-path "./peer_b_db" \
  --bootstrap "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWLhtLikHJ1zkunuvPkiGMPP5oBw5K9vvNWiWbGeHFUwsT"

You should see "Connection established with peer" messages in both terminals.

Step 3: Store and Share a Secret (Terminal 3)

# Store a secret in Peer A
p2p-secrets store "database_password" "super_secret_123" --db-path "./peer_a_db"

# Get Peer B's ID
p2p-secrets status --db-path "./peer_b_db"
# Note the Peer ID shown

# Share the secret with Peer B
p2p-secrets share "database_password" "12D3KooW...PeerBID..." --db-path "./peer_a_db"

Step 4: Request Secret from Peer A (Terminal 3)

# Peer B requests the shared secret
p2p-secrets request "database_password" "12D3KooW...PeerAID..." --db-path "./peer_b_db"

# Output: ✅ Secret 'database_password': super_secret_123

Step 5: Test Access Control

# Store a private secret (don't share)
p2p-secrets store "admin_token" "private123" --db-path "./peer_a_db"

# Try to request it from Peer B (should fail)
p2p-secrets request "admin_token" "12D3KooW...PeerAID..." --db-path "./peer_b_db"

# Output: ❌ Error: Not found or access denied

Complete Usage Guide

Running Daemons in Background

The daemon occupies a terminal. Use these methods to run in background:

Option 1: screen (Recommended)

# Start screen session
screen -S peer_a

# Run daemon
p2p-secrets daemon --db-path "./peer_a_db"

# Detach: Press Ctrl+A, then D

# List sessions
screen -ls

# Reattach
screen -r peer_a

# Stop daemon: Reattach and press Ctrl+C

Option 2: tmux

# Create session
tmux new -s peer_a

# Run daemon
p2p-secrets daemon --db-path "./peer_a_db"

# Detach: Press Ctrl+B, then D

# Reattach
tmux attach -t peer_a

# List sessions
tmux ls

Option 3: nohup

# Run in background
nohup p2p-secrets daemon --db-path "./peer_a_db" > peer_a.log 2>&1 &

# Save PID
echo $! > peer_a.pid

# View logs
tail -f peer_a.log

# Stop daemon
kill $(cat peer_a.pid)
rm peer_a.pid

Managing Multiple Peers on Same Machine

# Terminal 1: Peer A (default port 4001)
p2p-secrets daemon --db-path "./peer_a_db"

# Terminal 2: Peer B (custom port to avoid conflict)
p2p-secrets daemon --db-path "./peer_b_db" --port 4002 \
  --bootstrap "/ip4/127.0.0.1/tcp/4001/p2p/..."

# Terminal 3: Peer C
p2p-secrets daemon --db-path "./peer_c_db" --port 4003 \
  --bootstrap "/ip4/127.0.0.1/tcp/4001/p2p/..."

Setting Up a Network Across Machines

Machine A (Bootstrap Node - Public IP: 203.0.113.10):

p2p-secrets daemon --db-path "./peer_db"
# Note the Peer ID

Machine B (Remote Peer):

p2p-secrets daemon --db-path "./peer_db" \
  --bootstrap "/ip4/203.0.113.10/tcp/4001/p2p/12D3Koo..."

Firewall Configuration: Ensure TCP port 4001 is open on the bootstrap node.

Command Reference

Daemon Management

daemon

Start the P2P daemon process.

p2p-secrets daemon [OPTIONS]

Options:

  • --db-path <PATH> - Database directory path (default: ./db)
  • --bootstrap <ADDR> - Bootstrap peer multiaddress to connect to
  • --port <PORT> - TCP port to listen on (default: 4001)

Examples:

# Start standalone peer
p2p-secrets daemon --db-path "./peer_a_db"

# Connect to bootstrap peer
p2p-secrets daemon --db-path "./peer_b_db" \
  --bootstrap "/ip4/127.0.0.1/tcp/4001/p2p/12D3Koo..."

# Custom port
p2p-secrets daemon --db-path "./peer_db" --port 5001

status

Display daemon and peer information.

p2p-secrets status --db-path <PATH>

Output:

  • Peer ID
  • Number of connected peers
  • List of connected peer IDs
  • Secret count

Example:

p2p-secrets status --db-path "./peer_a_db"

ping

Test daemon connectivity.

p2p-secrets ping --db-path <PATH>

Returns "Pong" if daemon is responsive.

Secret Management

store

Store a secret locally.

p2p-secrets store <KEY> <VALUE> --db-path <PATH>

Arguments:

  • <KEY> - Unique identifier for the secret
  • <VALUE> - Secret value to store

Example:

p2p-secrets store "api_key" "sk-1234567890abcdef" --db-path "./peer_a_db"

get

Retrieve a locally stored secret.

p2p-secrets get <KEY> --db-path <PATH>

Example:

p2p-secrets get "api_key" --db-path "./peer_a_db"
# Output: ✅ Secret 'api_key': sk-1234567890abcdef

list

List all locally stored secrets.

p2p-secrets list --db-path <PATH>

Example:

p2p-secrets list --db-path "./peer_a_db"
# Output:
# Stored secrets:
#   api_key
#   database_password
#   admin_token

delete

Delete a secret (owner only).

p2p-secrets delete <KEY> --db-path <PATH>

Example:

p2p-secrets delete "old_api_key" --db-path "./peer_a_db"

Access Control

share

Grant access to a secret for another peer.

p2p-secrets share <KEY> <PEER_ID> --db-path <PATH>

Arguments:

  • <KEY> - Secret identifier
  • <PEER_ID> - Target peer's ID (12D3Koo... format)

Example:

# Get target peer's ID first
p2p-secrets status --db-path "./peer_b_db"

# Share the secret
p2p-secrets share "api_key" "12D3KooWDDvH2KrqDZhZHZLcPSLkANdQxtW5gXgSCzw3MRp4rRWZ" \
  --db-path "./peer_a_db"

revoke

Revoke access to a secret from a peer.

p2p-secrets revoke <KEY> <PEER_ID> --db-path <PATH>

Example:

p2p-secrets revoke "api_key" "12D3KooW..." --db-path "./peer_a_db"

request

Request a secret from another peer over the network.

p2p-secrets request <KEY> <PEER_ID> --db-path <PATH>

Arguments:

  • <KEY> - Secret identifier
  • <PEER_ID> - Peer who owns/shares the secret

Important: The secret must have been shared with your peer ID first.

Example:

# Peer B requests from Peer A
p2p-secrets request "api_key" "12D3KooWLhtLikHJ..." --db-path "./peer_b_db"

How it works:

  1. Your daemon sends a network request to the target peer
  2. Target peer's daemon checks if you have permission
  3. If authorized, secret is sent back over encrypted channel
  4. Secret is displayed but NOT stored locally
  5. Each access requires a new network request (fetch-on-demand model)

Maintenance

cleanup

Remove database directory and all stored data.

p2p-secrets cleanup --db-path <PATH> [--force]

Options:

  • --force - Stop daemon if running before cleanup

Example:

# Stop daemon first manually
p2p-secrets cleanup --db-path "./peer_a_db"

# Or force cleanup
p2p-secrets cleanup --db-path "./peer_a_db" --force

Security Model

Transport Security

Encryption: All network communication is encrypted using the Noise protocol framework:

  • XX handshake pattern for mutual authentication
  • ChaCha20-Poly1305 for symmetric encryption
  • Curve25519 for key exchange

Peer Authentication: Each peer has a unique cryptographic identity (PeerId derived from public key). Man-in-the-middle attacks are prevented by the Noise handshake.

Access Control Model

Owner-Based Permissions:

  1. Creator of a secret is automatically the owner
  2. Only the owner can grant/revoke access
  3. Only the owner can delete the secret
  4. Permissions persist across daemon restarts

Permission Checking:

Request for secret "api_key" from Peer B
          ↓
Check: Is Peer B the owner?
  Yes → Grant access
  No → Check ACL
          ↓
Is Peer B in allowed list?
  Yes → Grant access
  No → Access denied

Current Limitations

Secrets are stored unencrypted on disk:

  • RocksDB stores secrets in plaintext
  • Relies on filesystem permissions for protection
  • If database directory is compromised, secrets are readable

Mitigation:

  • Set proper file permissions: chmod 700 peer_db
  • Store database on encrypted filesystem
  • Run daemon as non-privileged user

No secret replication:

  • Each secret exists on only one peer's storage
  • If that peer goes offline, secret is unavailable
  • Single point of failure for each secret

No secret versioning:

  • Updating a secret overwrites the previous value
  • No history or rollback capability

Troubleshooting

Daemon Issues

Problem: Daemon won't start

# Check if port is in use
lsof -i :4001

# If occupied, use different port
p2p-secrets daemon --db-path "./peer_db" --port 5001

# Check database isn't locked
rm -rf ./peer_db/LOCK

Problem: Cannot connect to daemon (IPC errors)

# Verify daemon is running
ps aux | grep p2p-secrets

# Check socket file exists
ls -la ./peer_db/*.sock

# Restart daemon
# (Ctrl+C in daemon terminal or kill process)
p2p-secrets daemon --db-path "./peer_db"

Network Issues

Problem: Peers cannot connect

# Verify both daemons are running
# Check network connectivity
ping <peer_ip>

# Verify firewall allows TCP 4001
sudo ufw allow 4001/tcp  # Ubuntu/Debian
sudo firewall-cmd --add-port=4001/tcp --permanent  # CentOS/RHEL

# Check bootstrap address is correct (copy full multiaddress)

Problem: Connection established but request fails

# Verify secret was shared
p2p-secrets status --db-path "./peer_a_db"

# Check peer IDs match exactly
# Peer IDs are case-sensitive: 12D3Koo...

# Try ping to test connectivity
p2p-secrets ping --db-path "./peer_db"

Access Control Issues

Problem: "Access denied" when requesting secret

# Verify share was successful
# On owner's machine:
p2p-secrets status --db-path "./owner_db"

# Check you're using correct peer ID
# Your peer ID must match what was shared to

# Re-share if needed
p2p-secrets share "secret_key" "<your_peer_id>" --db-path "./owner_db"

Problem: Cannot delete secret

# Only owner can delete
# Verify you're the owner:
p2p-secrets list --db-path "./peer_db"

# Secrets you own will be listed

Database Issues

Problem: Database corruption

# Backup if possible
cp -r ./peer_db ./peer_db_backup

# Try cleanup and restart
p2p-secrets cleanup --db-path "./peer_db" --force

# Reinitialize
p2p-secrets daemon --db-path "./peer_db"

Problem: Disk space

# Check database size
du -sh ./peer_db

# List secrets
p2p-secrets list --db-path "./peer_db"

# Delete unused secrets
p2p-secrets delete "old_key" --db-path "./peer_db"

Building from Source

Development Setup

# Clone repository
git clone https://github.com/bahbah94/p2p-secrets.git
cd p2p-secrets

# Install dependencies (Rust/Cargo required)
rustc --version  # Should be 1.70+

# Build debug version
cargo build

# Run tests
cargo test

# Run with debug logging
RUST_LOG=debug cargo run -- daemon --db-path "./test_db"

Release Build

# Build optimized binary
cargo build --release

# Binary at: target/release/p2p-secrets
./target/release/p2p-secrets --help

Cross-Compilation

# Install cross
cargo install cross

# Build for Linux (from macOS)
cross build --release --target x86_64-unknown-linux-gnu

# Build for macOS Intel (from Linux)
cross build --release --target x86_64-apple-darwin

# Build for macOS Apple Silicon
cross build --release --target aarch64-apple-darwin

# Binaries in target/<target>/release/

Code Quality

# Format code
cargo fmt

# Lint
cargo clippy

# Fix clippy warnings
cargo clippy --fix

Future Roadmap

High Priority

  • At-Rest Encryption: Encrypt secrets in RocksDB using ChaCha20-Poly1305

    • Derive encryption key from user password or system keyring
    • Protect secrets even if database files are compromised
  • Secret Replication: Distribute secrets across multiple peers for redundancy

    • Owner specifies replica count
    • Automatic failover if primary peer offline
    • Consistency protocol for updates
  • Audit Logging: Track all access and modifications

    • Who accessed which secrets and when
    • Store logs locally and optionally share with secret owner
    • Tamper-proof log chain

Medium Priority

  • Key Rotation: Update secrets without changing access control

    • Version history
    • Automatic propagation to replicas
    • Rollback capability
  • Web UI: Browser-based interface for secret management

    • WebSocket communication with daemon
    • Visual peer network graph
    • Access control management UI
  • Secret Expiration: Time-based automatic deletion

    • TTL (time-to-live) for secrets
    • Scheduled expiration
    • Expiration notifications
  • Group Permissions: Share with multiple peers at once

    • Define peer groups
    • Grant access to entire group
    • Nested groups
  • Search and Filtering: Better secret discovery

    • Tag-based organization
    • Full-text search in keys
    • Filter by creation date, access count, etc.

Long-Term Goals

  • Mobile Apps: iOS and Android clients

    • React Native or Flutter
    • Push notifications for access requests
    • Biometric authentication
  • Secret Templates: Pre-defined secret structures

    • Database credentials template
    • API key template
    • SSH key template
  • Integration APIs: Easy integration with other tools

    • REST API server mode
    • Language-specific SDKs (Python, JavaScript, Go)
    • CI/CD plugins (GitHub Actions, GitLab CI)
  • Windows Support: Native Windows binary

    • Named pipes instead of Unix sockets
    • Windows service support
    • PowerShell integration
  • Advanced Networking: Better peer discovery and routing

    • mDNS for local network discovery
    • Relay nodes for NAT traversal
    • DHT improvements for larger networks
  • Backup and Recovery: Export/import functionality

    • Encrypted backup format
    • Selective export (specific secrets)
    • Restore to new peer identity
  • Monitoring and Metrics: Observability features

    • Prometheus metrics export
    • Grafana dashboards
    • Health checks and alerts

Contributing

Contributions are welcome! Here's how to get started:

Reporting Issues

Open an issue on GitHub with:

  • Clear description of the problem
  • Steps to reproduce
  • Expected vs actual behavior
  • System info (OS, Rust version)
  • Relevant logs

Submitting Pull Requests

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Make your changes
  4. Add tests if applicable
  5. Run tests: cargo test
  6. Format code: cargo fmt
  7. Lint: cargo clippy
  8. Commit with clear message
  9. Push and open PR

Development Guidelines

  • Follow Rust conventions and idioms
  • Write tests for new features
  • Update documentation for API changes
  • Keep commits atomic and well-described
  • Be respectful in discussions

Code of Conduct

Be kind, respectful, and constructive. This is an open-source project for learning and collaboration.

License

MIT License

Copyright (c) 2025 P2P Secrets Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

About

a p2p Secret sharing CLI tool.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages