Reference

The settings file

Keep Gatesys SSH preferences, AI providers, hooks, command-risk rules and shell profiles in ~/.gatesys-ssh/settings.json, checked by a JSON schema.

Gatesys SSH keeps your preferences, your AI providers and your hooks in one JSON file you can read, edit and keep in a dotfiles repository. Changes in Settings are written to it, and edits you make to it apply while the app runs.

Where it is

SystemFolder
macOS and Linux~/.gatesys-ssh/
Windows%USERPROFILE%\.gatesys-ssh\

Every page of Settings shows the path under Saved automatically to, with Open settings.json and Reveal folder beside it.

The folder holds:

File or folderWhat it is
settings.jsonPreferences, AI providers without their keys, and hooks
settings.schema.jsonThe file’s schema, written by the app
hooks/A README, an example receiver (verify-signature.mjs) and a place for command-hook scripts
logs/Where a new file hook writes by default
account.jsonYour Gatesys account’s name, email and plan. See Sign in and licence
license.jsonThe licence on this device and its last check
farabi/system.mdFarabi’s instructions, the layer below its safety core. See Instructions and skills
skills/Your Farabi skills, one folder each with a SKILL.md. See The SKILL.md file

The folder is readable only by you, and so are its files. Hosts, trusted host keys, snippets, the audit log, host facts and the vault are not here: they stay in the app’s own data folder.

What the file holds

{
  "$schema": "./settings.schema.json",
  "version": 1,
  "theme": "system",
  "metricsInterval": 5,
  "farabiLanguage": "auto",
  "hooks": [
    {
      "name": "Ops receiver",
      "kind": "webhook",
      "url": "https://hooks.example.com/gatesys",
      "groups": ["sessions", "ai"],
      "secret": { "env": "GATESYS_HOOK_SECRET" }
    }
  ],
  "account": { "apiBase": "https://api.gatesys.ai" },
  "setup": { "completedAt": "2026-09-27T10:12:03.120Z" }
}
  • Preferences are top-level keys, such as theme, fontSize, scrollback, metricsInterval, aiEnabled and changeSafetyNetSeconds. A key you leave out takes its default.
  • aiProviders is the list of AI providers, and aiProviderId names the default one. API keys are never here.
  • farabiSkills lists the ids of the Farabi skills on in every conversation, and farabiAutoSkills sets whether a new panel turns on what a host’s facts suggest. See Instructions and skills.
  • farabiLanguage is the language Farabi writes and asks in: auto (the default, which follows this computer’s locale), en, tr or pt. See Farabi’s language.
  • commandRisks holds your own command-risk rules (add), the built-in rule ids you turned off (disable), and built-ins set to another level (lower, such as {"git-reset-hard": "caution"}). See Command risks in settings.json.
  • terminal.local holds defaultProfile, the id of the shell a new local terminal opens with (empty for your login shell), and profiles, your own shells. See Profiles in settings.json.
  • hooks is the list of hooks. A hook you add by hand needs a name, a kind (webhook, command or jsonl), its groups, and its url, command or path.
  • account.apiBase is the Gatesys account server, and account.authorizeUrl, when set, its sign-in page. See Another account server.
  • setup.completedAt records when the first-run setup finished. Remove it to see the setup again at the next start.

Edit the file

  1. Click Open settings.json in Settings, or open the file in any editor.
  2. Make your change and save.

The app reads the file a moment after you save and applies it straight away, with no restart. VS Code and Cursor read settings.schema.json through the $schema line, so they complete keys and flag wrong values as you type; the app checks every edit against the same schema.

When the app writes the file, it keeps your key order and any keys it does not know, writes through a temporary file so the file is never half-written, and leaves a symlinked settings.json a symlink. If you delete the file, the app writes the settings in use back.

When the file has an error

An edit that does not parse, or does not match the schema, is not applied. A banner across the top of the window says what is wrong and where, for example settings.json was not applied: line 8, column 17, with Open settings.json, and each Settings page says Error on line 8 of settings.json.

  • The app keeps using the last good settings.
  • It never overwrites the broken file. It is yours to fix. Changes you make in the app meanwhile last until you quit.
  • Save a fixed file and the banner goes away on its own.

Secrets stay out

The file is readable by any program you run and often ends up in a repository, so it never holds a secret. An edit that writes one is refused with a banner, like any other error: a value under a key such as password, token, apiKey or secret.

  • API keys and passwords go in the app, which keeps them in its vault.
  • A webhook’s signing secret is named, never written: "secret": {"vault": "<id>"}, set by the app, or "secret": {"env": "GATESYS_HOOK_SECRET"} to read it from the environment the app started in.

Command hooks and endpoints need approval

Anything that can write the file could otherwise point the app at a program or a server of its own. So a few things that arrive by an edit wait until you approve them once in the app:

Added in the fileWaits untilWhere to approve
A command hookIts program and arguments are approved, and again after any change to themSettings › Automation › Hooks: the hook reads Waiting for your approval; click Approve
A cloud provider endpoint on another machine, such as a gateway, that is not the vendor’s own APIApproved before your API key or a prompt is sent thereSettings › Farabi › Model: Set in settings.json — waiting for your approval for the default provider, or Needs approval in the providers list; click Approve
An account.apiBase that is not Gatesys’s own, or an account.authorizeUrlApproved before anything is sent there or your browser is sent to itSettings › Account: Approve the account server first
A skill in skills/ that the Injection Shield flagsApproved before any conversation uses it, and again after any change to itSettings › Farabi › Skills: the skill reads Flagged; click Approve
A built-in command-risk rule turned off in commandRisks.disable, or lowered in commandRisks.lowerApproved before the rule is weakened; until then it stays as it wasSettings › Safety › Command risks: settings.json weakens a rule; click Approve
A local shell profile in terminal.local.profilesApproved before it can open, and again after a change to its program, arguments, folder or environmentSettings › Terminal › Local terminal: the profile shows what it would run; click Approve

Rules you add to commandRisks, and built-ins you raise, apply at once: they only add protection. A critical rule can never be turned off, or lowered below danger, and the rules that block attacks cannot be weakened at all.

A hook, provider, rule change or shell profile made in Settings needs no extra step. Each approval is kept in the vault as a hash, so a program that edits settings.json cannot approve itself. A hook added by file edit carries a from settings.json tag on its card.

Keep a second profile

Set GATESYS_HOME to a folder before starting the app, and that folder is used in place of ~/.gatesys-ssh: its own settings, hooks, account, licence, Farabi instructions and skills.

GATESYS_HOME="$HOME/.gatesys-ssh-work" "/Applications/Gatesys SSH.app/Contents/MacOS/Gatesys SSH"

The variable names the folder itself, not its parent.

Something unclear or wrong? Tell us.