Skip to content

Sessions and approvals

A session is one task on one or more servers: you write what you need, Heinzel proposes commands, the code classifies each one, and depending on the level it runs at once or waits for you.

Starting a session

The form under New session asks four things.

FieldWhat you choose
ServerOne, preset to the one used last. Or several: as one session that reaches all of them (moving a database from db to standby), or as the same task on each, a rollout (see Rollouts). A session reaches only the servers it was started with; if it needs one more, it ends and offers a new one with the wider set.
TaskOne to three sentences. What you want to know or what should be the case afterwards, plus what Heinzel has to know: the time, the customer, what must not happen.
LevelHow far Heinzel goes on its own, see below. Preset to what the tenant's policy says, never more than you may do on the server.
ModelOnly when several are open to you. Plus the effort (default, or a level the model offers).

Three good tasks

Input: On web03 customers have been getting sporadic 502s since 2 pm. Find the cause. Restart nothing before you have told me what it is.

Input: Create the user "monitoring" on db1 and db2 with read-only rights on all databases, password from the secret MONITORING_DB.

Input: The certificate on mail01 expires in 9 days and certbot has failed to renew it three times. Why, and put it right.

What the three share: a server or two, a goal, and the limit Heinzel has to know. A task like "tidy up a bit" gets a question back instead of a command.

The three levels

Every session chooses at its start how far Heinzel goes on its own. The interface writes the levels like the permissions of a file.

LevelRuns without approvalWhat for
Every command waitsnothing, not even readingA server where you want to see every move, such as the first contact with an unfamiliar system.
rw- Asks before changescommands that only readDaily work. Heinzel reads on its own, finds, explains, and every change waits for you.
rwx Changes alonewhat the tenant's matrix runs at once, by default everything but identitiesSchedules at night, rollouts, routine on servers whose outage you can bear.

For every command the lowest of four limits counts:

  1. The tenant's ceiling, set by the installation (rw- or rwx).
  2. The person's letters on this server, from their teams and groups.
  3. The server's ceiling, that of its groups and of the login used.
  4. The session's choice.

Example: Anna has rwx on the group Web through her team. The server web07 carries the ceiling rw-, because the customer looks after it too. If Anna starts a session there on "Changes alone", every change still goes through an approval. The session says so when it starts.

The command card

Every command Heinzel proposes appears as a card with four parts.

A command card waiting for approval: class service, the server, the complete command, Heinzel's reason and the buttons Approve and Deny
Class, server, the command word for word, Heinzel's reason, two buttons.

The class

It comes from the code, not from the model: Heinzel Pro takes the command apart (pipes, &&, sudo, sh -c) and takes the highest class of its parts. What the code cannot read counts as writing. What a class then does on rw- and on rwx is set by the tenant in the matrix (Settings, Policy); the right-hand column shows the default.

ClassExampleDefault on rw-
read-onlysystemctl status nginx, df -h, tail -n 50 /var/log/syslogruns at once
writingsed -i … /etc/hosts, mkdir, chmodwaits for a person
packageapt-get install, dnf update, pkg upgradewaits for a person
servicesystemctl restart, service … reloadwaits for a person
firewallufw allow, nft, pfctlwaits, with a rollback timer
identityuseradd, passwd, changes to sudoers or authorized_keyswaits for two people, on every level; never runs unattended
rebootreboot, shutdown -rwaits for a person
irreversiblerm -rf /var/lib/…, mkfs, DROP DATABASE, userdelwaits for two people
blockeddd if=/dev/zero of=/dev/sda, writing to /etc/heinzel.conf, everything on the block listnever runs

Approve or deny

Approve lets exactly this command run once on this server. Deny takes a reason along, which Heinzel reads: "Not now, the customer is running a load test until 6 pm" brings the proposal to carry on after six, or a way without a restart. A denial is final; Heinzel may not propose the same command again in other words.

Where the matrix asks for two people, the second approval comes from another person with the right to it, and their sign-in may be at most five minutes old. Who approved stands on the command and in the audit log.

A change that could lock Heinzel out

Before a change to an address, a route or the firewall, Heinzel sets a timer on the server that restores the old state after two minutes, in the same command as the change. Then it signs in afresh and stops the timer. If the new login fails, the server takes the change back by itself. The card says so.

The Approvals page

Waiting commands of all sessions you may decide on, in one place. The same change on many servers you approve here at once. Beside them stands, for a week, what nightly runs skipped because they were not allowed to do it alone, to be taken over into a session of your own.

The Approvals page: a session with its task, the note that three commands ran before, and the waiting command card with Approve and Deny
One session, one waiting command. The three reading commands before it unfold, so the decision is made in context.

