The discipline the whole course is built on. Every other article in this course assumes you have an .env file at ~/.openclaw/.env with the right permissions, the right secrets, and nothing else. This article is the discipline itself — why .env and not chat, why OpenClaw deletes passwords from notes, what chmod 600 actually does, and how to recover when you screw it up. If you read this and conclude "I'll just paste the key in Discord," you have missed the entire point of the course.
The non-obvious rule from the channel's "5 Must Know TIPS" video (Zkw8jIDzspc): OpenClaw will actively delete passwords from notes because it considers them insecure. The agent treats plaintext secrets in notes as a security violation and removes them. The .env file is the only path the bot treats as coding convention, so the credentials actually persist. The corollary: if you tell the agent "remember this API key" or paste it in a Notion page or write it in a Discord message, the bot will either ignore it, forget it on context reset, or actively delete it. .env is the only storage that survives.
This article walks through the .env setup, the permissions model, the security properties, and the audit checklist. The wider threat model (SSH keys, firewalls, Vault) is covered in Course 9: Security & Best Practices — this article is the integration-specific discipline.
What you'll learn
- OpenClaw will actively delete passwords from notes. The bot treats plaintext secrets in any non-
.envlocation as a security violation. If you tell the agent "remember my API key is X," it will either ignore you, forget on context reset, or delete the value from wherever you stored it..envis the only path it leaves alone. .envfiles have a specific security property AI models respect. Models like OpenClaw are trained not to reveal environment variable contents. The bot won't echo the value back at you in chat, won't paste it into a Notion page, won't include it in a debugging log. This is what.envhas that "remember this token" doesn't.- The setup is rigid. File location:
~/.openclaw/.env. Permissions:chmod 600(only your user can read/write). Format:KEY=value, one per line, no quotes unless the value has spaces. Restart the gateway after every edit (openclaw gateway restart). .gitignoreis non-negotiable. Even withchmod 600, the file shouldn't be in version control. Add.env,.env.local,.env.*.local,**/.env, and.openclaw/.envto.gitignorefrom day one. If you've committed a secret, consider it compromised — rotate, don't just delete from the working tree.- The principle of least privilege applies to capabilities, not just keys. Read-only API keys for analytics, read+insert for journaling, read+insert+update for tasks. The right default depends on what the agent needs to do — default to less capability, escalate when the use case demands it.
- The recovery playbook is short. Exposed secret → rotate immediately → update
.env→ restart gateway → audit logs. The longer you wait to rotate, the more likely the key is in someone else's hands. - Vault and AWS Secrets Manager are the production-grade alternatives for teams and shared infrastructure. For a personal OpenClaw install,
.envis the right answer. Reach for Vault when you have multiple users, audit requirements, or auto-rotation needs.
Why .env and not "remember this"
The fundamental reason: AI models are trained to forget things on context reset, and they're trained to flag secrets in plaintext as a security issue. The combination is fatal for any storage method that isn't .env.
Three things happen when you paste a secret in chat:
- The bot uses it once. The model has the value in context and can call the API.
- The bot forgets. On context reset (which happens daily for most OpenClaw installs), the value is gone. Next session, the agent asks "what's the API key?" again.
- The bot may actively delete it. If you write the secret in a note, a Notion page, or a Discord message, the bot's safety training may flag it and remove it. The agent "considers it insecure."
The .env file sidesteps all three:
- The bot reads it on demand. The value is in the shell environment, available to any process that needs it.
- The bot doesn't reset it. The file persists across sessions, reboots, and context wipes. The only way to lose the value is to delete the file.
- The bot treats
.envas a coding convention. The path~/.openclaw/.envis the convention for OpenClaw-specific secrets. The agent leaves it alone.
The host's framing in the "5 Must Know TIPS" video is explicit: "Force secrets into the .env file. OpenClaw will actively delete passwords from notes because it considers them insecure. Tell it explicitly to store API keys and secrets in the .env file." This is the single most load-bearing rule in the course — without it, every other integration breaks on the second day.
The setup, in five commands
The .env setup is mechanical. Five commands, in order:
# 1. Create the directory if it doesn't exist
mkdir -p ~/.openclaw
# 2. Create the .env file
touch ~/.openclaw/.env
# 3. Lock down permissions (only your user can read/write)
chmod 600 ~/.openclaw/.env
# 4. Edit the file
nano ~/.openclaw/.env
# 5. Add secrets in KEY=value format, one per line
# NOTION_API_KEY=secret_abc123XYZ456def789
# YOUTUBE_TRANSCRIPT_API_KEY=yt_live_abc123def456ghi789
# DISCORD_BOT_TOKEN=MTIzNDU2Nzg5MDEyMzQ1Njc4OQ...
Save with Ctrl+X, Y, Enter in nano. Verify:
ls -la ~/.openclaw/.env
# Expected: -rw------- 1 username username <size> <date> /home/username/.openclaw/.env
cat ~/.openclaw/.env | grep YOUTUBE
# Expected: YOUTUBE_TRANSCRIPT_API_KEY=yt_live_...
openclaw gateway restart
# Restarts the gateway so the new env vars are loaded
The -rw------- in the ls -la output is the permissions check. Only your user account can read or write the file. Other users on the system get a "permission denied" error if they try to read it. This is what chmod 600 enforces.
The format and the comments
Each secret is one line, KEY=value format. No quotes around the value unless the value itself has spaces. Comments are # to end of line. A realistic .env for an OpenClaw install with multiple integrations:
# Notion integration (read+write for tasks and journaling)
NOTION_API_KEY=secret_abc123XYZ456def789GHI012jkl345MNO678pqr901STU234vwx567YZA890
# Discord bot
DISCORD_BOT_TOKEN=MTIzNDU2Nzg5MDEyMzQ1Njc4OQ.GhIjKl.MnOpQrStUvWxYzAbCdEfGhIjKlMnOpQrStUv
# Telegram bot
TELEGRAM_BOT_TOKEN=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz1234567890
# YouTube Transcripts API
YOUTUBE_TRANSCRIPT_API_KEY=yt_live_abc123def456ghi789
# Custom APIs
COINGECKO_API_KEY=CG-abc123def456ghi789jkl012
TWITTER_API_KEY=AAAAAAAAAAAAAAAAAAAAABcde
OPENAI_API_KEY=sk-abc123def456ghi789jkl012
ANTHROPIC_API_KEY=sk-ant-api03-abc123def456ghi789jkl012
The comments are documentation — they tell future-you (or a teammate) which integration each key belongs to and what permissions it has. The chmod 600 keeps the file readable only by you, so the comments aren't a security issue.
Git and version control
.env should never be in version control. Even on a personal project. Even on a private repo. Even on a repo you've already deleted.
Add to .gitignore from day one:
# Environment variables
.env
.env.local
.env.*.local
**/.env
# OpenClaw specific
.openclaw/.env
.openclaw/**/.env
The **/.env catches .env files in any subdirectory. The .openclaw/.env is explicit because the home-directory path doesn't match **/.env.
Before every commit
# Check what will be committed
git status
# Search staged files for secrets
git diff --cached | grep -i "api_key\|token\|secret\|password"
# If you find a secret, STOP. Don't commit. Rotate the key.
The grep is paranoid by design. It catches api_key, token, secret, password in any case. If your staged diff contains any of these, you have a leak. The fix is never "delete from the working tree and recommit" — it's "rotate the key, update .env, recommit." The secret is in the git history even after you delete the file.
If you've already committed a secret
The recovery is severe: assume the secret is compromised and rotate immediately. The git history rewrite options (git filter-branch, git filter-repo) are technically possible but practically unreliable — the secret may have been cloned, forked, cached, or scraped by automated tools between the leak and the rewrite.
The right playbook:
- Rotate the exposed key immediately. Generate a new key at the service (Notion, Discord, etc.).
- Update
.envwith the new value. - Restart the gateway.
- Audit logs for unauthorized access (most services show recent API calls).
- Notify team members if the integration is shared.
- Document the incident — what was leaked, when, how it was discovered, what you did.
- Consider the old key burned. Even after rotation, treat the old key as compromised. Don't reuse it for other services.
The principle of least privilege
Not all API keys need the same capabilities. The right default is the smallest set of permissions the use case requires:
| Use Case | Notion Permissions | Discord Permissions | Telegram Policy |
|---|---|---|---|
| Data Analysis | Read only | N/A | Read only |
| Knowledge Base Journaling | Read + Insert | Send messages, Read history | DM pairing |
| Task Management | Read + Insert + Update | Manage channels, Send messages | Allowlist |
| Public Bot | Read + Insert + Update | Limited to specific channels | Pairing codes |
The channel's default is to enable all capabilities for new integrations and trust the agent to do the right thing — but the production-grade default is the opposite: start with the minimum, escalate only when the use case demands it.
For Notion specifically, the permissions decision is the §8.2 anchor — read-only for analytics, read+insert for journaling, read+insert+update for tasks. The bot doesn't need write access to your trade journal to count your trades; it only needs read.
The recovery playbook
When something goes wrong (exposed key, leaked secret, compromised .env), the playbook is short and the order matters.
If an API key is exposed
Immediate actions (within 5 minutes):
- Revoke the exposed key at the source — Notion, Discord, Telegram, etc.
- Generate a new key with the same permissions.
- Update
.envwith the new value. - Restart the gateway (
openclaw gateway restart).
Follow-up actions (within 24 hours):
- Review logs for unauthorized access.
- Check for unexpected changes in connected services.
- Notify team members if shared.
- Document the incident and how it happened.
- Update procedures to prevent recurrence.
If the .env file itself is compromised
Immediate actions:
- Rotate ALL keys in the file. If the file is compromised, every key in it is compromised.
- Check system logs for unauthorized access:
sudo grep "\.env" /var/log/auth.log - Review recent file access:
ls -lu ~/.openclaw/.envshows the last-accessed time. - Change system passwords if needed.
Follow-up actions:
- Enable 2FA on all integrated services.
- Review SSH access logs.
- Consider rotating SSH keys.
- Audit all connected services for suspicious activity.
Try it yourself
The hands-on goal: stand up a properly-locked .env file with at least three integrations, audit the permissions, and run the §8.3 security checklist end-to-end.
- Create the directory and file.
mkdir -p ~/.openclaw && touch ~/.openclaw/.env && chmod 600 ~/.openclaw/.env. Verify withls -la ~/.openclaw/.env— permissions should be-rw-------. - Add three integrations to
.env— pick Notion, YouTube Transcripts, and one more (Discord bot, CoinGecko, OpenWeather, whatever). Use the format from this article. - Restart the gateway and verify all three env vars are loaded. The exact verification depends on your OpenClaw install; most have a
openclaw config showor similar command. - Audit permissions. For each integration, confirm the capabilities match the use case. If you gave Notion full read+write but you're only using it for analytics, drop to read-only. If you gave Discord admin but you only need message-send, drop to specific permissions.
- Add
.envto.gitignore. If the project is in a repo, add.env,.env.local,.env.*.local,**/.env,.openclaw/.env.git statusto confirm.envdoesn't show as untracked. - Run the pre-commit grep.
git diff --cached | grep -i "api_key\|token\|secret\|password"should return nothing. If it returns anything, rotate the key immediately. - Test the agent's discipline. Send the bot: "remember this API key for later:
test_key_abc123." Verify the bot does NOT store the key anywhere accessible. Then send: "save this key to.env:TEST_KEY=test_key_abc123." Verify the bot edits the file or tells you to. - Rotate one key as a dry run. Generate a new Notion integration secret, update
.env, restart, verify the agent can still query Notion. This is the recovery playbook in miniature. - Run the §8.3 audit checklist from below.
- Document your setup. In a separate (non-secret) note, list which integrations you have, what capabilities each one has, and where the env var names live. The note itself should never contain the values.
The §8.3 audit checklist
Run this checklist after setting up .env, after any new integration, and once a month for ongoing maintenance.
Initial setup:
-
.envfile exists at~/.openclaw/.env - Permissions are
-rw-------(only owner can read/write) -
.envis in.gitignore(along with.env.local,.env.*.local,**/.env,.openclaw/.env) - Each integration uses a unique key (no key reuse across services)
- Each integration has only the permissions it needs (least privilege)
Ongoing maintenance:
- Keys rotated in the last 90 days (or per your security policy)
- No
.envkeys appear in chat history, Notion pages, Discord messages, or screenshots - OpenClaw version is up to date
- No security advisories outstanding for installed integrations
- Backup of
.envstored in a secure location (encrypted drive, password manager — NOT in the project repo)
Before sharing or recording:
- No
.envfile contents shown on screen - API keys redacted/blurred in screenshots
- Dummy keys used in tutorials
- Any keys shown in videos regenerated
- Recordings reviewed before publishing
Common pitfalls
- Pasting API keys in chat. The most common failure. The agent may use the key once and forget, or actively delete it on context reset. Always
.env. - Telling the agent "remember this key." Same as above — chat memory doesn't persist. The agent will ask you again next session.
- Storing keys in Notion or other notes. OpenClaw will actively delete passwords from notes because it considers them insecure.
.envis the only path the bot treats as coding convention and leaves alone. - Committing
.envto Git. Even once. Even by accident.chmod 600is irrelevant if the file is in version control. Add.envto.gitignorefrom day one. - Using one API key across multiple projects. A leaked key in one project takes down all your other projects. Use separate keys per project, separate keys per environment (dev/staging/prod).
- Hardcoding secrets in code.
config.pywithNOTION_API_KEY = "secret_abc..."is a disaster waiting to happen. Alwaysos.getenv("NOTION_API_KEY")and read from.env. - Granting admin permissions when scoped permissions would do. Discord admin, Notion full workspace, Telegram no pairing policy — these are bigger attack surfaces than the use case demands.
- Forgetting to restart the gateway after editing
.env. The gateway reads env vars at startup. If you add a new key but don't restart, the agent doesn't see it.openclaw gateway restartafter every edit. - Not rotating keys after a suspected leak. "I think I might have screenshared it once" is enough. Rotate, update
.env, move on. The cost of rotation is low; the cost of a compromised key is unbounded. - Sharing the same Notion integration across team members. Each team member should have their own integration. Otherwise the team's audit trail is one person's actions.
- Using
chmod 644orchmod 777"for convenience." These are world-readable or world-writable. Alwayschmod 600. There's no use case for a more permissive.env. - Skipping the 90-day rotation. The longer a key lives, the more likely it's been exposed somewhere. Rotate on a schedule. The actual interval depends on your threat model, but "never" is wrong.
Sources
- OpenClaw Skills: The SECRET to Accurate and Consistent Agents —
video_id: txTowBmYXMc· the context-overhead argument that motivates the.envdiscipline. Skills save context; secrets in chat burn context. - How to Build Your OpenClaw AI Agent the RIGHT Way — 2,690 views ·
video_id: Zkw8jIDzspc· "OpenClaw will actively delete passwords from notes because it considers them insecure. Tell it explicitly to store API keys and secrets in the.envfile" (host transcript, tip #5). This is the load-bearing quote for §8.3.
Notion troubleshooting deep-dive
The integration setup has six mechanical steps and three of them have hidden failure modes that only surface after you think everything is working. This appendix covers the failure modes the channel's transcripts flag and the recovery playbook for each.
"The agent says it doesn't have access to that database"
This is the most common failure and it's almost always the same root cause: the integration was created but not added to the specific database. Notion's permission model is database-scoped — workspace-level access doesn't grant database-level access.
The fix:
- Open the database in Notion
- Click "..." in the top-right corner
- Click "Connections" (or "Add connections")
- Find your integration name and click "Connect"
- Verify the connection shows up in the database's connection list
If the integration doesn't appear in the Connections menu, the integration was created in a different workspace. Create a new integration in the right workspace and repeat the setup.
If the integration appears but the agent still can't access the database, the issue is the capability setting. The integration needs "Read content" enabled at minimum. Check the integration's settings page at notion.so/my-integrations.
"NOTION_API_KEY environment variable not set"
The agent says it can't find the API key. The fix sequence:
# 1. Verify the file exists
ls -la ~/.openclaw/.env
# Expected: -rw------- 1 user user ... /home/user/.openclaw/.env
# 2. Verify the key is in the file
cat ~/.openclaw/.env | grep NOTION
# Expected: NOTION_API_KEY=secret_...
# 3. Verify the gateway can see the env var
openclaw config show | grep NOTION
# (Output depends on your install; some have a config-show command, others don't)
# 4. Restart the gateway
openclaw gateway restart
If the file exists and the key is in it but the agent still says "not found," the gateway hasn't picked up the new env var. Most OpenClaw installs read env vars at startup, not on every API call. Restart is the fix.
If the restart doesn't fix it, check for typos. NOTION_API_KEY vs NOTION_APIKEY vs NOTION_KEY are three different env vars. The Notion setup uses NOTION_API_KEY — if you named it something else, the agent won't find it.
"Integration secret was exposed — what now?"
The recovery playbook is short. The longer you wait to rotate, the more likely the secret is in someone else's hands.
Immediate actions (within 5 minutes):
- Go to notion.so/my-integrations
- Click on the compromised integration
- Under "Internal Integration Secret," click "Regenerate"
- The old secret is now invalid. Anyone holding it gets 401s on the next call.
- Copy the new secret
- Update
~/.openclaw/.envwith the new value - Restart the OpenClaw gateway
- Verify the agent can still query Notion
Follow-up actions (within 24 hours):
- Review Notion's integration activity log (if available — Notion's audit trail is limited)
- Check every database the integration has access to for unexpected changes
- Notify team members if the integration is shared
- Document the incident — when, how, what you did
Bigger picture: if the secret was in a public GitHub repo, a Discord message, a screenshot, or a video, treat it as permanently compromised. Regeneration invalidates the secret but doesn't un-leak it. Assume any third party that saw the old secret has it forever. Use the regenerated secret going forward and don't reuse the old one.
"Can't edit .env file — permission denied"
Two causes, both fixable:
# Cause 1: directory doesn't exist
mkdir -p ~/.openclaw
# Cause 2: file doesn't exist or has wrong permissions
touch ~/.openclaw/.env
chmod 600 ~/.openclaw/.env
# Then edit
nano ~/.openclaw/.env
If the file exists but you still get "permission denied," check the owner:
ls -la ~/.openclaw/.env
# Owner should be your user. If it's root or another user:
sudo chown $USER:$USER ~/.openclaw/.env
chmod 600 ~/.openclaw/.env
The file should be owned by the user running OpenClaw and only readable by that user. Any other ownership or permission is a security issue and should be fixed before proceeding.
- API Integration Guide — cross-referenced from §8.1 (
video_id: 2YPV2OmPZyo). The "store keys in.env, never paste in chat" framing is from the API integration walkthrough. - Git and version control hygiene — sourced from the §8.3 article's wider guidance. The
.gitignorepatterns, the pre-commit grep, and the rotation-after-leak playbook are standard security practice, not channel-specific.
Appendix to §8.3: advanced .env patterns
The basic .env setup in this article is right for a personal OpenClaw install on a single VPS. The patterns below cover the cases where the basic setup isn't enough.
Multiple .env files per environment
If you run OpenClaw in dev, staging, and production, use a separate .env per environment. Same env var names, different values:
# ~/.openclaw/.env (production)
NOTION_API_KEY=secret_prod_abc123
YOUTUBE_TRANSCRIPT_API_KEY=yt_live_prod_xyz789
# ~/.openclaw/.env.staging
NOTION_API_KEY=secret_staging_def456
YOUTUBE_TRANSCRIPT_API_KEY=yt_live_staging_uvw012
# ~/.openclaw/.env.dev
NOTION_API_KEY=secret_dev_ghi789
YOUTUBE_TRANSCRIPT_API_KEY=yt_live_dev_rst345
Symlink ~/.openclaw/.env to the right file per environment. The agent reads ~/.openclaw/.env; you control which file that points to. This is also how you test changes safely — dev env first, staging second, production last.
Secret rotation via cron
For high-value integrations, automate the rotation:
# Cron: 0 3 1 * * (3 AM on the 1st of each month)
0 3 1 * * /home/user/.openclaw/scripts/rotate-notion-key.sh
The script:
- Generates a new Notion integration secret via the Notion API
- Updates
~/.openclaw/.envwith the new value - Restarts the OpenClaw gateway
- Tests the integration (fetch a sample database to confirm the new key works)
- Logs the rotation result to a separate audit file
For personal use this is overkill, but for shared or production installs it's the difference between "we rotate keys manually" and "we have key rotation."
Encrypted .env backup
The .env file should be backed up, but the backup should be encrypted. Options:
- Password manager — 1Password, Bitwarden, etc. Store the
.envcontents as a secure note. - Encrypted file in cloud storage —
gpg -c .envproduces an encrypted file you can store in Dropbox, iCloud, etc. - Secret management service — HashiCorp Vault, AWS Secrets Manager, Doppler. For production-grade.
The rule: never store .env in plaintext anywhere outside the OpenClaw server. A plaintext backup in your email or cloud drive is a leak waiting to happen.
.env template files for new projects
For teams or for projects where multiple people need to set up the same integrations, use a .env.example template:
# .env.example (committed to git)
# Copy this file to .env and fill in your values
# Notion integration (https://notion.so/my-integrations)
NOTION_API_KEY=
# YouTube Transcripts API (https://youtubetranscript.io)
YOUTUBE_TRANSCRIPT_API_KEY=
# Discord bot (https://discord.com/developers/applications)
DISCORD_BOT_TOKEN=
The .env.example is committed to git; the .env is in .gitignore and never committed. New team members copy .env.example to .env and fill in their own keys. Each person has their own Notion integration, their own Discord bot, their own API keys. The template documents what env vars the project needs without exposing any values.