Skip to content

🔒 ZSHAND Security¶

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


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.

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.

See Also¶