Skip to content
Community open-source Web · 0.2.6 release docs · 0.2.6Content reviewed: 2026-10-22View Markdown

5.1 Configuration and data locations ​

The current source workflow runs Teloa and DSH in local Node.js processes, with only PostgreSQL in Docker by default. Compose runs all three in containers. Both existing workflows use standard Docker; OrbStack is not required. Native npm installation is described below; keep data directories separate between installation methods.

Where files and programs are used ​

Native mode uses a local working directory and integrated, authorized tools. Compose uses programs and a working directory inside the container. The default Compose configuration does not mount your computer's entire filesystem and cannot directly invoke native desktop applications.

To expose a directory on your computer to a container, configure an explicit mount and its read/write permissions. The path belongs to the machine running the Docker engine; a remote engine does not automatically receive files from your computer. See Docker bind mounts.

Who manages each setting ​

SettingManaged inWhat to check
Business areas, employees, tasks and grantsTeloa pages and databaseUse the supported actions; direct database edits bypass validation
Models, keys, MCP and run configurationsThe DSH configuration reached from SettingsVerify a real call after saving
Extension compositionSource configuration and setup:dshPrepare and build again after changes
Browser authenticationA new authentication link from the launcherThe link changes after restart; do not publish it

Compose data locations ​

Named volumeContainer pathContents
app-data/data in the appDSH conversations, model configuration, Teloa working files and knowledge
postgres-data/var/lib/postgresql/data in the databasePostgreSQL business data
database-secret/run/teloa-secrets in the app and databaseThe generated database password
credentials-secret/run/teloa-credentials in the app only (read-only)The generated key storage master key, kept apart from app-data

Actual volume names include the Compose project prefix, such as teloa_app-data. Using -p changes that prefix. Do not confuse these volumes with the fixed container used for source development.

DSH configuration lives in /data/dsh, Teloa data in /data/teloa, and the working directory in /data/teloa/workspace. The database is reachable through the internal Compose service db; no database port is published on the device running Teloa.

Source development data locations ​

When you run Node.js directly from source, the database volume is teloa-postgres-data, the Teloa data directory is .runtime/teloa, and the DSH directory is .runtime/dsh. The adapter log is harness.log inside the data directory. Redact it before sharing.

For either installation, back up both the database and the working files. Copying source code or connection settings alone is not a complete backup.

Read-only dashboard database role ​

Business dashboard queries run over a dedicated login role, teloa_business_reader. The role can read only the table holding copies of business records and the safe helper functions, both in the schema that holds the Teloa tables (public by default). It has no superuser, create-database, create-role, replication or row-level-security bypass attributes, and it is not a member of any other role. Teloa checks these conditions at startup; if they do not hold, dashboard queries are disabled and the reason is written only to the server log.

The role password is generated randomly and kept in a password file inside the Teloa data directory (mode 0600, owned by the system user running Teloa); the database stores only a SCRAM verifier. To rotate the password, stop Teloa, delete the password file and start Teloa again. Startup generates a new password and updates the database role. Do not edit the file by hand or include it in shared backups.

npm data layout ​

GitHub Releases provides the native 0.2.6 package; see installation for native installation. The installer keeps program versions, application data, and working files separate: ~/.teloa/releases/ stores programs, instances/default/ stores sessions and configuration, and workspaces/default/ stores working files. Updating the npm package does not automatically migrate data or restart the service. Docker PostgreSQL is the default; an existing dedicated local database is an alternative. Do not mix these paths with a source or Compose installation.

Keys and environment variables ​

