TypeClawTypeClaw
Reference

secrets.json

Structured credential store schema

Gitignored. Managed by TypeClaw under the env-wins / file-never-auto-mutated policy (/concepts/secrets-policy).

{
  "version": 2,
  "providers": {
    "fireworks": { "type": "api_key", "key": "fw_xxx" },
    "minimax": { "type": "api_key", "key": "sk-cp-xxx" },
    "openai": { "type": "api_key", "key": { "env": "MY_CUSTOM_OPENAI_KEY" } },
    "anthropic": {
      "type": "oauth",
      "access_token": "…",
      "refresh_token": "…",
      "expires_at": 1735776000000
    }
  },
  "channels": {
    "slack-bot": {
      "botToken": { "value": "xoxb-…" },
      "appToken": { "env": "CI_SLACK_APP_TOKEN" }
    },
    "discord-bot": { "token": "…" },
    "telegram-bot": { "token": "…" },
    "kakaotalk": {
      "currentAccount": "alice@example.com",
      "accounts": {
        "alice@example.com": {
          "oauth_token": "…",
          "refresh_token": "…",
          "device_uuid": "…",
          "email": "alice@example.com",
          "encryptedPassword": {
            "v": 1,
            "alg": "AES-256-GCM",
            "kid": "…",
            "iv": "…",
            "ciphertext": "…",
            "authTag": "…",
            "createdAt": 1735776000000
          }
        }
      }
    }
  }
}

The Secret shape

type Secret = string | { value?: string; env?: string }

The string form is shorthand for { value }. The object form lets you bind a credential to a custom env-var name.

Resolution order

For any secret-bearing field:

  1. process.env[secret.env] if env is set
  2. process.env[canonicalEnvName] (platform's standard env var)
  3. secret.value from secrets.json
  4. Otherwise missing

Providers

typeFieldsEnv-wins?
api_keykey: Secretyes
oauthaccess_token, refresh_token, expires_at, …no (stateful refresh)

Channel adapters

AdapterFields
slack-botbotToken: Secret, appToken: Secret
discord-bottoken: Secret
telegram-bottoken: Secret
kakaotalkcurrentAccount: string | null, accounts: Record<accountId, KakaoAccountRecord>

KakaoTalk account record

FieldTypeNotes
oauth_tokenstringOAuth access token; rotated by SDK on refresh
refresh_tokenstringOAuth refresh token; rotated on the same cycle
device_uuidstringSDK-generated, persisted to skip phone-passcode confirmation on re-login
emailstringtypeclaw-only; renewal cron uses it for attemptLogin
encryptedPasswordEncryptedBlobtypeclaw-only; AES-256-GCM envelope, key at ~/.typeclaw/keys/<containerName>.key
(other SDK fields)catchall-passthrough for upstream-controlled fields

Encrypted blob envelope

type EncryptedBlob = {
  v: 1
  alg: 'AES-256-GCM'
  kid: string // key id, matches the on-disk key filename
  iv: string // base64
  ciphertext: string // base64
  authTag: string // base64
  createdAt: number // epoch ms
}

AAD is typeclaw:kakaotalk-password:v1:<containerName>:<accountId>, so ciphertext copied across accounts or containers fails authentication on decrypt.

Legacy shapes

Only the v2 envelope is accepted. The v1 envelope, pre-envelope flat shape, and auth.json filename are no longer supported — parseSecretsFile rejects them with an error. If you have an old file in one of these shapes, rewrite it to the v2 format shown above before booting.

On this page