# Can I Store Sensitive Information in My Dotfiles? Security Risks and Safe Alternatives

> Never commit raw secrets to dotfiles. Learn secure alternatives for storing sensitive data like API keys and passwords to protect your credentials.

- Repository: [Ivan Smirnov/dotfiles](https://github.com/issmirnov/dotfiles)
- Tags: security
- Published: 2026-03-04

---

**No, you should never commit raw secrets like passwords or API keys to your dotfiles repository.** Instead, store sensitive data in untracked `.env` files and load them at runtime via your shell configuration to keep credentials secure while maintaining configuration portability.

The **issmirnov/dotfiles** repository is a public collection of configuration scripts designed to be symlinked into your home directory. Because these files are intended for sharing and public visibility on GitHub, the architecture explicitly discourages storing secrets directly in version-controlled files. Understanding this security model helps you protect credentials while leveraging the repository's automation.

## Why Storing Secrets in Dotfiles Is Unsafe

Several structural factors make the **issmirnov/dotfiles** repository unsuitable for hosting sensitive information:

- **Public visibility** – The repository is publicly hosted on GitHub, meaning any committed file is readable by anyone with internet access.
- **Explicit ignore rules** – The `/.gitignore` and `ubersicht/.gitignore` files explicitly skip `.env` files, signaling that secrets should live outside version control.
- **No encrypted storage** – The repository does not include tools like `git-crypt`, `blackbox`, or GPG wrappers for secret management.
- **Runtime environment loading** – Configuration files like [`zsh/config/paths.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/config/paths.zsh) set environment variables at runtime rather than storing them statically, and `zshrc` sources `$HOME/.zshenv` (see [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) linking `~/.zshenv`).

## How the Repository Structure Handles Sensitive Data

The **issmirnov/dotfiles** repository implements multiple safeguards to prevent accidental secret commits:

**`.gitignore` protections** – The root `.gitignore` explicitly ignores `.env` files and patterns (see [`.gitignore`](https://github.com/issmirnov/dotfiles/blob/master/.gitignore)), while `ubersicht/.gitignore` and `git/template/info/exclude` provide additional layers of protection for subdirectories and new clones.

**Symlink architecture** – The [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) file (lines 30-32) creates a symlink mapping that links `~/.zshenv` to [`zsh/config/paths.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/config/paths.zsh). This design allows you to source private, untracked files that exist only on your local machine without modifying tracked repository files.

**Template exclusions** – The `git/template/info/exclude` file ensures that new repositories created with this dotfiles configuration automatically ignore `.env` files, preventing secret leaks in future projects.

## Recommended Methods for Managing Secrets

Follow these practices to keep credentials secure while using the **issmirnov/dotfiles** setup:

1. **Use a local `.env` file** – Create environment files that are listed in `.gitignore`. The repository already ignores `.env` patterns globally, so these files will never be committed accidentally.

2. **Source from a non-tracked wrapper** – Modify your `~/.zshenv` (symlinked via [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml)) to source a private [`secrets.zsh`](https://github.com/issmirnov/dotfiles/blob/main/secrets.zsh) file that lives outside the repository. This keeps machine-specific credentials isolated from shared configuration.

3. **Consider encrypted storage** – If you must version-control secrets, add tools like `git-crypt`, `blackbox`, or `sops` to your setup. Note that the **issmirnov/dotfiles** repository does not provide these tools out-of-the-box, so you would need to implement them yourself.

4. **Avoid hard-coded credentials** – Never replace placeholder values in scripts (such as those in cheat sheets) with real passwords or tokens. Always reference environment variables instead.

## Implementation: Loading Secrets at Runtime

Here is how to implement secure secret management with the **issmirnov/dotfiles** repository structure.

Create a private `.env` file that will never be committed:

```bash

# ~/.dotfiles/.env   ← this file is ignored by .gitignore

export GITHUB_TOKEN="my-super-secret-token"
export DATABASE_URL="postgres://user:pass@localhost/db"

```

Load the `.env` file from `~/.zshenv`, which is symlinked by the repository:

```zsh

# ~/.zshenv  (linked from default.conf.yaml → zsh/config/paths.zsh)

# Load user-specific environment variables if the file exists

if [[ -f "$HOME/.dotfiles/.env" ]]; then
  source "$HOME/.dotfiles/.env"
fi

```

Reference secrets in scripts without exposing them in your dotfiles:

```zsh

# Example: git-push with a token (token stays in the environment)

git push https://$GITHUB_TOKEN@github.com/issmirnov/dotfiles.git

```

Ensure `.env` patterns remain in `.gitignore`:

```gitignore

# .gitignore – ensures .env files are never tracked

.env
*.env

```

## Summary

- **Never commit raw secrets** to the **issmirnov/dotfiles** repository because it is publicly visible and designed for sharing.
- **Store credentials in `.env` files** that are explicitly ignored by the repository's `.gitignore` rules.
- **Load secrets at runtime** by sourcing private files from `~/.zshenv`, which is symlinked via [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml).
- **Use environment variables** in scripts rather than hard-coded passwords to prevent accidental exposure.
- **Consider encryption tools** like `git-crypt` only if you absolutely must version-control sensitive data.

## Frequently Asked Questions

### What happens if I accidentally commit a secret to my dotfiles?

If you commit a secret to a public repository like **issmirnov/dotfiles**, you must assume it is permanently compromised. Immediately revoke the exposed API key or password, rotate your credentials, and use `git filter-repo` or BFG Repo-Cleaner to remove the secret from Git history. Simply deleting the file in a new commit does not remove it from the repository's history.

### How does the issmirnov/dotfiles repository load environment variables?

The repository loads environment variables through [`zsh/config/paths.zsh`](https://github.com/issmirnov/dotfiles/blob/main/zsh/config/paths.zsh), which is symlinked to `~/.zshenv` via the [`default.conf.yaml`](https://github.com/issmirnov/dotfiles/blob/main/default.conf.yaml) configuration (lines 30-32). This file sets up the `PATH` and other environment variables at shell startup, and you can extend it to source additional private files that contain your secrets without tracking them in Git.

### Can I use git-crypt with this dotfiles setup?

Yes, you can add `git-crypt` or similar encryption tools to the **issmirnov/dotfiles** repository, but the setup does not include them by default. You would need to initialize `git-crypt` in the repository, configure your GPG keys, and ensure that sensitive files are properly encrypted before committing. This approach allows you to version-control encrypted secrets while keeping them protected.

### Where should I place my .env file to ensure it stays private?

Place your `.env` file outside the tracked repository directories or in the repository root where it will be caught by the `*.env` pattern in `.gitignore`. The **issmirnov/dotfiles** repository explicitly ignores `.env` files in multiple locations including the root `/.gitignore`, `ubersicht/.gitignore`, and `git/template/info/exclude`, ensuring that environment files remain local to your machine and never appear in `git status` or commits.