Summary
Credential handling across NemoClaw integrations uses inconsistent patterns that evolved organically as each integration was added at different times. This creates confusion about the intended architecture and makes security review harder.
Current state
| Credential |
Passed at sandbox creation |
Written to file inside sandbox |
Runs inside sandbox |
| NVIDIA_API_KEY |
Yes (env var via onboard) |
Yes — startup script writes auth-profiles.json (mode 0600) |
Yes |
| DISCORD_BOT_TOKEN |
Yes (env var, added in #601) |
No — OpenClaw reads env var directly |
Yes |
| SLACK_BOT_TOKEN |
Yes (env var, added in #601) |
No — OpenClaw reads env var directly |
Yes |
| TELEGRAM_BOT_TOKEN |
Deploy path only — not passed via onboard |
No |
No — bridge runs on host |
| Gateway auth token |
No — baked at Docker build time |
Yes — openclaw.json (root 444) |
N/A (security boundary) |
Problems
- NVIDIA_API_KEY gets extra file-write treatment that Discord/Slack don't. This is because OpenClaw's inference provider requires a specific JSON file, but it's not obvious why the patterns differ without reading the startup script.
- TELEGRAM_BOT_TOKEN is not passed through onboard at all — only through the deploy path. If a user sets up Telegram after initial onboard, they have to recreate the sandbox or run the bridge manually.
- No single place documents which credentials go where and why.
Proposed cleanup
- Standardize on env-var-at-creation for all user-provided secrets (NVIDIA, Discord, Slack, Telegram).
- Where OpenClaw requires a specific file format (auth-profiles.json), the startup script handles the translation — but this should be documented as the exception, not discovered by reading code.
- Add a credential inventory table to the architecture doc.
- Consider whether Telegram bridge should move inside the sandbox for consistency, or whether the host-side pattern is intentional and should be documented as such.
Context
This inconsistency became visible when #555/#588 made openclaw.json immutable, which broke Discord/Slack (#599, fixed in #601). Each fix was scoped narrowly to the immediate problem rather than unifying the pattern.
Summary
Credential handling across NemoClaw integrations uses inconsistent patterns that evolved organically as each integration was added at different times. This creates confusion about the intended architecture and makes security review harder.
Current state
auth-profiles.json(mode 0600)openclaw.json(root 444)Problems
Proposed cleanup
Context
This inconsistency became visible when #555/#588 made
openclaw.jsonimmutable, which broke Discord/Slack (#599, fixed in #601). Each fix was scoped narrowly to the immediate problem rather than unifying the pattern.