thcode uses a bring-your-own-key (BYOK) model: you supply your own API keys for each provider, and those keys stay entirely on your machine. The credential store is the single gateway through which secrets are written and retrieved. No key value ever appears in a config file,Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Temicide/thcode/llms.txt
Use this file to discover all available pages before exploring further.
.env, log, telemetry payload, prompt, or session transcript — the only place a key lives is the OS-managed credential facility.
The CredentialStore Interface
Every platform adapter implements the same interface so the rest of thcode never needs to know how the OS stores secrets:
CredentialId is a plain string — typically the provider name ("typhoon", "aiforthai") or the reserved per-install session data key id ("__thcode_session_dek__"). The availability() probe is non-mutating: it returns the backend kind without reading or writing any secret.
Windows DPAPI Backend
The Windows-first prototype stores each secret as a DPAPI-encrypted file under%LOCALAPPDATA%\thcode\credentials\<id>.cred. Encryption and decryption run through PowerShell 7 (pwsh.exe) using ConvertFrom-SecureString / ConvertTo-SecureString in the CurrentUser DPAPI scope. This approach:
- requires no native npm dependency;
- ties the ciphertext to the OS user account (another user on the same machine cannot decrypt it);
- keeps all storage logic behind the
CredentialStoreinterface so platform adapters can be swapped.
Secrets are piped to PowerShell over stdin, never over command-line arguments. This prevents the secret from appearing in process listings or shell history.
File locations
Platform paths follow OS conventions so session data, credentials, and checkpoints are stored in the correct user-state directory:- Windows
- macOS (deferred)
- Linux (deferred)
%LOCALAPPDATA% defaults to C:\Users\<you>\AppData\Local if the environment variable is unset.Onboarding Flow
The onboarding flow for a provider key follows a fixed sequence that ensures disclosure happens before the user ever types a secret.Select a provider
The CLI presents the available providers. Typhoon is the only Release-1 reasoning provider; AI for Thai is an optional separate credential for specialist tools.
Disclosure
Before accepting any input, the CLI prints exactly where the credential will be stored and which host it will contact. For Typhoon:Onboarding is blocked entirely in non-interactive (headless) environments; it fails closed with a
headless-blocked result rather than reading from stdin.Masked key input
The key is accepted through a masked, non-echoing input prompt. Empty keys are rejected before any write to the credential store.
Write to OS credential store
The trimmed key is written via
store.set(providerId, trimmedKey). If the OS credential facility is unavailable, onboarding returns a typed failed result — it never falls through to a plaintext write.Provider health check
After the key is stored, the CLI runs a live health probe against the configured endpoint to confirm the credential is valid and the provider is reachable. See Typhoon health checks for probe details.
Security Invariants
The following rules are enforced throughout the codebase and must be preserved in any extension or integration:Never persist in repo, config, logs, or telemetry
Never persist in repo, config, logs, or telemetry
A provider key must never appear in:
- any file committed to a repository (
.env, config YAML, JSON, TOML, etc.) - thcode config files
- log output, crash reports, or telemetry payloads
- prompts, tool results, or session transcripts
- SQLite session database entries or journal files
Never send to thcode server or cross-provider
Never send to thcode server or cross-provider
Each key travels only to its configured official provider endpoint:
- The Typhoon key goes only to
api.opentyphoon.ai. - The AI for Thai key goes only to
api.aiforthai.in.th. - Neither key ever reaches the hosted thcode service.
- A key for one provider is never reused against a different provider hostname.
Redact from tool output
Redact from tool output
Recognized credential patterns are redacted from tool output before they can enter a reasoning turn and appear in context.
Support explicit removal and rotation
Support explicit removal and rotation
Users can run
/disconnect at any time to remove a stored credential. Removing or rotating a key invalidates the current configuration generation and puts dependent providers back into unconfigured state — no cached key value remains in any product buffer or persistence layer.Credential Removal and Rotation
store.set(), a new configuration generation is registered, and a fresh health check runs against the updated credential.