identity.*
Identity and soul management RPC methods
identity.* reads and writes the identity files under each agent's directory (~/.aleph/agents/{agent_id}/) — the very files that SoulLayer / IdentityFilesLayer inject into every turn's prompt. All methods are wired at boot by register_identity_handlers against a SharedIdentityCtx (the default agent ID is captured at startup); the optional agent_id field on each request overrides the target agent.
Methods
| Method | Description |
|---|---|
identity.get | Read the live SOUL.md (raw + structured preview) and the status of every identity file |
identity.set | Write an identity file (default SOUL.md), snapshotting the prior version |
identity.clear | Remove an identity file (revert to default persona) |
identity.list | List existence / size of every identity file |
Historical references to
identity.sign/identity.verify/identity.rotateare not RPCs. The sign / verify chain lives insrc/gateway/security/crypto.rsfor internal delegation only and is not exposed via JSON-RPC.
Identity File Catalogue
IDENTITY_FILE_NAMES (src/thinker/identity_files.rs:17) defines the five canonical files, loaded in this order:
| File | Purpose |
|---|---|
SOUL.md | Core persona / identity statement |
IDENTITY.md | Identity metadata |
AGENTS.md | Agent-supplemental notes |
TOOLS.md | Tool-supplemental notes |
HEARTBEAT.md | Heartbeat-probe supplemental notes |
MEMORY.md is not whitelisted (writes are rejected by validate_identity_file_name); the memory system uses its own storage.
identity.get
Read the target agent's live SOUL.md (raw + best-effort structured parse via SoulManifest::from_file) plus the status of every identity file.
Request:
{ "jsonrpc": "2.0", "id": 1, "method": "identity.get", "params": { "agent_id": "main" } }Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"agent_id": "main",
"soul_md": "I am Aleph, calm and precise.\n",
"parsed": { "identity": "I am Aleph", "relationship": "peer" },
"files": [
{ "name": "SOUL.md", "exists": true, "size_bytes": 4096, "path": "/home/user/.aleph/agents/main/SOUL.md" },
{ "name": "IDENTITY.md", "exists": false, "size_bytes": 0, "path": "/home/user/.aleph/agents/main/IDENTITY.md" }
],
"has_custom_identity": true
}
}agent_id is optional; when omitted, the default captured at boot is used. The field must pass the path-safety check (no .., no separators, no NUL).
identity.set
Write an identity file (default SOUL.md). Before writing, backup_identity_file snapshots the prior version into <agent_dir>/backups/<file>.<UTC timestamp> (the newest 5 backups are kept).
Request:
{ "jsonrpc": "2.0", "id": 2, "method": "identity.set", "params": { "content": "You are Aleph, calm and precise.", "file_name": "SOUL.md" } }Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"success": true,
"agent_id": "main",
"file_name": "SOUL.md",
"bytes_written": 33,
"backup_path": "/home/user/.aleph/agents/main/backups/SOUL.md.20260315T100000000Z",
"note": "Identity updated. Takes effect on the next turn."
}
}Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
content | string | Yes | Full markdown content; max 1 MB per file |
file_name | string | No | Target file (must be in the IDENTITY_FILE_NAMES whitelist); default SOUL.md |
Changes take effect on the next turn: every prompt re-reads SOUL.md.
identity.clear
Remove an identity file (default SOUL.md) and revert to the default persona. clear is idempotent: clearing an absent file returns had_content: false rather than an error.
Request:
{ "jsonrpc": "2.0", "id": 3, "method": "identity.clear", "params": { "file_name": "SOUL.md" } }Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"success": true,
"agent_id": "main",
"file_name": "SOUL.md",
"had_content": true,
"backup_path": "/home/user/.aleph/agents/main/backups/SOUL.md.20260315T100000000Z",
"note": "Identity reverted to default. Takes effect on the next turn."
}
}Parameter: file_name (optional, default SOUL.md, same whitelist check as identity.set).
identity.list
List every identity file with existence / size / path.
Request:
{ "jsonrpc": "2.0", "id": 4, "method": "identity.list", "params": { "agent_id": "main" } }Response:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"agent_id": "main",
"files": [
{ "name": "SOUL.md", "exists": true, "size_bytes": 4096, "path": "/home/user/.aleph/agents/main/SOUL.md" },
{ "name": "IDENTITY.md", "exists": false, "size_bytes": 0, "path": "/home/user/.aleph/agents/main/IDENTITY.md" },
{ "name": "AGENTS.md", "exists": false, "size_bytes": 0, "path": "/home/user/.aleph/agents/main/AGENTS.md" },
{ "name": "TOOLS.md", "exists": false, "size_bytes": 0, "path": "/home/user/.aleph/agents/main/TOOLS.md" },
{ "name": "HEARTBEAT.md", "exists": false, "size_bytes": 0, "path": "/home/user/.aleph/agents/main/HEARTBEAT.md" }
]
}
}Safety Constraints
IdentityHandlerContext::resolve rejects any agent_id containing:
/or\(path separators)..(path traversal)- NUL (
\0)
An invalid agent_id returns -32602 Invalid params.
Relation to the self_config Tool
identity.* RPC and the self_config LLM tool read and write the same files: a tool write is immediately visible to the next RPC read, and vice versa. Both paths go through crate::thinker::identity_files.
See Also
- Methods Reference -- All method namespaces