Agents
Generate keys
Generate Ed25519 keypairs with the CLI, the AgentIdentity class or standard tooling, and understand key ids, thumbprints and the keystore.
Algorithm
Only Ed25519 is supported. Private keys are 32-byte seeds, public keys 32 bytes, signatures 64 bytes. The server identifies a key by a server-assigned id (key_…) and records its RFC 7638 JWK thumbprint; a public key can be registered once per agent.
With the CLI
node imnotahuman-agent.mjs keygen
# ✓ Generated Ed25519 keypair
# ✓ Private key saved to ~/.imnotahuman/agent.json
#
# Public key (paste this in the dashboard):
# _Gqb_W0_oiqrRCCw8P_X8DSeNSwTiMpA4rUS3OqqBZk
# Print instead of saving (for secret managers):
node imnotahuman-agent.mjs keygen --no-save --jsonkeygen does not talk to the server. Register the printed public key in the dashboard (Agent → Add key) or with POST /api/v1/agents/:id/keys, then finish with verify <registration challenge url> --agent agent_… --key-id key_…. The CLI persists the ids after the first successful verification.
With AgentIdentity
@imnotahuman/agent, @imnotahuman/react and @imnotahuman/server are private packages. They are not installed from npm. Use the script tag, the REST API, and the agent CLI at https://imnotahuman.ai/agent.mjs.
import { AgentIdentity } from "@imnotahuman/agent";
const identity = await AgentIdentity.generate();
console.log(await identity.publicKeyBase64url()); // upload this
console.log(await identity.publicKeyPem()); // or this
const seed = identity.exportPrivateKey(); // base64url seed: store securely
// Register directly with a registration token:
const { agentId, keyId } = await identity.register("reg_...", { label: "worker-3" });With OpenSSL
openssl genpkey -algorithm ed25519 -out agent-key.pem
openssl pkey -in agent-key.pem -pubout -out agent-pub.pem
cat agent-pub.pem # paste the PEM as public_keyThe PKCS#8 PEM in agent-key.pem is accepted directly by the SDK and by IMNOTAHUMAN_PRIVATE_KEY.
Keystore and environment
The CLI stores credentials in ~/.imnotahuman/agent.json (directory mode 700, file mode 600). Override the path with --keystore or IMNOTAHUMAN_KEYSTORE.
{
"version": 1,
"agent_id": "agent_nova_8f2a",
"key_id": "key_b7n2xq4mfc3rtw6y",
"private_key": "<base64url seed — secret>",
"public_key": "_Gqb_W0_oiqrRCCw8P_X8DSeNSwTiMpA4rUS3OqqBZk",
"api_base": "https://imnotahuman.ai",
"created_at": "2026-09-20T11:58:00.000Z",
"registered_at": "2026-09-20T11:58:04.000Z"
}Environment variables take precedence over the file, so CI and containers never need to write it:
| Variable | Example | Description |
|---|---|---|
IMNOTAHUMAN_PRIVATE_KEY | base64url seed or PEM | The private key. When set, the keystore file is ignored. |
IMNOTAHUMAN_AGENT_ID | agent_nova_8f2a | Agent id to sign as. |
IMNOTAHUMAN_KEY_ID | key_b7n2xq4mfc3rtw6y | Key id to sign with. |
IMNOTAHUMAN_API | https://imnotahuman.ai | API origin. |
IMNOTAHUMAN_KEYSTORE | /run/secrets/agent.json | Alternative keystore path. |
IMNOTAHUMAN_REGISTRATION_TOKEN | reg_… | Used by init when --token is omitted. |
whoami prints the stored agent id, key id and public key; it never prints the private key.