Model keys and connection grants share the DSH key storage, which prefers encryption with a master key in the system keychain or a master key file outside the DSH folder. Auto mode falls back to plaintext only on first initialization when neither is available, with a persistent warning in Settings. An existing encrypted store is locked if its key cannot be retrieved; it does not downgrade.

  • The source and container launchers drop key-like variables from the environment they start in: names that, split on _, contain a whole segment such as KEY, TOKEN, SECRET, PASSWORD or AUTH, and values that are URLs with a password (such as postgres://user:password@…). Only the dropped names are printed, never the values. The npm teloa command already passes a fixed short list of variables.
  • URLs with a password in proxy variables (such as HTTPS_PROXY=http://user:password@…) are dropped as well, and proxy variables have no _FILE form; with the source or container launcher, use a local proxy forwarder that needs no password. The npm teloa command passes proxy variables through unchanged under its allowlist.
  • Enter model keys in Settings. To inject one from a file, point <NAME>_FILE at a file only you can read (for example DEEPSEEK_API_KEY_FILE). The security action token likewise moves to TELOA_SECURITY_ACTION_TOKEN_FILE.
  • IM channel keys (FEISHU_APP_SECRET, FEISHU_ENCRYPT_KEY, LARK_APP_SECRET, LARK_ENCRYPT_KEY, TELEGRAM_BOT_TOKEN, SLACK_BOT_TOKEN, SLACK_APP_TOKEN) can only be saved under Settings > IM channels; environment variables and _FILE have no effect. When the launcher drops them, the startup log shows one extra notice.
  • With Teloa stopped you can maintain the key storage: teloa credentials --action export-plaintext --confirm writes an owner-only (0600) plaintext file before you roll back to the previous version; teloa credentials --action reset --confirm resets the store when the master key cannot be recovered and keeps the old files renamed to .bak-<time>. Reset deletes only the keychain entries this installation registered and never enumerates the keychain; if macOS still shows a keychain prompt, declining it does not stop the reset. The entry for the previous master key is kept so the .bak-* files can still be opened; delete it by hand in the system keychain (service Teloa Credentials) once you no longer need it.
  • An npm installation needs network access to fetch the system keychain component for the current platform. If you install offline (npm install --offline) and the local cache lacks that component, or the platform is not supported, the program still installs, but first initialization quietly uses a master key file instead, and it never switches back to the system keychain on its own. To move to the keychain: reinstall with network access, stop Teloa, optionally run teloa credentials --action export-plaintext --confirm first to keep a plain-text copy for re-entry, then run teloa credentials --action reset --confirm, start Teloa (set TELOA_CREDENTIALS_STORE=keyring to require the keychain), enter your keys again in Settings, and check the current method under Settings > Key storage.
  • teloa backup includes neither keys, authorizations nor the .env file in the DSH folder (it may hold plain-text keys). If you need it, save it yourself somewhere protected and, after a restore, put it back as instances/default/dsh/.env in the new installation (mode 0600); the backup and restore commands both print this reminder.
  • Security-related TELOA_* switches (the OAuth callback address, the security action address and token, usage statistics and online market switches, the data folder, acceptance switches and so on) are read only from the environment Teloa inherits at launch; setting them in a .env file in your project folder or the DSH folder has no effect. Upgrade note: such variables that you previously kept in either .env file stop working after the upgrade; Teloa prints one warning at startup listing only their names. Set them in the environment that launches Teloa instead (the npm-installed teloa does not pass them; put the OAuth callback in oauth.publicCallbackUrl in config.json in the data directory).
  • Known forms of AI tool calls that read key storage files, master keys, the DSH folder's .env, database password files or backup folders are blocked. Content matching saved keys in tool output or group posts is replaced with [已隐藏]. This raises the bar but does not cover arbitrary encodings or every outbound path; it is not a security boundary.
  • Settings > Key storage shows how keys are encrypted and keeps a warning on screen while the store is locked or can only save plain text. It also lists plain-text key copies left from before encryption: copies in old backups and upgrade backup folders, and .credentials.yaml.quarantine-* files set aside at startup. Nothing is deleted until you select the copies (one by one or all at once) and confirm again; each file is overwritten with zeros in place before it is removed. Files that share their contents with another path (hard links) are marked for manual handling in the list and cannot be selected; links, files that cannot be overwritten and files replaced after the list was built are not deleted either. SSDs, APFS and system backups (such as Time Machine) may still hold old data; overwriting with zeros does not guarantee physical erasure. Backups written elsewhere with teloa backup --output are not scanned; clean those up yourself.

Skill API keys ​

Skill key configuration does not enable unsupported resources. X Search, Finance Search, Macro Data, CellCog and CellCog Image Generation remain unsupported and cannot be enabled by entering keys.

The following workflow applies only to a supported, installed marketplace skill that lists its required keys:

  1. Open the skill under Resources > Apps and choose Keys. Review each key's purpose, required status, destination domain and path prefix, and injection location (Bearer, header or query parameter). Do not send keys in chat, write them into skill content or put them in environment variables.
  2. Enter the key in the password field and save. Fields are write-only, never prefilled with stored values, and cleared on submission; the page shows only saved or missing status. Teloa saves third-party API keys in the encrypted key storage described above, using the same storage tiers and initial fallback rules. Check the actual status under Settings > Key storage.
  3. If the catalog's key-use description changes, saving from an old page is rejected. The page refreshes the description; you must review it, enter the keys and submit again. Old input is not retried automatically. Reconfirmation clears old keys that you do not re-enter. Changes to destinations, methods, injection locations, variable names, labels and required status all require you to review again.
  4. A locked or read-only store prevents saving and deletion; unknown status is not shown as missing. Resolve it under Settings > Key storage first. To remove keys, choose delete and confirm again: this deletes all stored keys for that skill. It does not revoke them at the third-party provider; revoke them with the provider separately.

Teloa makes the request and injects keys only for the HTTPS origins listed by the skill, path prefixes and HTTP methods. At every hop it checks that all DNS results are public addresses, locks the connection addresses and verifies the destination hostname's TLS certificate. Only same-origin redirects that stay within what the skill lists are allowed. The web search and reading master switch and domain blocklist still apply. Binding follows the currently installed, active marketplace skill; a workspace skill overriding it by name receives no injected keys. The model cannot retrieve raw values through key interfaces and does not receive these keys through environment variables.

Limits: the authorized third-party service receives the keys. Response bodies are redacted by the values used and common encodings; this does not cover arbitrary transformations or control a provider's echoing or forwarding, and is not a general exfiltration boundary. Skill requests follow the official DSH proxy settings (HTTP_PROXY / HTTPS_PROXY / NO_PROXY). Direct connections check for public addresses and lock the connection address; through a proxy, the proxy resolves the destination, so address locking does not apply and protection comes from verifying the destination hostname's TLS certificate. Proxy addresses and accounts never appear in logs, errors or responses.

Write confirmation and employee grants: every request that changes data (POST, PUT, PATCH, DELETE) shows a confirmation card that you decide on the workbench; IM can only reject it. After a rejection or no answer, the same skill calling the same address with the same method does not show another card for 60 seconds. An AI employee's task session can use a skill's keys only if you tick that skill under Employees > Capabilities; skills added later are not granted by default, and sub-task and group-routed sessions can never use them.

Extra headers, call guides and shared keys: the catalog may allow a few extra request headers for a skill (up to 8); authentication, routing and forwarding headers are never allowed. The catalog may also include reviewer-written call guidance, which explains how to call the service but never widens the allowed addresses, methods or headers. Several skills can share one key: the key page lists the skills that share it, and saving or deleting applies to all of them at once.

IM channels ​

IM channels (Feishu, Lark (Feishu international), Telegram, Slack) ships with the app and is loaded by default; nothing needs to be installed from the marketplace. A channel starts running as soon as you enable it in Settings > IM channels (no restart needed); it needs Node.js 22 or later. Teloa connects out to each platform from your machine: Telegram uses long polling, Slack uses Socket Mode, and Feishu and Lark use a long-lived event connection (to open.feishu.cn and open.larksuite.com respectively), so no public address or inbound port is needed, but the machine running Teloa must be able to reach the platform.

  • Channel keys are stored only in the DSH key storage. The im-gateway/ folder in the data directory holds channel switches, bindings and audit records (folder 0700, files 0600) and never contains key values or pairing codes.
  • The Feishu SDK is not shipped with Teloa: the first time a Feishu or Lark channel is saved, Teloa downloads a locked version from npm, verifies its integrity, skips install scripts and places it in the data directory; both channels share this copy. Feishu and Lark channels cannot be added offline.
  • Only one process per data directory may connect IM channels (im-gateway/instance.lock). A second Teloa shows "Another Teloa is connected to this channel" for its channels, and its settings page is read-only.
  • Enabling or disabling only changes the DSH profile's bundle list; disabling keeps im-gateway/ and the keys. Source, container and npm upgrades re-register the bundled extension at startup and check that it comes from this program's own directory, so you do not need to re-run pnpm setup:dsh; if the source does not match, Teloa refuses to start. If you had configured channels before upgrading, IM channels is enabled once automatically (recorded in teloa-官方扩展.json in the profile directory).
  • teloa backup does not include keys: after a restore, save the channel keys again in Settings; bindings are kept in im-gateway/.
  • When moving Teloa, keep the bindings in im-gateway/ and re-enter keys in Settings on the new installation. Do not copy ciphertext as a substitute for re-entering them: its master key belongs to the original installation.

See Chat with employees from IM for usage.

OAuth callback address ​

App connections on Apps that need OAuth authorization with the service (such as Supabase remote, GitLab and Slack) send the authorization result back to Teloa's /oauth/callback:

  • Local deployments (Teloa listens only on 127.0.0.1) need no configuration; the callback is http://127.0.0.1:<port>/oauth/callback.
  • Inside the Compose container Teloa always listens on 127.0.0.1:3100, so the callback and the authorization entry are fixed at http://127.0.0.1:3100/oauth/…. If you change TELOA_PORT to another port, the browser is sent back to 3100 after authorization and never reaches Teloa. When you use OAuth connections, keep TELOA_PORT=3100, or set oauth.publicCallbackUrl below behind an HTTPS reverse proxy so the callback matches the address you actually use.
  • Server deployments (Teloa listens on 0.0.0.0 or another external address) must set a public HTTPS callback in config.json in the data directory. Otherwise starting authorization is refused with "Server deployments must set oauth.publicCallbackUrl in the configuration file to use OAuth authorization."
json
{
  "oauth": {
    "publicCallbackUrl": "https://teloa.example.com/oauth/callback"
  }
}
  • The address must use https:// and must not contain a user name, password or # fragment. Your reverse proxy must forward that path unchanged to Teloa's /oauth/callback, and forward the sibling start path (such as https://teloa.example.com/oauth/start) to Teloa's /oauth/start. Authorization opens through that entry: it first writes a one-time cookie to the browser and then redirects to the authorization server, so the callback must come back to the same browser. The authorization entry link is returned only to the person who started authorization; do not forward it. The first browser to open it is bound, and other browsers cannot complete authorization.
  • config.json lives in the data directory (.runtime/teloa/config.json when running from source, /data/teloa/config.json in Compose). It must be owned by the system user running Teloa and must not be writable by other users; otherwise the setting is ignored and a warning is logged.
  • Teloa reads it once at startup; restart after changing it. Only when the file has no such setting does Teloa fall back to the TELOA_OAUTH_PUBLIC_CALLBACK_URL environment variable.
  • The npm-installed teloa command passes only a fixed set of environment variables to Teloa, so TELOA_OAUTH_PUBLIC_CALLBACK_URL has no effect there. Set oauth.publicCallbackUrl in config.json in its data directory instead (by default ~/.teloa/instances/default/runtime/config.json).
  • Authorization tokens are also kept in the key storage and are no longer written to separate plaintext files under mcp/credentials/. Encryption and first-initialization fallback follow the rules above. Token values do not appear in connection configuration, pages or logs.

After changing configuration ​

Check that the change was saved, that it applies to the intended employee or task, and that an actual call succeeds. Extension code or composition changes may require a build and service restart in development. Refreshing the browser does not reload server code.

See Commands and configuration for environment variables and Backup, restore and upgrades for maintenance.