153 lines
7.1 KiB
Markdown
153 lines
7.1 KiB
Markdown
# 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.
|