#where to add api keys that are required for scripts /programs that will be invoked by skills ?
1 messages · Page 1 of 1 (latest)
i have kept the keys under skills.entries is this recommended approach ?
Use env vars/secrets, not plaintext in the skill itself.
Best options:
- General script env vars: put them in the Gateway environment or
~/.openclaw/.env:
MY_SERVICE_API_KEY=...
OpenClaw loads ~/.openclaw/.env without overriding already-set env vars.
- Per-skill config: use
skills.entries.<skillKey>in~/.openclaw/openclaw.json:
{
skills: {
entries: {
"my-skill": {
env: {
MY_SERVICE_API_KEY: "..."
}
}
}
}
}
This works, but it’s still plaintext in openclaw.json.
- Safer per-skill API key: if the skill declares a
primaryEnv, useapiKeywith a SecretRef:
{
skills: {
entries: {
"my-skill": {
apiKey: { source: "env", provider: "default", id: "MY_SERVICE_API_KEY" }
}
}
}
}
That keeps openclaw.json pointing at the env var instead of storing the key directly.
So: is it safe to keep keys in openclaw.json? It works, but I’d avoid it unless the file is local-only, not committed, and locked down (chmod 600). Prefer ~/.openclaw/.env, process env, or SecretRefs / 1Password / Vault for real secrets.
Docs:
https://docs.openclaw.ai/tools/skills-config
https://docs.openclaw.ai/tools/skills#environment-injection
https://docs.openclaw.ai/help/environment
https://docs.openclaw.ai/gateway/secrets
If it’s not being picked up, share openclaw --version and the skill’s env metadata, with keys redacted. 🦐
Yes, skills.entries is the right place for per-skill config/env, but for API keys I’d split it like this:
- ✅ Recommended shape:
skills.entries.<skill>.apiKeyas a SecretRef or env-backed value. - ⚠️ Works but less ideal: plaintext keys inside
skills.entries.<skill>.env.
Example recommended:
{
skills: {
entries: {
"my-skill": {
apiKey: { source: "env", provider: "default", id: "MY_SERVICE_API_KEY" }
}
}
}
}
Then put the real key in ~/.openclaw/.env:
MY_SERVICE_API_KEY=...
Plaintext under skills.entries.env is okay for quick local testing, but I wouldn’t treat it as the recommended long-term approach unless openclaw.json is private, never committed, and locked down.
Docs:
https://docs.openclaw.ai/tools/skills-config
https://docs.openclaw.ai/gateway/secrets
is it same for channels as well
Same principle, different location.
For channel credentials, use the channel’s own config path — not skills.entries.
Example:
{
channels: {
discord: {
enabled: true,
token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" }
},
telegram: {
enabled: true,
botToken: { source: "env", provider: "default", id: "TELEGRAM_BOT_TOKEN" }
}
}
}
Then keep the real secrets in ~/.openclaw/.env or the Gateway process env:
DISCORD_BOT_TOKEN=...
TELEGRAM_BOT_TOKEN=...
Plaintext directly in openclaw.json usually works, but I’d treat it as “okay for quick local testing,” not the recommended long-term setup. Prefer env vars / SecretRefs / token files where supported.
Channel field names vary (token, botToken, appToken, signingSecret, serviceAccountRef, etc.), so check the specific channel doc.
We're using SecretRefs for channels.slack and gateway.auth — works great. But skills.entries.env only accepts plain strings, not SecretRef objects. Is there a supported way to reference env vars in skills.entries.env instead of storing plaintext API keys there? Or is this on the roadmap?
Yes — for skills.entries.env, use ${VAR_NAME} env substitution. SecretRef objects are supported on skills.entries.<skill>.apiKey, but not directly inside skills.entries.<skill>.env.
Example:
# ~/.openclaw/.env
MY_TOOL_API_KEY=...
{
skills: {
entries: {
"my-skill": {
env: {
MY_TOOL_API_KEY: "${MY_TOOL_API_KEY}"
}
}
}
}
}
If the skill declares that key as its primaryEnv, the cleaner option is:
{
skills: {
entries: {
"my-skill": {
apiKey: { source: "env", provider: "default", id: "MY_TOOL_API_KEY" }