Your Secrets Are in Slack Right Now
Why every small company distributes secrets over Slack, and the one-afternoon exit plan: inventory, a single source of truth, runtime injection, and scoped IAM.

Somewhere in your company’s Slack, right now, there is a message that says “here’s the .env” with a file attached containing your production database password. It was DM’d by a senior engineer to a new hire on their first day, because that’s the onboarding process. There is no other onboarding process.
Every small company converges on the same secret distribution system: a senior dev pasting credentials into chat. The .env.example that was supposed to contain placeholders but has two real values in it because someone copied the wrong file. The Stripe key that appeared in a CI log when a debug step ran printenv. And the contractor who left eight months ago and still, technically, has every credential the company owns — because nothing was rotated when they left, because rotating everything felt like a quarter-long project, so nothing happened at all.
Why this persists #
Not because anyone thinks it’s fine. It persists because it works— right up until it very suddenly doesn’t. Secrets-in-Slack has zero day-to-day friction, and the failure mode is rare, invisible, and catastrophic: a laptop theft, a leaked log, a disgruntled ex-contractor, a Slack workspace export landing in the wrong hands. There’s no gradual degradation that nags you into fixing it.
And the perceived fix is enormous. “Do secrets properly” sounds like: deploy Vault, design a rotation policy, migrate every service, audit everything. A quarter of platform work. So it gets deferred indefinitely, and the Slack DMs continue.
Here’s the reframe: the dangerous part isn’t that your secrets aren’t rotated on a 90-day schedule. The dangerous part is that they’re distributed by hand and stored in a dozen uncontrolled places. Fixing distribution and storage is one afternoon. Rotation can come later — and becomes vastly easier once distribution is centralized.
The one-afternoon exit plan #
Total: roughly four hours for a typical small setup (5–10 services, 30–80 secrets). Do the steps in order.
Step 1: Inventory (30 minutes)
You can’t migrate what you can’t see. Grep the repo:
grep -rEn "(API_KEY|SECRET|TOKEN|PASSWORD|PRIVATE_KEY)" \
--include="*.env*" --include="*.yml" --include="*.yaml" \
--include="*.json" --include="*.tf" .Then check the places grep can’t reach: CI/CD environment variable settings, deploy scripts, that shared Google Doc, pinned Slack messages. Build one flat list with three columns: secret, what consumes it, where it currently lives. Expect 30–80 entries and at least two surprises — typically a credential nobody recognizes and a “temporary” token from 2022 that production depends on.
Don’t fix anything yet. Inventory only. The afternoon dies when step 1 turns into six side quests.
Step 2: Pick one source of truth (1 hour)
If you’re on AWS, the choice is between two managed options — and either beats what you have today:
- SSM Parameter Store (SecureString)— free for standard parameters, fine for almost everyone starting out.
- Secrets Manager— $0.40/secret/month plus API calls; buys you built-in rotation hooks and cross-account access when you need them later.
Pick one. Don’t deploy Vault this afternoon — a self-hosted secrets cluster is its own ops burden, and the goal today is to reduce the number of things that can go wrong.
Load everything from your inventory under a strict naming convention:
/app/{env}/{service}/KEY
/app/prod/api/DATABASE_URL
/app/prod/api/STRIPE_SECRET_KEY
/app/staging/worker/REDIS_URLThe convention matters more than it looks: it’s what makes step 4 (per-service IAM scoping) a three-line policy instead of an audit project.
Step 3: Runtime injection (1–2 hours)
Secrets should reach processes at start time, pulled from the store — never baked into images, never committed to files.
On ECS, the task definition does this natively:
"secrets": [
{
"name": "DATABASE_URL",
"valueFrom": "arn:aws:ssm:eu-west-1:123456789:parameter/app/prod/api/DATABASE_URL"
}
]On Kubernetes, External Secrets Operator syncs from SSM or Secrets Manager into native Secret objects your pods already know how to consume. For anything that can’t be changed today (a legacy VM, a cron box), a one-line wrapper bridges the gap:
eval $(aws ssm get-parameters-by-path --path /app/prod/worker \
--with-decryption --query "Parameters[*].[Name,Value]" \
--output text | awk -F'\t' '{n=$1; sub(/.*\//,"",n); printf "export %s=%s\n", n, $2}')Migrate service by service. Each one is a config change and a redeploy, not a rewrite.
Step 4: Scope IAM per service (30 minutes)
This is where the naming convention pays off. Each service’s role gets read access to exactly its own path:
{
"Effect": "Allow",
"Action": ["ssm:GetParameter", "ssm:GetParametersByPath"],
"Resource": "arn:aws:ssm:*:*:parameter/app/prod/api/*"
}Now a compromised worker container can’t read the API’s Stripe key. With the Slack-DM system, every secret was effectively readable by everyone forever; this single policy change is the biggest blast-radius reduction of the whole afternoon.
Step 5: Delete the .env files and set a tripwire (30 minutes)
Delete the .env files from the repo and from laptops where you can. Replace .env.examplewith key names only — no values, real or fake. Then make regression impossible to miss: add gitleaks or trufflehog to CI as a blocking check.
- name: gitleaks
uses: gitleaks/gitleaks-action@v2Note what this is: a tripwire for newleaks. Anything already committed lives in git history forever and must be treated as compromised — which brings us to the last step.
Deliberately last: rotation #
Rotation goes last on purpose, because making it a prerequisite is exactly how teams end up doing nothing for two years.
Today, rotate only the two or three scariest credentials — the ones that were in Slack, in git history, or in an ex-contractor’s possession. Usually: the production database password, the cloud provider root/admin keys, and your payment provider’s secret key. Each is a 15-minute job now that distribution is centralized: generate the new value, update one parameter, redeploy. No hunting through laptops.
Automate the rest later. Secrets Manager’s rotation lambdas, or a quarterly calendar event — fine either way. Imperfect rotation on top of centralized storage beats perfect rotation plans on top of Slack DMs every single time.
What you end up with #
For roughly $0–30/month and one afternoon, you’ve gone from “every secret is on every laptop and in chat history forever” to: one encrypted source of truth, per-service least-privilege access, injection at runtime, a CI tripwire against regression, and your scariest credentials freshly rotated.
The goal was never vault perfection. The goal is a specific, checkable property: no human needs to possess a production secret in order to deploy.Once that’s true, every future improvement — rotation automation, audit logging, short-lived credentials — is an incremental upgrade instead of a migration. And the next new hire’s onboarding doesn’t start with a DM containing your database password.
Review your cloud plan in Vylara, merge delivery changes as Git PRs, and deploy into your own AWS or Azure account when you’re ready.
Start freeRelated posts

Infrastructure State Collaboration Without a Team Meeting

Stop storing customer cloud keys: cross-account IAM with external IDs, end to end

