Skip to content
Console

Identity Files

An identity file is private setup material for one client. It tells the SDK how to authenticate, which protocols are enabled, and where to connect.

Create identities in Thalovant, then give each deployed client only the identity it needs.

For local development, put SDK credentials in a protected YAML file:

Terminal window
install -d -m 700 ~/.config/thalovant
$EDITOR ~/.config/thalovant/config.yaml
chmod 600 ~/.config/thalovant/config.yaml

The SDKs read ~/.config/thalovant/config.yaml by default. If XDG_CONFIG_HOME is set, they read $XDG_CONFIG_HOME/thalovant/config.yaml. On Windows, they use %APPDATA%\Thalovant\config.yaml.

version: 1
profile: prod
profiles:
prod:
identity:
access_key: client-access-key
password: client-password
site_id: demo-agent
default_master: https://jokes.thalovant.io
default_port: 443
default_path: /public
data_plane_endpoints:
wss: wss://jokes.thalovant.io/public
https: https://jokes.thalovant.io/public
mqtt: mqtts://mqtt.thalovant.com:8883
protocols:
wss: { enabled: true }
http: { enabled: true }
mqtt: { enabled: true }
mqtt:
endpoint: mqtts://mqtt.thalovant.com:8883
username: client-access-key
password: client-broker-password
topic_prefix: <namespace>/<hub-id>/<client-id>
tls: true

You can add more profiles under profiles, then choose one in code.

SDK Load default profile Load named profile
Python ThalovantClient.from_config() ThalovantClient.from_config(profile="prod")
Node.js await ThalovantClient.fromConfig() await ThalovantClient.fromConfig({ profile: "prod" })
Go thalovant.NewClientFromConfig("", "") thalovant.NewClientFromConfig("", "prod")
Rust Client::from_config(None) Client::from_config(Some("prod"))
Field Required Purpose
access_key Yes Public identifier for the client.
password Yes Secret used by the client during auth.
site_id Recommended Stable client site, device, service, or runtime label.
data_plane_endpoints Recommended Explicit WSS, HTTPS, and MQTT addresses.
protocols Recommended Protocol availability for this hub.
mqtt MQTT only Per-client broker endpoint, username, password, and topic scope.

Hubs no longer issue a crypto_key. Transport encryption comes from the v3 Noise handshake, which derives its pre-shared key from password. Current SDKs accept and ignore crypto_key in older identity files. The identity still needs a valid password and enabled endpoint to authenticate.

{
"access_key": "client-access-key",
"password": "client-password",
"site_id": "demo-agent",
"default_master": "https://jokes.thalovant.io",
"default_port": 443,
"default_path": "/public",
"data_plane_endpoints": {
"wss": "wss://jokes.thalovant.io/public",
"https": "https://jokes.thalovant.io/public",
"mqtt": "mqtts://mqtt.thalovant.com:8883"
},
"protocols": {
"wss": { "enabled": true },
"http": { "enabled": true },
"mqtt": { "enabled": true }
},
"mqtt": {
"endpoint": "mqtts://mqtt.thalovant.com:8883",
"username": "client-access-key",
"password": "client-broker-password",
"topic_prefix": "<namespace>/<hub-id>/<client-id>",
"tls": true
}
}

Raw JSON identity files are still supported. Use them for downloaded single-client identities or mounted Kubernetes secrets. Use the YAML config when you want named local profiles.

If you keep _identity.json on a laptop, workstation, or VM, restrict it before the SDK reads it:

Terminal window
chmod 600 _identity.json

Python, Node.js, Go, and Rust SDKs reject local identity files with group or world permissions on Linux and macOS. In containers, mount the file from a secret store with owner-only permissions.

The SDKs also support environment variables for container and CI usage. Prefer secret stores for production deployments.

The identity file and Noise state work together. Keep both across application and container restarts:

Material Why it must survive
Client static private key The hub can pin this key after authentication. Replacing it on each start changes the client’s cryptographic identity.
Verified server pins The SDK uses these to recognize the hub on reconnect and reject an unexpected server key.
Cached PSK, when used This avoids repeating the password derivation. Protect it like the password; a credential change may require fresh derivation.

Use a private, writable, persistent directory or the SDK’s platform storage provider. An identity file mounted read-only is useful for credentials, but the SDK also needs writable storage for its own Noise state. A custom identity-file path does not by itself relocate that state. Language-specific directory options and platform requirements are listed on the SDK pages.

For server-side Node and MCP, the default state directory follows the default config directory: $XDG_CONFIG_HOME/thalovant when set, %APPDATA%\Thalovant on Windows, or ~/.config/thalovant otherwise. It contains noise_key, noise_pins.json, and any noise_psks.json cache. Preserve the directory as a unit. MCP has no per-tool Noise-directory option.

Node serializes complete filesystem state transactions across processes, including first-key creation and pin updates. Malformed or unreadable existing keys and pin maps stop the operation without resetting trust. Lock waits are bounded; if a writer crashes and leaves .noise-state.lock, confirm that writer has stopped before removing only the lock file. Keep the key and pin files. This filesystem lock does not coordinate live hub sessions or browser tabs.

Malformed saved pins stop authentication and trust updates without overwriting the original state. For SDKs that store hexadecimal pins, uppercase and lowercase encodings of the same key identify the same server.

A failed pinned-key handshake does not authorize deleting trust or regenerating a key. First check the identity password, endpoint, and availability of the original client key. Confirm an intended server-key rotation with the hub owner before deliberately updating a pin.

  1. Create one identity per active client process. Give parallel services, MCP processes, and devices separate identities. HTTP and MQTT sessions use identity-scoped state, so sharing credentials can make clients consume or close each other’s session.
  2. Store it as a secret. Use a secret store, protected environment, or private runtime volume.
  3. Keep access narrow. Grant only the permissions that client needs.
  4. Rotate on exposure. Recreate the client identity if a file or secret is copied to the wrong place.
  5. Review stale clients. Connections can show identity review when a client has not reported presence for a long time.
  6. Refresh after protocol changes. Create or download a fresh identity after enabling HTTPS or MQTT.

The dashboard marks a connection for identity review when no presence has been seen for an extended period. Review means “confirm the device or runtime is still expected” before trusting the identity again.

When the dashboard recommends quarantine, use Quarantine identity to disable runtime access and remove the client manifests. Rotate or recreate the identity before restoring access.

Use site_id and request context together:

Metadata Best use
site_id Stable runtime, device, room, service, or deployment label.
session_id Conversation, workflow, user journey, or trace group.
request_id Single request trace through logs and support records.
Context User, platform, app version, locale, or flow details.

Public repos

Do not commit identity files, copied setup commands, or raw environment files.

Browser bundles

Do not ship long-lived client secrets in JavaScript served to users. Use SDK Origins for reviewed browser domains, and keep secrets on a backend.

Logs

Redact passwords, access keys, crypto keys, broker passwords, and setup material before logging.

Support tickets

Share request IDs, hub names, and visible errors instead of setup material.

Last reviewed: September 9, 2026. Review this page when identity fields, config loading, file permissions, Noise persistence, or concurrent-client requirements change.