Skip to content

πŸ”’ ZSHAND SecurityΒΆ

How the framework handles credentials, file permissions, trust boundaries, and network access.

Rule of thumb

Secrets β†’ ~/.config/zshand/secrets.zsh only (auto chmod 600 on every startup).
Everything else β†’ env.zsh or config.toml. Never put API keys or tokens in env.zsh β€” it can appear in debug output or process listings.


Secrets ManagementΒΆ

User secrets (API keys, tokens, passwords) belong in $ZSHAND_CONFIG_DIR/secrets.zsh. The framework automatically enforces chmod 600 on this file during startup, ensuring only the file owner can read it. This file is never committed to version control β€” it is listed in .gitignore and excluded from all bundle operations that might leak content to logs.

Keep secrets out of env.zsh and aliases.zsh β€” those files may be readable by other processes or included in debug output.

Location Use for Permissions
secrets.zsh API keys, tokens, passwords Enforced 600 on startup
env.zsh Editor, PATH, non-sensitive env Normal; exported to shell
config.toml Framework flags (dev_mode, quiet, etc.) Normal

File PermissionsΒΆ

The framework applies the following permissions automatically:

  • secrets.zsh: chmod 600 (owner read/write only) β€” enforced on every startup
  • bin/*: chmod +x (executable) β€” set by zprime and zupdate
  • SSH agent state (~/.local/state/zshand/ssh-agent.env): user-only access

Compiled .zwc files inherit the permissions of their source files. The cache directory (~/.cache/zshand/) and log directory (~/logs/zshand/) are created with default umask permissions.

Network AccessΒΆ

The framework makes no network requests during initialization. All startup operations are local: reading files, loading bytecode, setting environment variables.

Network access occurs only in these explicit, user-initiated scenarios:

  • zupdate: Pings 8.8.8.8 to check connectivity, then runs git fetch/pull. Skips network operations gracefully when offline.
  • Atuin sync: The network monitor hook (_zshand_network_monitor) periodically checks connectivity and triggers atuin sync when online. Controlled by [network] monitor = true in config.toml.
  • cloner.sh: The installation bootstrap script clones the repository from GitHub.

Trust BoundariesΒΆ

The framework distinguishes between framework code and user code:

  • Framework code (core/, build/, shared_functions/, etc.) is maintained in the repository and compiled into bytecode bundles. Changes require zr to take effect.
  • User code (~/.config/zshand/) is loaded at startup but kept separate from framework files. User files with the same basename as framework files can override them in the full bundle.
  • User init.d/ and post.d/ scripts run before and after framework initialization respectively. These have full shell access and can modify any behavior.
  • The zshrc.zsh override ($ZSHAND_CONFIG_DIR/zshrc.zsh) completely replaces framework initialization when present.

Source ValidationΒΆ

  • zrebuild runs zsh -n on every .zsh file before compilation, catching syntax errors before they can cause runtime failures.
  • zprime validates syntax during compilation and reports errors.
  • health checks for conflicting shell configs, missing dependencies, and stale compiled caches.

GitleaksΒΆ

The framework source is clean of hardcoded secrets. The CI pipeline can be configured to run gitleaks as part of the lint job. User-specific secrets.zsh is excluded from version control by .gitignore.

Safe ModeΒΆ

If the shell fails to initialize three or more times within five minutes, safe mode activates automatically. Safe mode provides a minimal shell environment with basic PATH and a recovery menu β€” preventing a broken configuration from locking users out of their terminal. See SAFE_MODE.md for details.

Document Purpose
πŸ›‘οΈ Safe Mode Emergency recovery when init fails
πŸ‘€ User Configuration Config directory and secrets.zsh
πŸ”§ Troubleshooting Diagnosing problems
πŸ“š Documentation Index Full doc nav