Do not paste the file into chat or email
A .env file is a list of working credentials. Sent in Slack, Teams or email, it becomes searchable by everyone with access to that conversation, synced to their phones, kept in backups and exports, and it stays valid until every key in it is rotated. If that already happened, rotate the keys: what to do if you leaked an API key covers how.
Sharing the values with a teammate
- Use a secrets manager or a shared password manager vault. Cloud providers have one (AWS Secrets Manager, Google Cloud Secret Manager, Azure Key Vault), and team password managers have shared vaults. Access is granted per person and can be revoked when someone leaves.
- Give each developer their own development keys where the provider allows it, such as Stripe test mode keys, instead of passing one production key around.
- Commit a template with names only, and keep
.envin.gitignore. This command writes a.env.examplewith the values removed. It also cuts comments that contain an equals sign, so skim the result:
sed -E 's/=.*/=/' .env > .env.example
- If a file really has to travel, encrypt it for the one person who needs it, for example with age and their public key. They decrypt it with their private key:
age -r <recipient-public-key> -o .env.age .env
age -d -i key.txt -o .env .env.age
Sharing the shape to debug it
To ask an AI assistant why the app cannot connect, or to attach the config to an issue, you need the variable names and the harmless values, not the credentials. That is what masking is for. Before highlights what PasteSafe finds, After is its exact output:
# billing-api, local development
NODE_ENV=development
PORT=3000
ADMIN_USER=admin
S3_BUCKET=acme-billing-exports
DATABASE_URL=postgres://billing:Wint3r-Fake-Pass@localhost:5432/billing
REDIS_URL=redis://:FakeRedisPass42@cache.internal:6379
STRIPE_SECRET_KEY=sk_test_51FakeKeyForDocs0nlyNotReal0000
JWT_SECRET=fake-jwt-signing-secret-9f8a7b
SMTP_PASSWORD=Fake-Smtp-Pass-1
ALERT_EMAIL=ops@example.net# billing-api, local development
NODE_ENV=development
PORT=3000
ADMIN_USER=admin
S3_BUCKET=acme-billing-exports
DATABASE_URL=postgres://billing:DB_PASSWORD_1@localhost:5432/billing
REDIS_URL=redis://:FakeRedisPass42@cache.internal:6379
STRIPE_SECRET_KEY=STRIPE_KEY_1
JWT_SECRET=SECRET_1
SMTP_PASSWORD=PASSWORD_1
ALERT_EMAIL=EMAIL_1The database password, the Stripe key, the JWT secret, the SMTP password and the email are replaced. NODE_ENV, PORT and the bucket name stay, which is often exactly what the AI needs to see. The Redis URL keeps its password, because there is no user name before the colon. Replace that one by hand.
- Paste the
.envinto PasteSafe. It runs in your browser. - Values under names like
PASSWORD,SECRET,TOKEN,API_KEYorPRIVATE_KEY, passwords in connection URLs with a user name, and known key formats become placeholders. - Read the result, fix anything left, and copy it.
- If the AI answers with placeholders, paste the reply into Put the real values back to see it with your values, still in your browser.
What PasteSafe does not catch in a .env file
- Passwords in URLs without a user name, like
redis://:password@host. - Short or simple values under neutral names, such as
ADMIN_USER=admin. - Hostnames, bucket names and account IDs, which may be internal but are not secrets.
Questions
Should I commit my .env file to git?
No. Add .env to .gitignore and commit a .env.example with the variable names and empty or dummy values. If a .env was already committed, rotate the keys in it and remove it from the history.
What is the safest way to share environment variables with a team?
A secrets manager or a shared vault in a team password manager, with access per person. You can see who has access and revoke it, which you cannot do with a file sent in chat.
Is it safe to send a .env file over Slack?
No. The file stays in the channel history, search and exports for as long as the workspace keeps messages, and anyone who can read it can use the keys. Use a secrets manager, or at least encrypt the file for one person.
Can I paste my .env into ChatGPT to debug it?
Mask it first. With placeholders the AI still sees every variable name and the harmless values like ports and modes, which is usually what the problem is about, but none of the credentials.