So that you miss nothing without keeping the page open:

  • The navigation counts what your sessions need; the browser tab carries the number in its title.
  • A session's tab begins with "● Approval needed", "● Failed", "● Stopped" or "● Answer ready", and with "…" while Heinzel works.
  • "Notify in this browser" on the Sessions page: a notification, from another window too.
  • Mail or webhook, if the tenant has switched on the event "approval needed" under Settings, Alerts. An approval that waits too long can be escalated (Settings, Policy).

Plans

If a task needs three or more changing commands, Heinzel first presents a plan: the goal, every step with its exact command, what can go wrong and how to undo it. You approve it as a whole or deny it.

A plan in a session: three steps with their command and class, below them the buttons to approve and deny the plan
The plan from the php2shell example: three steps, one approval.

An approved step lets exactly that command run once, in the plan's order, the next only when the one before succeeded. A command that differs by one character asks on its own. So does one that needs two people, names a secret or changes a file. A stop or your next message ends the plan.

File changes

When Heinzel changes a configuration file, the card shows the difference as a diff. A file change always asks on its own; no plan and no standing approval replaces that. Before writing, Heinzel Pro checks that the file is still the one the diff was shown against, and refuses otherwise. The old file stays beside it as <file>.heinzel-<time>.bak.

Files that Ansible, Terraform or another tool writes you enter under Managed files, such as /etc/nginx/**; a change there is refused with the note where it belongs instead. A file whose first lines say "Ansible managed" is refused even without an entry.

Secrets

A password or token a command needs is stored by administrators under Secrets. Heinzel uses it as $HEINZEL_SECRET_NAME; the value never goes to the model, reaches the command on its standard input and is redacted in the output. A command that names a secret waits for a person on every level. Read it before you approve: a command can pass a value on in another form.

# What Heinzel's proposal looks like when MONITORING_DB is stored
psql -c "CREATE ROLE monitoring LOGIN PASSWORD '$HEINZEL_SECRET_MONITORING_DB'"

Several sessions side by side

Start the next while the first one reads. The list under Sessions and the strip beside an open session say what each is doing.

StateMeaning
needs youwaits for an approval, has failed or was interrupted
answeredHeinzel is done, and you have not read it yet
workingHeinzel is at it
readynothing open
The list of sessions with search, the filters All, Waiting for you, Running, Mine and Closed, and one session with server, person, time, model and the state ready
The list, sorted by what needs you.

Long sessions keep going: the page shows how much of the model's room a session has used, and past the budget the provider sums up the earlier messages for the model while the session keeps every message in full.

When the task is done

Heinzel writes the summary at the top of the session: changes, checks, open points, the way back. It is the model's own account and not checked against what ran; the evidence is the record of the commands. Open points go onto the server's to-do, and a note goes into the server's journal and, where the server allows it, as a handover note into its system journal (journalctl -t heinzel).

A session whose task is done closes by itself after three quiet hours, otherwise after the tenant's hours without activity. Work goes on in a new session that reads the old one's summary. Under More on the session page:

  • Change record: a Markdown file with who asked, who decided, the outcome of every command and its place in the audit chain. For the ticket or the auditor.
  • Incident draft: the same facts as a timeline, the sections for people (impact, cause, what to change) marked TODO. No model writes it.
  • Roll back: puts the undo notes of every command, newest first, into the task of a new session. The button itself undoes nothing; every step is proposed and approved like any other command.
  • Report and messages: where this session's report goes, see below.
  • Reload rules, as soon as a newer rule set applies; a session otherwise keeps the one it started with.

Sharing

A session belongs to whoever started it. Under People in the session the owner opens it to everybody in the tenant, to groups and people, each to read or to write, or to people without an account through a link that ends after 1, 7 or 30 days. Links are allowed by an administrator under Settings, Policy; they are off at first. Writing means sending messages: a colleague carries on where you stopped, every message carries its sender, and a turn runs with the lesser rights of both. With Take over an administrator or somebody named in the session becomes its owner.

What new sessions are for everybody (private, readable, writable) is set by the policy; every member sets a default of their own under Sessions, Sharing, such as "private, and the group on-call may write".

Reports and messages

A session sends its report to the destinations on its page: mail addresses and the team's channel (the tenant's webhook: Slack, Teams, Mattermost). It goes out by itself when Heinzel has finished a task and written the summary, and when the session fails. Under Account, "Reports of my sessions" sets the destinations every session of yours takes along.

Or you ask for it in the task:

Input: Check on all web servers that the certificate is valid for at least 20 more days, and then send me a mail to ops@example.com.

Heinzel writes only to destinations a person named: an address from a message of the session, the report destinations, the people of the session, the team's channel. An address it read on a host or in a file is refused. At most ten messages per session and hour, each freed of secrets, each in the audit log.

Attachments

The message field takes files through the paperclip, by dropping or pasting: text files up to 300 kB, and with an Anthropic model also images and PDFs up to 3.5 MB, five per message. A graph from the monitoring, a configuration file from the laptop, the screenshot of an error. A text that reads like instructions to Heinzel is kept from the model until somebody with write access lets it through.