Configuration Reference
Every configuration key telectl understands, where the config file lives,
and how environment overrides work. This page is generated from the config
schema in internal/config/config.go — if a key isn’t here, the bot doesn’t
read it.
Config file discovery
telectl searches these locations, in order (first match wins):
- An explicit path from
--config /path/to/telectl.yaml ~/.config/telectl/telectl.yaml~/.config/telectl.yaml/etc/telectl/telectl.yaml
Deliberate design choice: the working directory and
$HOMEare not searched.~/.kube/configand stray YAML files in the home directory would be misparsed as bot config, producing confusing errors likeyaml: control characters are not allowed(kubeconfigs contain binary cert data). A binary namedtelectlin the repo root would also collide with the config name.
A complete annotated example lives in the repo as
config.yaml.example.
Environment overrides
Every key can be overridden by an environment variable: uppercase the key
path, replace . with _, prefix with TELECTL_:
bot.rate_limit -> TELECTL_BOT_RATE_LIMIT
kubernetes.dry_run -> TELECTL_KUBERNETES_DRY_RUN
logging.level -> TELECTL_LOGGING_LEVEL
Credentials keep their conventional unprefixed names:
telegram.bot_token -> TELEGRAM_BOT_TOKEN
kubeconfig path -> KUBECONFIG
allowed user ids -> ALLOWED_USER_IDS (comma-separated)
CLI flags outrank config file and environment (see CLI flags below).
nav_order: 900
telegram
| Key | Type | Default | Description |
|---|---|---|---|
bot_token |
string | "" |
Bot token from @BotFather. Required. Env: TELEGRAM_BOT_TOKEN. |
allowed_user_ids |
[]int64 | [] |
Telegram user IDs permitted to use the bot. Empty = everyone who finds the bot can operate the cluster. Env: ALLOWED_USER_IDS. |
admin_user_ids |
[]int64 | [] |
Reserved for privileged operations (display/UX only — real authority is RBAC). Env: ADMIN_USER_IDS. |
parse_mode |
string | "MarkdownV2" |
Message parse mode: MarkdownV2, HTML, or "" for plain text. |
webhook_url |
string | "" |
Read but unused — webhook mode is not implemented; the bot uses long polling. |
webhook_port |
int | 8443 |
Read but unused — same as above. |
Why the example config has two user IDs
The sample configs in this wiki (Try It Locally, the manual test runbook) list two Telegram user IDs deliberately, because they demonstrate the two kinds of user the bot supports out of the box:
| Placeholder | Role | Impersonated as |
|---|---|---|
YOUR_ADMIN_TELEGRAM_ID |
full access | admin-user + system:masters (cluster-admin) |
YOUR_READONLY_TELEGRAM_ID |
read-only | readonly-user + viewers (get/list/watch only) |
Having both in one config is how you see RBAC working end-to-end: one user
can scale and delete, the other gets Forbidden on the same commands. It’s a
teaching setup, not a requirement.
Using just one ID
You don’t need two IDs. If you only want one person (or one kind of access):
- Single admin: put your ID in
allowed_user_ids, keep it inadminUserIds, and inuserMappingmap it toadmin-user. Delete the read-only mapping (or leave it — unused mappings are harmless). - Single read-only user: put your ID in
allowed_user_ids, map it toreadonly-user+viewers, and leaveadminUserIdsempty.
The mapping table maps each listed ID to an identity; IDs not listed in
userMapping fall back to impersonation.defaultUser / defaultGroups.
Keep every ID in allowed_user_ids quoted — unquoted, YAML renders
large numbers in scientific notation and the mapping silently breaks.
kubernetes
| Key | Type | Default | Description |
|---|---|---|---|
kubeconfig_path |
string | "" |
Path to kubeconfig. Empty → $KUBECONFIG, then ~/.kube/config. Env: KUBECONFIG. |
default_namespace |
string | "default" |
Namespace used when a command doesn’t pass -n/--namespace. |
context |
string | "" |
Kubeconfig context to use. Empty → the kubeconfig’s current context. |
timeout |
int | 30 |
API request timeout in seconds. |
dry_run |
bool | false |
Log mutating operations instead of performing them. Replies say so explicitly. |
impersonate_user |
string | "" |
Read but unused — use the impersonation: block instead. |
impersonate_groups |
[]string | [] |
Read but unused — same as above. |
burst |
int | 10 |
client-go request burst (rate limiting). |
qps |
float | 5.0 |
client-go requests per second. |
cluster_name |
string | "" |
Display name shown in /config, /version, main menu. Empty → kubeconfig context name. |
impersonation
Per-user Kubernetes RBAC. When enabled, the bot impersonates a K8s identity mapped from the Telegram user ID — Kubernetes RBAC, not the bot, decides who may do what.
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
bool | false |
Enable impersonation. |
default_user |
string | "" |
Identity to impersonate for unmapped users. e.g. system:serviceaccount:default:readonly. |
default_groups |
[]string | [] |
Groups to carry for unmapped users. e.g. [viewers]. |
user_mapping |
map | {} |
telegram_user_id → {user, groups}. |
impersonation:
enabled: true
default_user: "system:serviceaccount:default:readonly"
default_groups: ["viewers"]
user_mapping:
"YOUR_ADMIN_TELEGRAM_ID":
user: "admin-user"
groups: ["system:masters"]
"YOUR_READONLY_TELEGRAM_ID":
user: "readonly-user"
groups: ["viewers"]
⚠️ The mapped
groupsmust match actual ClusterRoleBindings, or the impersonated identity has no permissions. See Impersonation & RBAC.
logging
| Key | Type | Default | Description |
|---|---|---|---|
level |
string | "info" |
debug, info, warn, error. |
format |
string | "json" |
json or console. |
output |
string | "stdout" |
stdout or stderr. |
bot
| Key | Type | Default | Description |
|---|---|---|---|
max_message_length |
int | 4096 |
Telegram’s message limit. |
command_prefix |
string | "/" |
Prefix for typed commands. |
enable_markdown |
bool | true |
Render rich formatting. |
rate_limit |
int | 30 |
Per-user, per-minute message throttle. |
allowed_commands |
[]string | (all) | Commands the bot dispatches. Must stay in sync with registered handlers — a command missing here is rejected as “not allowed” even though its handler exists. |
enable_menu_button |
bool | true |
Register the bot menu (☰) commands. |
enable_reply_keyboard |
bool | true |
Persistent reply keyboard under the input box. |
menu_page_size |
int | 10 |
Items per page in list views. |
CLI flags
telectl [flags]
Flags:
--config string Config file (searches $HOME/.config/telectl/, ...)
--token string Telegram bot token (or TELEGRAM_BOT_TOKEN)
--kubeconfig string Path to kubeconfig (or KUBECONFIG)
--allowed-users string Comma-separated Telegram user IDs
--log-level string debug | info | warn | error (default "info")
--dry-run Log mutations instead of performing them
Subcommands:
telectl # run the bot (default)
telectl version # print version + commit + build date
telectl config # print effective configuration (redacted) and exit
telectl contexts # list kubeconfig contexts and exit
Flags outrank config file and environment.
Validating your config
telectl config --config /path/to/telectl.yaml
Prints the effective, merged configuration (secrets redacted) so you can see
exactly what the bot will use. Also run the bot with --log-level debug to
see which config file was loaded at startup.