Attach to an existing Salt master
In attach mode, Gardience does not run its own Salt master. It connects to the salt-api of a master you already run (Salt 3006.x, 3007.x or 3008.x), and your agents stay connected to that master. The Gardience server runs only the web front end, the Gardience service and the playbook runner.
Attach mode takes two parts: install Gardience pointed at your salt-api, then make a few one-time changes on your Salt master.
Before you start
- A Linux server for Gardience that meets the requirements. It does not need ports 4505 and 4506.
- Your salt-api URL, for example
https://salt-master.example.com:8000. The Gardience server must be able to reach it. - The Salt external authentication type (eauth) you want Gardience's two service accounts to use, for example
pam,fileorldap. - The IP address your Salt master uses to reach the Gardience server.
- The user names, from your master's eauth, of the people who will administer and approve in Gardience.
Part 1: install Gardience in attach mode
To install:
- Extract the bundle as described in Install on one server.
Run the installer with
--attach:sudo ./install/install.sh \ --attach https://salt-master.example.com:8000 \ --eauth pam \ --attach-master-ip 10.0.0.10 \ --master-address salt-master.example.com \ --admins alice \ --approvers bob,carol \ --hostname gardience.example.com \ --license /path/to/gardience-license.json- When it finishes, the installer prints the console address and points you to
ATTACH.mdin the install folder (/opt/gardience/ATTACH.mdby default). That file holds the master-side steps with your values filled in. Follow it in Part 2.
Attach options
| Option | Default | What it does |
|---|---|---|
--attach URL | not set | Turns on attach mode. The URL of your salt-api. Gardience sends all its Salt requests there, and the console's base pages are served from it. |
--eauth TYPE | file | The eauth type Gardience's service accounts (gardience-scanner and gardience-automation) sign in with on your master. |
--insecure-salt-api | off | Accept a self-signed salt-api certificate. Without it, Gardience checks the certificate. |
--attach-master-ip IP | none | The only address allowed to reach /gardience/internal/ on the Gardience server. Your master's single sign-on and vault modules call this endpoint. Without this option the endpoint answers no one, so those modules cannot reach Gardience. |
--admins A,B | none | User names from your master's eauth who administer Gardience. Admins also approve. If you give none, nobody has admin rights in Gardience until you set them with gardience roles. |
--approvers A,B | none | User names who may approve runs that someone else launched (the two-person rule). |
Also useful in attach mode:
--master-address: the address agents use to reach your master. It goes into the agent install commands and the enrollment playbook that Gardience generates. It defaults to--hostname, which is the Gardience server, so set it in attach mode.
What the installer does differently
In attach mode the installer:
- does not create a Salt master container or publish ports 4505 and 4506,
- does not create the
adminaccount or the service accounts (your people and accounts live in your master's eauth), - writes the admin and approver names to
config/roles.env, - builds an attach kit in the install folder:
attach-kit/saltgui(the console files) andattach-kit/srv(Gardience's Salt content), - writes
ATTACH.mdwith your salt-api URL, install folder, console port and eauth type filled in.
Part 2, the quick way: one command
From the Gardience server, with SSH access to your master as a user who can sudo:
sudo /opt/gardience/gardience attach-setup admin@salt-master.example.com --admins alice --approvers bob,carolIt copies the attach kit to the master (a root-only temporary folder, deleted afterwards) and runs setup-master.sh there. You can also copy attach-kit/ to the master yourself and run sudo ./setup-master.sh in it.
The setup reads your master's configuration with Salt's own loader, so your included files and master.d drop-ins count exactly as Salt counts them. It then shows a plan and changes nothing until you confirm (--yes skips the question, --dry-run only shows the plan):
- Your settings stay. Gardience's additions go in
master.d/zz-gardience.conf, which repeats the settings it extends with yours included: your file roots plus/srv/gardience; your salt-api port and certificate (or a new self-signed one on port 8000 if salt-api was not set up), now serving the Gardience console; your external pillars plus the Gardience vault; your reactors plus drift repair; your logins plus Gardience's two service accounts and the roles for the people you name. - Service accounts. With file eauth, the two accounts go in their own file, or are added to yours if you already use file eauth (your entries are kept). With PAM, they become local system users with no shell or home. With LDAP, create them in your directory first.
- Gardience's settings for salt-master and salt-api go in
/etc/salt/gardience.env(root only) with systemd drop-ins. Without systemd, pass--restart-cmdwith your own restart command that loads that file. - It checks its work. It restarts salt-master and salt-api, syncs the agents, and stops with a clear message if any agent that answered before no longer does.
- Undo.
setup-master.sh --undoremoves everything it added and puts your configuration back as it was.
It stops instead of guessing on a syndic setup or an eauth type other than file, PAM or LDAP: use the manual steps below there. After you change file_roots, external_auth, ext_pillar or reactor in your own files, or after gardience automation commands on|off, run gardience attach-kit and the setup again (a rerun is safe).
The steps below are what the command does, for doing it by hand.
Part 2: set up your Salt master
Do these once on the Salt master, then restart salt-master and salt-api. The values in capitals are in the .env file in the Gardience install folder. That file is readable by root only:
sudo grep -E '^(SVC_PASS|AUTOMATION_PASS|GARDIENCE_INTERNAL_TOKEN|GARDIENCE_SSO_KEY)=' /opt/gardience/.env- Console files. Copy
attach-kit/saltguito/srv/saltguion the master. Gardience content. Copy
attach-kit/srvto/srv/gardienceand add it as a second file root:file_roots: base: [/srv/salt, /srv/gardience]salt-api. Enable
rest_cherrypy, serve the console, and enable the clients Gardience uses:rest_cherrypy: port: 8000 ssl_crt: /path/to/cert.pem ssl_key: /path/to/key.pem app: /srv/saltgui/saltgui/index.html static: /srv/saltgui/saltgui/static static_path: /static netapi_enable_clients: [local, local_async, runner, wheel] worker_threads: 8 # salt-api and Gardience share the request server token_expire: 3600 # 1-hour sessions, so role changes apply quicklyMaster-side modules for single sign-on and the secrets vault. Load them and add the vault as an external pillar:
salt-run saltutil.sync_auth && salt-run saltutil.sync_pillarext_pillar: - gardience_vault: {}Give the
salt-masterandsalt-apiprocesses these environment variables, for example with a systemd drop-in usingEnvironment=:Variable Value GARDIENCE_INTERNAL_URLhttps://<Gardience host>:<console port>/gardienceGARDIENCE_INTERNAL_TOKENGARDIENCE_INTERNAL_TOKENfrom.envGARDIENCE_SSO_KEYGARDIENCE_SSO_KEYfrom.envGARDIENCE_INTERNAL_CAPath to the Gardience certificate, if the master does not already trust it The Gardience server answers
/gardience/internal/only from the address you gave with--attach-master-ip.Accounts. In the eauth type you chose, create the two service accounts with the passwords from
.env:gardience-scanner(passwordSVC_PASS) andgardience-automation(passwordAUTOMATION_PASS). Then grant them, and your people, rights inexternal_auth.ATTACH.mdlists the exact grants. In short:gardience-scannergets read-only functions,@jobsand@wheelkey.list_allandkey.finger_master(this server's ID, which the license is bound to).gardience-automationgets the functions Gardience calls (listed inATTACH.md, never.*),@jobs, thegardience_match.membersandgardience_match.end_sessionsrunners and@wheelkey.list_all,key.acceptandkey.reject(node approval, decided by admins in the console).- People, admins included, get
gdn:.*plus read-only functions (admins also@wheelkey.list_all,key.fingerandconfig.values, and every role thecache.grainsrunner). Agdn:grant is never matched by Salt itself, so it works only through Gardience, which applies approvals, change tickets, windows and locks first. Give no person.*,@runneror@wheelbeyond these: raw Salt access stays with root on the master, your break-glass. config.valuesreturns the master's whole configuration. Keep secrets (such asauth.ldap.bindpw) out of the master's configuration files, or leaveconfig.valuesout.- The
gardience_ssoentries map single sign-on roles (gardience-admin%,gardience-operator%,gardience-approver%,gardience-viewer%) to their rights.
- Enrollment from an Ansible inventory (optional). Set
autosign_grains_dir: /etc/salt/autosign_grainsand share the Gardience fileconfig/autosign/gardience_enrollinto that folder. Skip this if you approve agent keys by hand. Drift auto-repair. Add the reactor:
reactor: - 'salt/beacon/*/service/*': - /srv/gardience/reactor/drift.slsSync to agents:
salt '*' saltutil.sync_all- Recommended hardening. Salt lets an agent send batched events under any tag except a short blocklist, and that list does not include job returns, so a compromised agent could fake another agent's result. If you run no syndic, add
"salt/job/*/ret/*"toMINION_EVENT_BLACKLISTinsalt/daemons/masterapi.py. Gardience's own master image does this. Repeat it after every Salt upgrade. Who administers and approves. If you did not pass
--adminsand--approvers, or to change them later, run this on the Gardience server:sudo /opt/gardience/gardience roles --admins alice --approvers bob,carolThe service reads the change right away, with no restart. Run
gardience roleswith no options to show the current lists. Names may use letters, digits,_,.,@and-. People who sign in with single sign-on get their role from their identity provider group instead.
Check that it works
Within a few minutes, Overview > Dashboard lists your nodes. If it stays empty, the banner at the top of the console says what failed. Most often it is step 5: the scanner account needs @wheel key.list_all and @jobs.
Limits in attach mode
- Event rules and system locks write pillar data on the Gardience server, in
srv/pillarin the install folder. To use them, point your master'spillar_rootsat that folder on shared storage, or manage the same data in your own pillar. - Your master runs your own Salt build, so Gardience's hardening of the master (refusing forged job returns and events, keeping console sign-ins across restarts) is not applied to it, and
gardience doctordoes not check it. The all-in-one install includes both. - Your agents keep their own settings. Run the Agent self-recovery settings runbook once so they restart themselves if their connection to the master ever hangs.
- Accounts made with
gardience user addare not used. People sign in with your master's eauth, andgardience rolesdecides who is an admin or approver.