Complete guide for using softKMS v0.2.0 via CLI, PKCS#11, and HD wallet operations.
- Quick Start
- Admin Operations
- Identity Management
- CLI Reference
- PKCS#11 Usage
- HD Wallet Operations
- Key Export Operations
- Examples
- Troubleshooting
# Start daemon in foreground
./target/release/softkms-daemon --foreground
# Or with custom storage path
./target/release/softkms-daemon --storage-path /path/to/keystore --foregroundThe daemon boots locked and rejects key operations until it holds the master key.
# First boot only: initialize with a passphrase (prompts)
./target/release/softkms init
# After EVERY restart: unlock for the session (prompts)
./target/release/softkms unlock
# Clear the in-memory master key again
./target/release/softkms lockOutput (init):
Enter passphrase: ********
Confirm passphrase: ********
Keystore initialized successfully.
init leaves the daemon unlocked for the current session; after a daemon restart you must unlock
again (no passphrase is ever read from a file or environment variable). softkms health shows the
initialized and unlocked state.
# Create Ed25519 key (will prompt for passphrase)
./target/release/softkms generate --algorithm ed25519 --label "my-first-key"
# Output:
# Enter passphrase: ********
# Key generated successfully:
# ID: 550e8400-e29b-41d4-a716-446655440000
# Algorithm: ed25519
# Label: my-first-key# List keys (will prompt for passphrase)
./target/release/softkms listOutput:
Keys:
550e8400-e29b-41d4-a716-446655440000:
Algorithm: ed25519
Type: imported
Label: my-first-key
Created: 2026-02-17T12:00:00Z
Total: 1 keys
Key operations authenticate with either the admin passphrase (-p/prompt — full access to all
keys) or an identity token (--token, scoped to that identity's own keys). The examples below use
the admin passphrase; pass --token <token> instead to act as a client identity. Admin operations
verify the passphrase on every call, even while the daemon is unlocked.
# Create Ed25519 key (recommended for most use cases)
./target/release/softkms generate --algorithm ed25519 --label "ed25519-key"
# Create P-256 key (for FIDO2/WebAuthn compatibility)
./target/release/softkms generate --algorithm p256 --label "p256-key"
# Create Falcon-512 key (post-quantum)
./target/release/softkms generate --algorithm falcon512 --label "falcon512-key"
# Create Falcon-1024 key (post-quantum, higher security)
./target/release/softkms generate --algorithm falcon1024 --label "falcon1024-key"# List all keys
./target/release/softkms list
# With detailed output
./target/release/softkms list --detailed# Sign with specific key
./target/release/softkms sign --key "key-uuid" --data "Hello World"
# Sign with key by label
./target/release/softkms sign --label "my-key" --data "Hello World"Note: there is currently no
deleteCLI command. Key deletion is available through the gRPCDeleteKeyRPC and the REST API; a CLI subcommand is planned.
# Get key details
./target/release/softkms info --key "key-uuid"Create and manage identities for future token-based authentication.
# Create Ed25519 identity for AI agent
./target/release/softkms identity create --type ai-agent --description "Trading Bot"
# Output:
# Identity created successfully:
# Public Key: ed25519:MCowBQYDK2VwAyEAabc123...
# Token: eyJhbGciOiJIUzI1NiIs...
# Created At: 2026-02-17T12:00:00Z
#
# IMPORTANT: Save this token - it will never be shown again!Identity Types (--type):
ai-agent- AI/autonomous agentsservice- Backend servicesuser- Human userspkcs11- PKCS#11 clients
Signing-key algorithm is derived from the type: pkcs11 → P-256, all others → Ed25519.
Use --expires-in-days <N> to set token expiry (0 = never).
./target/release/softkms identity listOutput:
Identities:
ed25519:MCowBQYDK2VwAyEAabc123...:
Type: ed25519 (ai-agent)
Description: Trading Bot
Status: active
Created: 2026-02-17T12:00:00Z
Keys: 0
# Revoke an identity
./target/release/softkms identity revoke --public-key "ed25519:abc123..." --force
# Output:
# Identity revoked successfully.
# Identity ed25519:abc123... revoked successfullyNote: Revoked identities cannot be used for authentication. To re-enable, delete the identity file from storage and recreate.
-s, --server <URL> gRPC server URL [default: http://127.0.0.1:50051]
-p, --passphrase <PASS> Admin passphrase (required for most operations)
-t, --token <TOKEN> Identity token (for token-based authentication)
-h, --help Print help
-V, --version Print version
softkms init # first boot only — set the admin passphrase (prompts; --confirm true|false)
softkms unlock # after every restart — load the master key for the session (prompts)
softkms lock # clear the in-memory master key
softkms change-passphrase # re-encrypt the entire keystore under a new passphrase (prompts)change-passphrase transactionally re-wraps every key (admin, identities, seeds, symmetric) under a
new master key.
Generate a new signing key.
softkms generate --algorithm <ALG> [OPTIONS]Options:
-a, --algorithm <ALG>- Algorithm: ed25519, p256, falcon512, or falcon1024 (required)-l, --label <LABEL>- Key label for identification
List all stored keys.
softkms listOptions:
-d, --detailed- Show detailed information
Sign data with a stored key.
softkms sign [OPTIONS]Options:
-k, --key <ID>- Key ID (required if label not provided)-l, --label <LABEL>- Key label (alternative to --key)-d, --data <DATA>- Data to sign (required)
Generate a new key under the same label; the old key is retained (label cleared, marked rotated) so
prior signatures still verify.
softkms rotate --label <LABEL> # or --key <ID># Deterministic, recoverable from the mnemonic (HKDF-SHA512 over a label path)
softkms derive-symmetric --seed <SEED_ID_OR_LABEL> -P "m/sym/app/db-key" --label dbkey
# Fresh random key (NOT seed-recoverable)
softkms generate-symmetric --label ephemeralCiphertext is base64 of nonce || ciphertext || tag (AES-256-GCM, fresh 96-bit nonce per message).
CT=$(softkms encrypt --label dbkey --data "top secret" --aad "context")
softkms decrypt --label dbkey --ciphertext "$CT" --aad "context"Get detailed information about a key.
softkms info --key <ID>Import a BIP39 mnemonic phrase as a master seed.
softkms import-seed [OPTIONS]Options:
-m, --mnemonic <PHRASE>- BIP39 mnemonic phrase (12-24 words)-l, --label <LABEL>- Seed label
Derive a key from a BIP32 seed. Supports Ed25519 (BIP44) and P-256 (FIDO2/WebAuthn).
softkms derive [OPTIONS]Options:
-a, --algorithm <ALGORITHM>- Algorithm: ed25519 or p256-s, --seed <ID>- Seed ID to derive from-p, --path <PATH>- Derivation path for Ed25519 (e.g., "m/44'/283'/0'/0/0")--scheme <SCHEME>- Derivation scheme for Ed25519: v2 or peikert--origin <ORIGIN>- Origin/domain for P-256 (e.g., "github.com")--user-handle <HANDLE>- User handle for P-256--counter <N>- Counter for P-256 [default: 0]-l, --label <LABEL>- Key label
Examples:
# Derive Ed25519 key (BIP44 style)
softkms derive --algorithm ed25519 --seed <seed-id> --path "m/44'/283'/0'/0/0" --label "hd-key"
# Derive P-256 key (FIDO2/WebAuthn style)
softkms derive --algorithm p256 --seed <seed-id> --origin "github.com" --user-handle "user123" --label "fido2-key"Export an Ed25519 key to OpenSSH private key format for use with SSH.
softkms export-ssh [OPTIONS]Options:
-k, --key <ID>- Key ID to export-l, --label <LABEL>- Key label (alternative to --key)-o, --output <PATH>- Output path [default: ~/.ssh/id_ed25519]
Example:
# Export by label
softkms export-ssh --label "myEdKey" --output ~/.ssh/id_ed25519
# Export by key ID
softkms export-ssh --key abc123-uuid --output ~/.ssh/my_keyNotes:
- Only Ed25519 keys are supported for SSH export
- The private key is written with mode 0600 (owner read/write only)
- Original key remains encrypted in softKMS keystore
Export a key to GPG (OpenPGP) format for use with GnuPG.
softkms export-gpg [OPTIONS]Options:
-k, --key <ID>- Key ID to export-l, --label <LABEL>- Key label (alternative to --key)-u, --user-id <USER_ID>- GPG user ID (e.g., "User user@example.com")
Example:
# Export by label with custom user ID
softkms export-gpg --label "myEdKey" --user-id "John Doe <john@example.com>"
# Export by key ID
softkms export-gpg --key abc123-uuid --user-id "Backup Key <backup@example.com>"Notes:
- Supports Ed25519 and P-256 keys
- Supports HD-derived keys (32, 64, or 96 bytes)
- Key is automatically imported to GPG keyring
- Temporary file is deleted after successful import
Create a new identity for token-based auth (admin only).
softkms identity create [OPTIONS]Options:
-t, --type <TYPE>- Identity type: ai-agent, service, user, pkcs11 (required)-d, --description <DESC>- Description--expires-in-days <N>- Token expiry in days (0= never expires) [default: 0]
The signing-key algorithm is chosen from the identity type — pkcs11 identities get a P-256 key,
all others get Ed25519. There is no separate --key-type flag.
List all identities (admin only).
softkms identity list [OPTIONS]Options:
--include-inactive- Include revoked identities
Revoke an identity (admin only).
softkms identity revoke [OPTIONS]Options:
-p, --public-key <KEY>- Public key of identity to revoke-f, --force- Skip confirmation
Export keys from softKMS for use with external tools like SSH and GPG.
Check daemon health and status.
softkms healthShow PKCS#11 module information.
softkms pkcs11
softkms pkcs11 --module # Show module path# Get PKCS#11 module path
./target/release/softkms pkcs11 --module
# Output:
# /home/user/workspace/softKMS/target/release/libsoftkms.soThe module talks to the daemon's REST API; point it at the daemon with SOFTKMS_DAEMON_ADDR if it is
not on the default 127.0.0.1:8080. The PIN is an identity token (create a --type pkcs11
identity and use its token):
export MODULE=target/release/libsoftkms.so
# List slots / mechanisms
pkcs11-tool --module "$MODULE" --list-slots
pkcs11-tool --module "$MODULE" --list-mechanisms
# Log in with the identity token as the PIN and generate an EC key
pkcs11-tool --module "$MODULE" --login --pin "<identity-token>" \
--keypairgen --key-type EC:prime256v1 --label my-key -m 0x1040Note: the PIN must be an identity token — admin-passphrase login over PKCS#11 is not allowed.
# Import 12-word mnemonic
./target/release/softkms import-seed \
--mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" \
--label "my-wallet"
# Output:
# Seed 550e8400-e29b-41d4-a716-446655440000 imported and stored encrypted# Derive first key from seed
./target/release/softkms derive \
--algorithm ed25519 \
--seed "550e8400-e29b-41d4-a716-446655440000" \
--path "m/44'/283'/0'/0/0" \
--label "account-0-key-0"
# Output:
# Ed25519 key 660e8400-e29b-41d4-a716-446655440001 derived successfully./target/release/softkms derive \
--algorithm p256 \
--seed "550e8400-e29b-41d4-a716-446655440000" \
--origin "example.com" \
--user-handle "user123" \
--counter 0 \
--label "fido2-key"
# Output:
# P-256 key 770e8400-e29b-41d4-a716-446655440002 derived
# Key ID: 770e8400-e29b-41d4-a716-446655440002
# Public Key: base64...# 1. Start daemon
./target/release/softkms-daemon --foreground &
# 2. Initialize keystore
./target/release/softkms init
# 3. Create Ed25519 key
./target/release/softkms generate \
--algorithm ed25519 \
--label "signing-key"
# 4. Sign data
./target/release/softkms sign \
--label "signing-key" \
--data "Hello World"
# 5. Create identity for service
./target/release/softkms identity create \
--type service \
--description "Payment API"
# Save the token output!
# 6. Import seed for HD wallet
./target/release/softkms import-seed \
--mnemonic "abandon abandon ... about" \
--label "master-seed"
# 7. Derive Ed25519 key from seed
./target/release/softkms derive \
--algorithm ed25519 \
--seed "seed-uuid-from-step-6" \
--path "m/44'/283'/0'/0/0" \
--label "derived-key-0"
# 8. List all keys
./target/release/softkms list
# 9. Check identities
./target/release/softkms identity list
# 10. Health check
./target/release/softkms healthExport keys from softKMS for use with SSH and GPG:
# 1. Start daemon
./target/release/softkms-daemon --foreground &
# 2. Initialize (first time only)
./target/release/softkms init
# 3. Create an Ed25519 key
./target/release/softkms generate \
--algorithm ed25519 \
--label "my-ssh-key"
# 4. Export to SSH format
./target/release/softkms export-ssh \
--label "my-ssh-key" \
--output ~/.ssh/id_ed25519
# 5. Use with SSH
ssh -i ~/.ssh/id_ed25519 user@server
# 6. Create another key for GPG
./target/release/softkms generate \
--algorithm ed25519 \
--label "my-gpg-key"
# 7. Export to GPG format (auto-imports to GPG keyring)
./target/release/softkms export-gpg \
--label "my-gpg-key" \
--user-id "My Name <myname@example.com>"
# 8. Verify GPG key was imported
gpg --list-secret-keysExport HD-derived keys to SSH/GPG:
# 1. Import BIP39 seed
./target/release/softkms import-seed \
--mnemonic "abandon abandon ... about" \
--label "master-seed"
# 2. Derive Ed25519 key from seed
./target/release/softkms derive \
--algorithm ed25519 \
--seed "seed-uuid" \
--path "m/44'/283'/0'/0/0" \
--label "hd-key-0"
# 3. Export HD key to GPG (supports 96-byte HD keys)
./target/release/softkms export-gpg \
--label "hd-key-0" \
--user-id "HD Key <hd@example.com>"
# The export handles the 96-byte extended key automatically
# Only the first 32 bytes (the scalar) are used for GPGCause: Daemon started but keystore not initialized
Solution:
./target/release/softkms initCause: Wrong passphrase provided
Solution: Use the correct passphrase used during init
Cause: Trying to use a revoked identity token
Solution: Create a new identity with identity create
Cause: Key ID doesn't exist
Solution: Use list to see available keys
Use either the admin passphrase or an identity token (-t/--token). If both are supplied, the
token takes precedence.
# Admin operation (passphrase prompt, or -p)
./target/release/softkms generate --algorithm ed25519 --label k
# Identity-scoped operation
./target/release/softkms -t "<token>" generate --algorithm ed25519 --label kCause: Daemon not running
Solution: Start the daemon:
./target/release/softkms-daemon --foreground- Admin passphrase authentication (verified per call) and identity-token authentication
- Key generation (Ed25519, P-256, Falcon-512, Falcon-1024) — note: RSA/ECDSA are not implemented
- Key signing and verification (all supported algorithms)
- Key listing; key deletion via gRPC/REST (no CLI subcommand yet)
- Identity creation/revocation with per-token expiry
- Passphrase rotation (
change-passphrase) and key rotation (rotate) - BIP39 seed import; HD key derivation; seed-derived & random symmetric AES-256-GCM keys
- PKCS#11 provider (token-as-PIN); REST API; gRPC API; optional REST TLS/mTLS
deleteCLI subcommand- TPM 2.0 / cloud-KMS auto-unseal
- WebAuthn (design only)
- README.md - Overview and project status
- docs/IDENTITIES.md - Identity management details
- docs/API.md - gRPC + REST API reference
- docs/ARCHITECTURE.md - System architecture
- docs/SECURITY.md - Security model
- docs/OPERATIONS.md - Deployment, backup/restore, lifecycle