Infernet Protocol uses a three-party key hierarchy (specified in IPIP-0028) that enables fine-grained permissions without sharing private keys. The three key types are: user keys, node keys, and model keys.
User keypair
├── signs node registrations
├── authorizes model installs/removes
└── delegates to → Node keypair
├── signs API requests to control plane
├── signs CPRs
└── delegates to → Model keypair (one per model artifact)
├── signs model-specific metadata
└── used for NIP-44 encrypted model comms
Each level can only do what its parent authorized. The user key (which the operator ultimately controls) never needs to be online — it’s only needed when registering a node or changing node permissions.
The user key is the operator’s master identity on the network. It’s analogous to a Nostr account key or an Ethereum wallet key.
Purpose: - Prove ownership of a set of nodes - Authorize node registrations - Sign operator profile metadata - Required for governance participation
Where it lives: In your personal wallet or key manager, ideally offline. It should not be on the node machine.
Format: secp256k1 keypair, encoded in bech32 as
nsec1... / npub1... (Nostr-compatible).
You don’t interact with the user key frequently — only when registering a new node or making major changes.
The node key is generated by infernet setup and lives on
the node machine. It’s the key that signs every API request and every
CPR.
Purpose: - Authenticate requests to the control plane - Sign Compute Payment Receipts - Identify the node on the network
Where it lives:
~/.infernet/keys/node.key (file permission 600)
Relationship to user key: The node key is authorized
by the user key. During infernet setup, the user key signs
a delegation message that says “this node key is authorized to act on
behalf of user X”. The control plane verifies this delegation before
accepting the node’s registration.
If you run multiple nodes, each has its own node key, but all are authorized by the same user key.
# View your node's public key
infernet status | grep "Public key"
# View the user key that authorized it
infernet status | grep "Authorized by"If you believe your node key is compromised, you can rotate it:
infernet keys rotateThis generates a new node keypair, signs the rotation with the old node key (proving you control the old key and are deliberately replacing it), and re-registers with the control plane. The old key is revoked. Any pending CPRs signed with the old key can still be redeemed during a 24-hour grace period.
Per IPIP-0028, each model artifact has its own secp256k1 keypair. This is the most granular level of the key hierarchy.
Purpose: - Sign model-specific metadata (version, hash, capabilities) - Enable NIP-44 encrypted communication between nodes and clients about specific model interactions - Support model-level reputation and provenance tracking
Where it lives: Generated by the daemon when a model
is installed, stored in ~/.infernet/keys/models/
~/.infernet/keys/models/
qwen2.5:14b.key
llama3.2:3b.key
deepseek-coder:6.7b.key
Format: Same secp256k1 format. Each model key is authorized by the node key that generated it.
Model provenance: When a client requests inference, the response includes a signature from the model key. This lets clients verify that the response came from the correct model artifact on the correct node.
NIP-44 encrypted channels: NIP-44 is a Nostr standard for encrypted direct messages using secp256k1 keys. Model keys can be used to establish encrypted channels between a client’s key and a specific model key. This enables confidential inference where the control plane can route the job without seeing the prompt content.
Model reputation: Model keys accumulate a reputation history on the control plane — successful completions, failure rate, latency percentiles. Clients can query this reputation before requesting a specific model key.
The full delegation chain:
User key
└─signs→ "node_key_abc123 is authorized"
└─signs→ "model_key_xyz789 is authorized for qwen2.5:14b on node_abc123"
└─signs→ inference response metadata
Each level in the chain can be verified independently by anyone with the parent’s public key.
infernet keys listUser key: npub1abc123... (not on this machine — delegation only)
Node key: npub1def456... (~/.infernet/keys/node.key)
Model keys:
qwen2.5:14b npub1ghi789... (~/.infernet/keys/models/qwen2.5:14b.key)
llama3.2:3b npub1jkl012... (~/.infernet/keys/models/llama3.2:3b.key)
# Get node public key in hex format
infernet keys export node --format hex
# Get in npub (bech32) format
infernet keys export node --format npub
# Get model key
infernet keys export model qwen2.5:14b --format hex# Verify a CPR signature
infernet keys verify cpr_7x2a1b3cFor applications requiring confidential inference, clients can use NIP-44 to encrypt the prompt:
This ensures the control plane and any intermediaries see only ciphertext. The node and the client share a secret derived from their keypair interaction, and no one else can read the conversation.
This feature requires a client-side library that supports NIP-44. Check the SDK documentation for current support status.