docs: Updated docs

This commit is contained in:
mrhid6 committed 2026-07-28 16:53:42 +01:00
1 parent 18755d8697
commit 51efb9e498
33 files changed
+368 -567

No files matched your search

+7 -7
View File
@@ -8,13 +8,13 @@ Every mutating API path writes an audit event. The log is at **Audit**.
## What an event carries
| Field | Meaning |
| --- | --- |
| Field | Meaning |
| ------ | -------------------------------------------------------- |
| Action | A dotted name, e.g. `server.created`, `settings.updated` |
| Actor | Who did it |
| Target | The object acted on |
| Detail | A short human-readable note |
| Time | When |
| Actor | Who did it |
| Target | The object acted on |
| Detail | A short human-readable note |
| Time | When |
## What is recorded
@@ -36,7 +36,7 @@ lookup.
## Retention
Audit events are not swept by the workflow log retention setting — that setting
Audit events are not swept by the workflow log retention setting that setting
governs run logs only. Audit history stays until the instance does.
:::warning It is a log, not a control
+11 -11
View File
@@ -7,7 +7,7 @@ sidebar_label: Browser console
An SSH, RDP or VNC session in a browser tab, with no client software and no
inbound port on the target beyond the one the protocol already uses.
Protocol handling is Apache Guacamole's — the control plane proxies a WebSocket
Protocol handling is Apache Guacamole's the control plane proxies a WebSocket
to a **guacd** daemon and manages credentials around it.
## Requirements
@@ -27,8 +27,8 @@ From a server's page, choose **Console**. Then:
1. The UI calls `POST /api/console/connect`, which mints a **one-time** session
token.
2. The browser opens a WebSocket to `GET /api/console/tunnel` with that token.
3. The server marks the token consumed — atomically, so a second use cannot
race — and proxies the connection to guacd.
3. The server marks the token consumed atomically, so a second use cannot
race and proxies the connection to guacd.
## Credentials
@@ -52,19 +52,19 @@ is worth one connection at most, and only until it is used.
## Session behaviour
Closing the tab ends the session. There is no reconnect and no session
persistence — reopening mints a new token and a new connection.
persistence reopening mints a new token and a new connection.
## Auditing
Opening a console is an audited action, with actor, server and time. What
happens *inside* the session is not recorded: there is no session capture or
happens _inside_ the session is not recorded: there is no session capture or
keystroke log. If you need that, it has to come from the target machine.
## When it does not work
| Symptom | Cause |
| --- | --- |
| Connects then closes immediately | guacd unreachable — check `GUACD_ADDR` and that the container is up |
| SSH refuses the key | The stored key has no private half, or is not in the target's `authorized_keys` |
| RDP fails on a fresh credential | Credentials are consumed on open; a retry needs them entered again |
| Hangs at connecting | The control plane cannot reach the target on the protocol port |
| Symptom | Cause |
| -------------------------------- | ------------------------------------------------------------------------------- |
| Connects then closes immediately | guacd unreachable check `GUACD_ADDR` and that the container is up |
| SSH refuses the key | The stored key has no private half, or is not in the target's `authorized_keys` |
| RDP fails on a fresh credential | Credentials are consumed on open; a retry needs them entered again |
| Hangs at connecting | The control plane cannot reach the target on the protocol port |
+14 -14
View File
@@ -9,12 +9,12 @@ from, and a notification path when they stop being satisfied.
## Types
| Type | Checks | Options |
| --- | --- | --- |
| `http` | An HTTP(S) URL | method, expected status, keyword that must appear in the body, allow insecure TLS |
| `tcp` | A host and port accept a connection | — |
| `icmp` | A host answers ping | — |
| `tls` | A certificate is valid and not expiring | warn N days before expiry |
| Type | Checks | Options |
| ------ | --------------------------------------- | --------------------------------------------------------------------------------- |
| `http` | An HTTP(S) URL | method, expected status, keyword that must appear in the body, allow insecure TLS |
| `tcp` | A host and port accept a connection | |
| `icmp` | A host answers ping | |
| `tls` | A certificate is valid and not expiring | warn N days before expiry |
An `http` monitor with a keyword is usually the one you want for an application:
a 200 that returns an error page still fails the keyword.
@@ -23,12 +23,12 @@ a 200 that returns an error page still fails the keyword.
Every monitor has a **runner**:
| Runner | Meaning |
| --- | --- |
| `server` | The control plane's scheduler performs the check |
| Runner | Meaning |
| ----------- | -------------------------------------------------------------- |
| `server` | The control plane's scheduler performs the check |
| a server ID | That server's agent performs it locally and reports the result |
Use `server` for anything reachable from the control plane — public endpoints,
Use `server` for anything reachable from the control plane public endpoints,
your own front door. Use an agent for anything only reachable from inside the
target network: a database on a private subnet, a service bound to localhost, a
device on a management VLAN.
@@ -41,8 +41,8 @@ different questions, and outages usually live in the gap.
## Interval, retries and state
- **Interval** — how often to check.
- **Retries** — how many consecutive failures are tolerated before the state
- **Interval** how often to check.
- **Retries** how many consecutive failures are tolerated before the state
flips.
A monitor sits in `pending` until its first result. Failures accumulate; once
@@ -65,7 +65,7 @@ hours does not send a message per interval.
The monitor detail page shows:
- **Uptime**, from hourly rollup records — checks performed, how many were up,
- **Uptime**, from hourly rollup records checks performed, how many were up,
and mean latency per hour. Rollups are what make the graph cheap to draw over
long windows.
- **Incidents**, each with a start, a resolution and the cause recorded at the
@@ -74,5 +74,5 @@ The monitor detail page shows:
## Disabling versus deleting
Disabling stops the checks and keeps the history. Deleting removes the monitor.
Prefer disabling for anything seasonal — the uptime record is usually the part
Prefer disabling for anything seasonal the uptime record is usually the part
you wanted.
+17 -17
View File
@@ -15,9 +15,9 @@ Manage them at **Settings → Notifications**.
Posts JSON to a URL you choose.
| Setting | |
| --- | --- |
| `url` | Required |
| Setting | |
| ------- | -------- |
| `url` | Required |
```json
{
@@ -35,31 +35,31 @@ after 10 seconds.
### Discord
| Setting | |
| --- | --- |
| `url` | Discord webhook URL |
| Setting | |
| ------- | ------------------- |
| `url` | Discord webhook URL |
Posts the alert as message content.
### Slack
| Setting | |
| --- | --- |
| `url` | Slack incoming webhook URL |
| Setting | |
| ------- | -------------------------- |
| `url` | Slack incoming webhook URL |
### Telegram
| Setting | |
| --- | --- |
| `token` | Bot token |
| Setting | |
| --------- | ----------- |
| `token` | Bot token |
| `chat_id` | Target chat |
### SMTP
| Setting | |
| --- | --- |
| `host`, `port` | Required |
| `from`, `to` | Required |
| Setting | |
| ---------------------- | ---------------------------------------------------- |
| `host`, `port` | Required |
| `from`, `to` | Required |
| `username`, `password` | Optional; auth is skipped when the username is empty |
Port `465` uses implicit TLS; anything else uses STARTTLS.
@@ -83,7 +83,7 @@ something that needs to branch on status.
## Testing
Every channel has a **Test** button. It dispatches a fabricated down event for a
monitor called "Test monitor", through the real delivery path — so a test that
monitor called "Test monitor", through the real delivery path so a test that
arrives proves the credentials, the network path and the destination, not just
the configuration form.
+3 -3
View File
@@ -10,7 +10,7 @@ External Secrets Operator.
## Groups and values
A **group** is a named bundle — `prod-db`, `registry`, `acme-api`. Inside it are
A **group** is a named bundle `prod-db`, `registry`, `acme-api`. Inside it are
key/value pairs.
Group by consumer, not by type. A group is the unit a workflow step references
@@ -22,7 +22,7 @@ a group holding everything is over-sharing to every step that needs any of it.
**Secrets → New group**, then add keys.
Values are write-then-hidden. The list shows keys, never values. **Reveal** is a
separate action on a separate endpoint, and it writes an audit event — so
separate action on a separate endpoint, and it writes an audit event so
looking at a secret is a recorded act.
Deleting a single key and deleting the whole group are separate operations.
@@ -42,7 +42,7 @@ library entry.
:::warning A step can print its own secrets
Injection puts values in the environment. If your script echoes them, or runs
with `set -x`, they land in the run log — which is stored on disk and readable
with `set -x`, they land in the run log which is stored on disk and readable
in the UI. Vantage does not scrub step output.
:::
+15 -15
View File
@@ -5,8 +5,8 @@ sidebar_label: Servers
---
The fleet. Every managed machine runs an agent that connects outbound to the
control plane, and everything else in Vantage — keys, workflows, monitors,
consoles — targets these records.
control plane, and everything else in Vantage keys, workflows, monitors,
consoles targets these records.
## Enrolling a server
@@ -16,14 +16,14 @@ a one-liner to run as root on the target machine.
## Lifecycle
| Status | Meaning |
| --- | --- |
| Status | Meaning |
| --------- | --------------------------------------------------- |
| `pending` | Enrolment created; the agent has not registered yet |
| `active` | The agent registered and is syncing |
| `offline` | Last-seen passed the threshold |
| `active` | The agent registered and is syncing |
| `offline` | Last-seen passed the threshold |
The offline sweep runs every two minutes, so a machine that has just gone away
takes a little while to be marked as such. That delay is intentional — a single
takes a little while to be marked as such. That delay is intentional a single
missed poll is not an outage.
## The server detail page
@@ -37,9 +37,9 @@ Which SSH keys are assigned to this machine, and their state. See
Agents report:
| Data | Refreshed |
| --- | --- |
| CPU, memory, swap, load | every 30 seconds |
| Data | Refreshed |
| ---------------------------------------- | ---------------- |
| CPU, memory, swap, load | every 30 seconds |
| Partitions, kernel, full static snapshot | every 15 minutes |
The two carry separate timestamps, so a stale static snapshot beside fresh
@@ -50,15 +50,15 @@ metrics is normal rather than a fault.
Agents check for pending package updates hourly and report the count. From the
server page you can:
- **Apply updates** — pushes `ApplyUpdatesCmd` down the command stream. The
- **Apply updates** pushes `ApplyUpdatesCmd` down the command stream. The
agent runs the platform's package manager and reports back.
- **Update agent** — pushes `UpdateAgentCmd` with a target version; the agent
- **Update agent** pushes `UpdateAgentCmd` with a target version; the agent
downloads the release, verifies it and replaces itself. See
[Agent updates](../operations/agent-updates.md).
:::warning Applying updates is not scheduled or staged
It runs now, on that machine. If you need ordering, health gates or a canary,
build it as a [workflow](./workflows.md) instead — that is what workflows exist
build it as a [workflow](./workflows.md) instead that is what workflows exist
for.
:::
@@ -69,7 +69,7 @@ Opens a browser SSH, RDP or VNC session. See [Browser console](./browser-console
## Windows servers
Windows agents register, heartbeat, run workflow steps and report inventory.
They do not manage `authorized_keys` — the poll loop stops after the heartbeat
They do not manage `authorized_keys` the poll loop stops after the heartbeat
on any non-Linux host. This is a deliberate scope decision, not a gap being
worked on.
@@ -94,5 +94,5 @@ no longer running to remove them. Revoke and let the agent apply the change
Each server has its own token. The control plane stores only its SHA-256; the
plaintext exists in the agent's `0600` config and nowhere else. There is no way
to read a token back out of the control plane — if one is lost, re-enrol the
to read a token back out of the control plane if one is lost, re-enrol the
machine.
+17 -17
View File
@@ -11,7 +11,7 @@ Settings require the `owner` or `admin` role.
:::info Where instance settings went
Members and single sign-on used to live at `/settings/instance`. They are now
the Access group at the top of this page — splitting "who can sign in" from "how
the Access group at the top of this page splitting "who can sign in" from "how
this instance behaves" produced two half-pages and a nav entry nobody could
distinguish from Settings. The old path still redirects.
:::
@@ -22,10 +22,10 @@ distinguish from Settings. The old path still redirects.
Add, remove and re-role the people who can sign in.
| Role | Can |
| --- | --- |
| `owner` | Everything |
| `admin` | Everything except owner-only settings |
| Role | Can |
| -------- | ---------------------------------------------------- |
| `owner` | Everything |
| `admin` | Everything except owner-only settings |
| `member` | Servers, keys, workflows, monitors, secrets, console |
Local members authenticate with email and a bcrypt-hashed password.
@@ -37,7 +37,7 @@ read-only rows with a link to the portal.
:::warning HQ-managed users cannot be edited locally
Changing the role of, or deleting, an `hq`-sourced user is refused with `409`.
HQ owns their role, their password and whether they exist at all — a local
HQ owns their role, their password and whether they exist at all a local
change would be overwritten by the next sync and would leave two writers for one
password hash. Manage them from [People and roles](../hq/people-and-roles.md).
:::
@@ -46,10 +46,10 @@ password hash. Manage them from [People and roles](../hq/people-and-roles.md).
Configured per organisation:
| Field | |
| --- | --- |
| Issuer | Your provider's issuer URL |
| Client ID | |
| Field | |
| ------------- | ---------------------------- |
| Issuer | Your provider's issuer URL |
| Client ID | |
| Client secret | Stored AES-256-GCM encrypted |
Sign-in then goes `/auth/oidc/start` → your provider → `/auth/oidc/callback`.
@@ -60,7 +60,7 @@ misconfigured or unreachable, a local account is the way back in.
## Monitoring
- **Alert defaults** for monitors.
- **Notification channels** — their own page. See
- **Notification channels** their own page. See
[Notification channels](./notification-channels.md).
## Integrations
@@ -69,11 +69,11 @@ misconfigured or unreachable, a local account is the way back in.
How long run logs are kept.
| Value | Meaning |
| --- | --- |
| unset | 30 days |
| Value | Meaning |
| -------- | -------------- |
| unset | 30 days |
| a number | that many days |
| `0` | forever |
| `0` | forever |
### ESO read token
@@ -87,7 +87,7 @@ once, stored as a SHA-256 hash, rotatable. See
features and expiry.
On **self-hosted**, paste a licence here. This works even while the current
licence is expired — that is the way out of degraded mode.
licence is expired that is the way out of degraded mode.
On **cloud**, there is no paste form. The endpoint answers `409 cloud_managed`,
because a cloud licence is written by HQ directly. The page links to the portal
@@ -108,6 +108,6 @@ organisation from the slug and rejects a session belonging to a different one.
The label it looks for comes from `APP_ROOT_LABEL`.
:::warning A wrong `APP_ROOT_LABEL` disables the guard
It does not fail loudly — it simply stops matching, and the host check stops
It does not fail loudly it simply stops matching, and the host check stops
protecting anything. If you serve the UI on a custom domain, set it to match.
:::
+4 -4
View File
@@ -28,7 +28,7 @@ library. You may optionally upload the private half too, in which case it is
stored **AES-256-GCM encrypted** under `KEY_ENCRYPTION_KEY`.
The JSON representation of a key exposes only `has_private_key` and
`has_passphrase` — never the material. Retrieving a stored private key is its
`has_passphrase` never the material. Retrieving a stored private key is its
own endpoint and its own audit event.
:::tip Why store a private key at all
@@ -38,7 +38,7 @@ you are not using the console, do not upload private halves.
## Assigning
Assign a key to one or more servers. Within one poll interval — 30 seconds — the
Assign a key to one or more servers. Within one poll interval 30 seconds the
agent picks up the change.
## Revoking
@@ -58,7 +58,7 @@ until it ends. Kill sessions on the machine if that matters.
Each poll:
1. `SyncKeys` returns the desired set of public keys for that server.
1. The control plane returns the desired set of public keys for that server.
2. The agent reads `/root/.ssh/authorized_keys` and computes fingerprints.
3. **If the sets match, it writes nothing.** No disk churn on unchanged state,
which is most polls.
@@ -77,5 +77,5 @@ it in Vantage.
## Recovering from a lockout
If you have removed every key from a machine and cannot get in, you still have
the console — provided a private key is stored — or out-of-band access from your
the console provided a private key is stored or out-of-band access from your
hosting provider. Vantage has no backdoor and does not keep a break-glass key.
+21 -22
View File
@@ -13,14 +13,14 @@ back live.
A step has:
| Field | Meaning |
| --- | --- |
| `name`, `description` | Library identity |
| `interpreter` | `bash` or `powershell` |
| `script` | The body |
| `declared_inputs` | Named parameters with defaults and descriptions |
| `declared_outputs` | Names this step promises to export |
| `secret_refs` | Vault entries injected as environment variables |
| Field | Meaning |
| --------------------- | ----------------------------------------------- |
| `name`, `description` | Library identity |
| `interpreter` | `bash` or `powershell` |
| `script` | The body |
| `declared_inputs` | Named parameters with defaults and descriptions |
| `declared_outputs` | Names this step promises to export |
| `secret_refs` | Vault entries injected as environment variables |
### Passing values between steps
@@ -59,7 +59,7 @@ new install is not staring at an empty page.
:::warning Default steps are read-only
Editing or deleting one is refused with `409`. Seeding rewrites them on every
boot, so an edit would silently revert and a delete would come back at the next
restart — refusing is the honest answer.
restart refusing is the honest answer.
To customise one, use the per-step **script override** in the workflow designer,
which belongs to that workflow and is not touched by seeding. To add to the
@@ -67,7 +67,7 @@ shared library permanently, a file has to be committed to the repository and the
server image rebuilt.
:::
The UI mirrors this — the step modal opens read-only and Delete is hidden — but
The UI mirrors this the step modal opens read-only and Delete is hidden but
the API is the boundary; the UI is the courtesy.
## Building a workflow
@@ -80,11 +80,11 @@ the API is the boundary; the UI is the courtesy.
### Failure behaviour
| `on_failure` | Effect |
| --- | --- |
| `stop` | Abort this server's run. Other servers continue |
| `continue` | Record the failure, run the next step anyway |
| `retry` | Re-run the step up to `max_retries`, then treat it as a failure |
| `on_failure` | Effect |
| ------------ | --------------------------------------------------------------- |
| `stop` | Abort this server's run. Other servers continue |
| `continue` | Record the failure, run the next step anyway |
| `retry` | Re-run the step up to `max_retries`, then treat it as a failure |
### Per-step overrides
@@ -94,9 +94,8 @@ scoped to that workflow.
## Running
**Run** snapshots the resolved steps into the run record and dispatches
`RunStepCmd` to each target's agent over the command stream — no waiting for the
next poll.
**Run** snapshots the resolved steps into the run record and dispatches each step
to the target's agent over the command stream no waiting for the next poll.
:::info Runs freeze their steps
The snapshot is why editing a step tomorrow never rewrites what happened today.
@@ -119,11 +118,11 @@ nothing further is dispatched.
Run logs are swept on a schedule set by `workflow_log_retention_days` in
Settings:
| Value | Meaning |
| --- | --- |
| unset | 30 days |
| Value | Meaning |
| -------- | -------------- |
| unset | 30 days |
| a number | that many days |
| `0` | keep forever |
| `0` | keep forever |
## Import and export