Security & Secret Management
Keeping credentials out of git — and what happens when you don't.
The Problem
Our first push to GitHub was blocked:
remote: - GITHUB PUSH PROTECTION
remote: - Push cannot contain secrets
remote:
remote: —— Grafana Cloud API Token ———————————————
remote: locations:
remote: - commit: 7fbe8cf...
remote: path: monitoring/alloy/config.alloy:18
GitHub's push protection scanned our commits and found the Grafana token hardcoded in the Alloy config file.
Why This Matters
A leaked Grafana token allows anyone to:
- Push arbitrary metrics to your Grafana Cloud account
- Exhaust your free tier limits
- Pollute your dashboards with fake data
The Fix — env() Injection
Alloy supports reading values from environment variables at runtime:
basic_auth {
username = "3163626"
password = env("GRAFANA_TOKEN")
}
The token never appears in the file — Alloy reads it from the environment when it starts.
File Structure
monitoring/alloy/
├── config.alloy ← committed — no secrets
├── .env ← NOT committed — real token
└── .env.example ← committed — placeholder only
.env.example (commit this):
GRAFANA_TOKEN=your_grafana_token_here
.env (never commit):
GRAFANA_TOKEN=glc_eyJvIjoiMTc1...
Add to .gitignore
echo "monitoring/alloy/.env" >> .gitignore
Running Alloy With the Token
source monitoring/alloy/.env
sudo -E alloy run /etc/alloy/config.alloy
The -E flag passes environment variables through to sudo.
The Git History Problem
When we tried git commit --amend after the blocked push, GitHub still rejected it. The token existed in two separate commits in git history — amend only rewrites the latest commit. We had to use git reset HEAD~2 to rewind history before those commits, then recommit cleanly. This taught us that git history is immutable — secrets must never enter commits in the first place.
Recovery Steps We Used
# Reset back before the bad commits
git reset HEAD~2
# Recommit cleanly — config uses env() now
git add monitoring/alloy/config.alloy monitoring/alloy/.env.example
git commit -m "feat(monitoring): add Grafana Alloy config with env-based token injection"
# Force push the rewritten history
git push origin monitoring/grafana-setup --force
Best Practices
| Practice | Why |
|---|---|
| Never hardcode tokens | Git history is permanent |
Use .env.example | Documents what variables are needed |
Add .env to .gitignore | Prevents accidental commits |
Use env() in config files | Tokens stay out of version control |
| Rotate tokens if exposed | Assume a leaked token is compromised |
1.Why can't you remove a secret from git history with just git commit --amend?
2.What is the correct way to store sensitive credentials for a tool like Grafana Alloy?
3.What does GitHub Push Protection do?