# Configuration IronStorage uses one small TOML file. Pass an explicit file with `--config PATH`; otherwise the CLI loads `ironstorage/config.toml` below the native per-user configuration directory: - Linux and other Unix systems: `$XDG_CONFIG_HOME`, when it is absolute, or `$HOME/.config`; - macOS: `$HOME/Library/Application Support`; - Windows: `%APPDATA%`. An explicit relative configuration path is resolved from the process current directory. Relative `vault` and `key_material` paths inside the file are resolved from the directory containing the resolved configuration file. Absolute paths remain absolute. `.` and `..` components are normalized lexically; `~` is not expanded. The vault may be absent before `init`, but an existing vault must be a directory. Exported key material must already exist as a regular file or directory. ```toml vault = "../vault" default_key = "0123456789ABCDEF0123456789ABCDEF01234567" key_material = "keys" # An array avoids shell interpretation. A quoted command string is also # accepted and split without launching a shell. editor = ["code", "--wait"] # Optional; upstream pass defaults to 45 seconds. Values are limited to 1..300. clipboard_timeout_seconds = 45 # Optional; interactive frontends default to a two-minute inactivity lease. [security] inactivity_timeout_seconds = 120 biometric_unlock_enabled = false # Optional iPhone appearance: "system", "light", or "dark". [ui] mobile_appearance = "system" [git] user_name = "Alice Example" user_email = "alice@example.test" [[git.remotes]] name = "origin" url = "https://git.example.test/alice/password-store.git" server_id = "personal-git" application_id = "ironstorage-cli" ``` `default_key` is the required identity that the embedded OpenPGP layer resolves against the exported key material. It may be a full fingerprint, key ID, or exact user ID; ambiguity and key capability checks happen in the key resolver. Editor selection is deterministic: TOML, `$VISUAL`, `$EDITOR`, then `vim`. Commands are split into an executable and argument vector and are never passed through a shell. Only the CLI `edit` adapter may eventually launch this configured editor. `git.user_name` and `git.user_email` set the author for commits created by IronStorage. Both must be present together and cannot contain line breaks or angle brackets. The built-in IronStorage identity is used when both are absent. HTTPS remote URLs containing user information, passwords, queries, or fragments are rejected. `server_id` and `application_id` are opaque HTTPS-only references used to retrieve credentials from the operating-system secret store; duplicate names and duplicate reference pairs are errors. The HTTPS account name is stored inside the protected credential record, not in TOML. OpenPGP passphrases are addressed by the resolved primary fingerprint. SSH remotes use either `ssh://[user@]host[:port]/path` or scp-like `[user@]host:path` syntax and omit the HTTPS credential fields. They select exactly one private-key file or one already-running SSH-agent identity: ```toml [[git.remotes]] name = "origin" url = "git@git.example.test:alice/password-store.git" ssh_identity_file = "keys/id_ed25519" ssh_known_hosts_file = "known_hosts" ``` Relative paths are resolved against `config.toml`. If `ssh_known_hosts_file` is omitted, `~/.ssh/known_hosts` is used. Agent authentication replaces `ssh_identity_file` with an exact SHA-256 fingerprint and may name a socket explicitly: ```toml ssh_agent_fingerprint = "SHA256:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU" ssh_agent_socket = "/run/user/1000/ssh-agent.socket" ``` Private-key passphrases are stored by fingerprint in the operating-system secret store and never appear in TOML. Desktop builds obtain remotes from the password-store repository and honor the connection-only `Host`, `HostName`, `User`, `Port`, and `IdentityFile` directives in `~/.ssh/config`. IronStorage does not try additional keys, prompt for passwords or keyboard-interactive authentication, launch an agent, or invoke proxy/helper commands. The normal CLI, TUI, and desktop builds enable the storage `ssh` feature, so the same configuration drives branch discovery, clone, fetch, and pull over the embedded upload-pack channel; push and full pull-then-push synchronization use the matching embedded receive-pack channel. The typed endpoint model is always available so an SSH remote remains readable through the Rust API even when the binary was built without SSH. Such a build returns a typed unsupported-transport error before connection or repository mutation. The Apple bridge explicitly enables the storage `full` feature set without `ssh`, keeping the iPhone, AutoFill, and Watch dependency graph HTTPS-only until an Apple target opts in. The optional storage `ssh` feature contains `russh` 0.63.1 and Tokio; `russh` default features are disabled and the Ring backend plus RSA key support are selected explicitly. The reviewed release, algorithm allowlist, advisory, target, and size evidence is recorded in `ssh-transport-audit.md`. For SSH, URI paths are absolute, scp-like paths without a leading slash are relative to the remote account, and `~`/`~user` paths retain tilde-expansion semantics. Bracketed IPv6 and explicit URI ports are accepted. Host names are IDNA-normalized, repository paths may contain Unicode, and usernames are restricted to ASCII letters, digits, `.`, `_`, and `-`. Empty paths, control bytes, credentials, queries, fragments, ambiguous unbracketed IPv6 or colon paths, leading-option paths, local paths, URL rewrites, separate push URLs, helper transports, and unknown schemes fail closed. Server identity is checked before authentication against the configured known-hosts file. Exact, hashed, and non-default-port host entries are supported. Unknown keys return their host, algorithm, and SHA-256 fingerprint for explicit confirmation; confirming appends the key atomically. A changed key is a hard failure and is never replaced by that confirmation API. `clipboard_timeout_seconds` controls the native clipboard presentation lease. It defaults to 45 seconds for upstream `pass` compatibility and must be between 1 and 300 seconds. The CLI remains alive for the lease so Linux can serve its selection and every platform can restore or clear the value reliably without a background helper process. `security.inactivity_timeout_seconds` controls the shared authentication lease used by interactive frontends. It defaults to 120 seconds and accepts values from 1 second through 24 hours. The storage crate owns deadline calculation and relock; frontends report only genuine input events as user activity. Repaints, timers, background refresh, and Git work never extend the lease. `security.biometric_unlock_enabled` records only whether biometric unlock is enabled; the GPG passphrase remains in protected system storage. `ui.mobile_appearance` is shared, secret-free iPhone presentation state and defaults to the system appearance. Passwords, passphrases, tokens, credentials, private keys, and other secret values are forbidden in TOML. Unknown fields are rejected. Parse errors never echo the source line or value, so an accidentally supplied secret is not repeated in diagnostics.