docs: Self review of doc pages
This commit is contained in:
+17
-20
@@ -4,7 +4,8 @@ title: Audit log
|
||||
sidebar_label: Audit log
|
||||
---
|
||||
|
||||
Every mutating API path writes an audit event. The log is at **Audit**.
|
||||
Anything that changes something is recorded, whether it was done in the UI or by
|
||||
a script. The log is at **Audit Log**.
|
||||
|
||||
## What an event carries
|
||||
|
||||
@@ -23,21 +24,24 @@ keys and assignments, workflow and step changes, runs triggered, monitors and
|
||||
channels, secret groups and reveals, console sessions opened, settings and
|
||||
member changes, licence installs.
|
||||
|
||||
Reads are not recorded, with one deliberate exception: **revealing a secret**
|
||||
writes an event, because reading that particular thing is an act rather than a
|
||||
lookup.
|
||||
Simply looking at something is not recorded, with one exception: **revealing a
|
||||
secret** is.
|
||||
|
||||
## What is not recorded
|
||||
|
||||
- Sign-ins and sign-out.
|
||||
- Sign-ins and sign-outs.
|
||||
- Anything inside a console session.
|
||||
- Step output. That lives in the run log, kept under the workflow retention
|
||||
setting rather than with the audit log.
|
||||
|
||||
## Retention
|
||||
|
||||
Audit events are not swept by the workflow log retention setting that setting
|
||||
governs run logs only. Audit history stays until the instance does.
|
||||
How long audit events are kept comes from your licence: 30 days on Free, a year
|
||||
on Professional, and unlimited on Enterprise. See
|
||||
[Licensing and entitlements](../hq/licensing-and-entitlements.md).
|
||||
|
||||
This is separate from the workflow log retention setting, which covers run logs
|
||||
only.
|
||||
|
||||
:::warning It is a log, not a control
|
||||
The audit log tells you what happened. It does not restrict what can happen, and
|
||||
@@ -45,18 +49,11 @@ an admin can do anything an admin can do. Use roles for restriction and the log
|
||||
for accountability.
|
||||
:::
|
||||
|
||||
## Getting events out
|
||||
## Searching and exporting
|
||||
|
||||
`GET /api/audit` returns one page of events as JSON:
|
||||
The page searches by actor, detail and event type, and filters by category, such
|
||||
as `workflow`, `key` or `server`. The count shown is the number of matching
|
||||
events, not the number on screen.
|
||||
|
||||
```json
|
||||
{ "events": [ ... ], "total": 3214 }
|
||||
```
|
||||
|
||||
It accepts `limit` (default 50, maximum 200), `skip`, `q` to search actor,
|
||||
details and event type, and `category` to match the part of an event type
|
||||
before the dot — `workflow`, `key`, `server`. `total` counts everything
|
||||
matching the filter, not the page, so a short page is not the end of the log.
|
||||
|
||||
There is no streaming or push export; if you need events in a SIEM, poll that
|
||||
endpoint, walking `skip` until you have `total`.
|
||||
The same events are available from the API if you want them in a log system of
|
||||
your own. See [Automating Vantage](../reference/rest-api.md).
|
||||
|
||||
@@ -4,70 +4,59 @@ title: Browser console
|
||||
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.
|
||||
An SSH, RDP or VNC session in a browser tab, with no client software to install
|
||||
and no new port to open on the target machine.
|
||||
|
||||
Protocol handling is Apache Guacamole's the control plane proxies a WebSocket
|
||||
to a **guacd** daemon and manages credentials around it.
|
||||
:::info Requires the console feature on your licence
|
||||
The console is a per-instance feature you enable on a paid plan. Without it, the
|
||||
Console button is unavailable. See
|
||||
[Licensing and entitlements](../hq/licensing-and-entitlements.md).
|
||||
:::
|
||||
|
||||
## Requirements
|
||||
## What you need
|
||||
|
||||
- `guacd` running and reachable from the server. The bundled Compose stack
|
||||
includes it; `GUACD_ADDR` defaults to `guacd:4822`.
|
||||
- `KEY_ENCRYPTION_KEY` set, since every credential involved is stored encrypted.
|
||||
- The target's **agent must be online**. Console traffic is relayed over the
|
||||
agent's existing outbound connection, so the control plane never needs a route
|
||||
to the server's address — but it does need the agent.
|
||||
- No inbound port on the target, beyond what the protocol already listens on
|
||||
locally. A service bound only to `127.0.0.1` works, because the agent dials
|
||||
loopback on the target itself.
|
||||
- The target server's **agent must be online**. Console traffic travels over the
|
||||
connection the agent already holds, so an offline agent means no session.
|
||||
- `KEY_ENCRYPTION_KEY` set on a self-hosted install, since every credential
|
||||
involved is stored encrypted.
|
||||
- The service you are connecting to listening on the machine itself. It does not
|
||||
have to be reachable from anywhere else, because the agent connects to it
|
||||
locally.
|
||||
|
||||
## Opening a session
|
||||
|
||||
From a server's page, choose **Console**. Then:
|
||||
|
||||
1. The UI calls `POST /api/console/connect`, which mints a **one-time** session
|
||||
token. If the target's agent is not connected, this fails immediately with
|
||||
`409 agent_offline` rather than hanging.
|
||||
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.
|
||||
From a server's page, choose **Console**, pick the protocol and connect. Vantage
|
||||
issues a one-time ticket for that session, and the connection is refused rather
|
||||
than left hanging if the agent is not online.
|
||||
|
||||
## Credentials
|
||||
|
||||
### SSH
|
||||
|
||||
Authenticates with a private key stored in the [key library](./ssh-keys.md). The
|
||||
key must have its private half uploaded; a public-only key cannot open a
|
||||
session.
|
||||
Uses a private key from your [key library](./ssh-keys.md). The key must have had
|
||||
its private half uploaded; a public key alone cannot open a session.
|
||||
|
||||
### RDP and VNC
|
||||
|
||||
You supply credentials when connecting. They are encrypted, **single-use**, and
|
||||
consumed when the tunnel opens. They are not retained for the next session.
|
||||
You type the credentials when you connect. They are encrypted, used once and
|
||||
discarded, so the next session asks again.
|
||||
|
||||
:::info Why single-use
|
||||
A stored console credential is a standing grant to that machine for anyone who
|
||||
can reach the endpoint. Consuming it at tunnel-open means a leaked session token
|
||||
is worth one connection at most, and only until it is used.
|
||||
:::
|
||||
## During and after a session
|
||||
|
||||
## Session behaviour
|
||||
Closing the tab ends the session. There is no reconnect: opening it again starts
|
||||
a fresh session.
|
||||
|
||||
Closing the tab ends the session. There is no reconnect and no session
|
||||
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
|
||||
keystroke log. If you need that, it has to come from the target machine.
|
||||
Opening a console is recorded in the [audit log](./audit-log.md), with who did
|
||||
it, which server and when. What happens inside the session is not recorded.
|
||||
There is no session replay or keystroke capture, so if you need that, it has to
|
||||
come from the target machine itself.
|
||||
|
||||
## 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, then disconnects | The agent never claimed the relay, nothing is listening on the protocol port on the target's own loopback address, or guacd never dialled in time. Check the audit log for `console.proxy_failed` — its reason (`agent_timeout`, `dial_refused`, `guacd_timeout`, `rejected`) names which |
|
||||
| Symptom | What to check |
|
||||
| -------------------------------- | ------------------------------------------------------------------------------------------ |
|
||||
| Connects, then closes at once | The console daemon is unreachable. On a self-hosted install, check that `guacd` is running |
|
||||
| SSH refuses the key | The stored key has no private half, or is not assigned to that server |
|
||||
| RDP fails when you retry | Credentials are used once. Enter them again |
|
||||
| Hangs, then disconnects | The agent could not reach the service on the machine, or the session timed out setting up. The audit log records the reason |
|
||||
| Works locally, fails in production | Your reverse proxy is not forwarding WebSocket connections |
|
||||
|
||||
+15
-16
@@ -28,22 +28,22 @@ Every monitor has a **runner**:
|
||||
| `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,
|
||||
your own front door. Use an agent for anything only reachable from inside the
|
||||
Use `server` for anything Vantage itself can reach, such as your public website
|
||||
or API. 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.
|
||||
|
||||
:::tip Agent-run monitors measure what your users can't
|
||||
A check run from the control plane tells you the service is reachable from
|
||||
there. A check run on the machine tells you the process is alive. Those are
|
||||
different questions, and outages usually live in the gap.
|
||||
:::tip The two answer different questions
|
||||
A check from Vantage tells you the service is reachable over the network. A
|
||||
check on the machine tells you the process is running. Watch both where it
|
||||
matters.
|
||||
:::
|
||||
|
||||
## Interval, retries and state
|
||||
|
||||
- **Interval** how often to check.
|
||||
- **Retries** how many consecutive failures are tolerated before the state
|
||||
flips.
|
||||
- **Interval** is how often to check.
|
||||
- **Retries** is how many failures in a row are tolerated before the state
|
||||
changes.
|
||||
|
||||
A monitor sits in `pending` until its first result. Failures accumulate; once
|
||||
they exceed `retries`, the monitor goes `down`, an **incident** opens and the
|
||||
@@ -58,21 +58,20 @@ Attach one or more [notification channels](./notification-channels.md) to a
|
||||
monitor. Channels are shared, so one Slack destination can serve every monitor
|
||||
you have.
|
||||
|
||||
Notification state is tracked per monitor, so a service that is down for six
|
||||
hours does not send a message per interval.
|
||||
You get a message when a monitor goes down and another when it recovers, not one
|
||||
per check while it stays down.
|
||||
|
||||
## Uptime and incidents
|
||||
|
||||
The monitor detail page shows:
|
||||
|
||||
- **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.
|
||||
- **Uptime**, summarised per hour: how many checks ran, how many passed and the
|
||||
average response time.
|
||||
- **Incidents**, each with a start, a resolution and the cause recorded at the
|
||||
moment it opened.
|
||||
|
||||
## 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
|
||||
you wanted.
|
||||
Disable anything seasonal rather than deleting it, since the uptime record is
|
||||
usually the part worth keeping.
|
||||
|
||||
@@ -4,8 +4,8 @@ title: Notification channels
|
||||
sidebar_label: Notification channels
|
||||
---
|
||||
|
||||
A channel is a destination for alerts. [Monitors](./monitors.md) reference
|
||||
channels by ID, so one destination serves as many monitors as you like.
|
||||
A channel is a destination for alerts. One channel serves as many
|
||||
[monitors](./monitors.md) as you like.
|
||||
|
||||
Manage them at **Settings → Notifications**.
|
||||
|
||||
@@ -64,9 +64,7 @@ Posts the alert as message content.
|
||||
|
||||
Port `465` uses implicit TLS; anything else uses STARTTLS.
|
||||
|
||||
Alert emails are rendered by the same email system that sends licence and
|
||||
account mail, so a monitor alert and an account email look like the same
|
||||
product.
|
||||
Alert emails look like the rest of the mail Vantage sends you.
|
||||
|
||||
## The message
|
||||
|
||||
@@ -83,9 +81,9 @@ 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
|
||||
arrives proves the credentials, the network path and the destination, not just
|
||||
the configuration form.
|
||||
monitor called "Test monitor" and sends it the same way a real alert goes out, so
|
||||
a test that arrives proves the credentials, the network path and the destination
|
||||
as well as the form.
|
||||
|
||||
:::tip Test after every change
|
||||
Channel settings are only exercised when something breaks, which is the worst
|
||||
|
||||
+22
-23
@@ -10,54 +10,53 @@ External Secrets Operator.
|
||||
|
||||
## Groups and values
|
||||
|
||||
A **group** is a named bundle `prod-db`, `registry`, `acme-api`. Inside it are
|
||||
key/value pairs.
|
||||
A **group** is a named bundle, such as `prod-db`, `registry` or `acme-api`.
|
||||
Inside it are key/value pairs.
|
||||
|
||||
Group by consumer, not by type. A group is the unit a workflow step references
|
||||
and the unit ESO reads, so a group that matches one consumer is one reference;
|
||||
a group holding everything is over-sharing to every step that needs any of it.
|
||||
Group by who uses them rather than by what they are. A workflow step references
|
||||
a whole group, so a group that matches one job stays tidy, while a group holding
|
||||
everything hands all of it to every step that needs any of it.
|
||||
|
||||
## Managing them
|
||||
|
||||
**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
|
||||
looking at a secret is a recorded act.
|
||||
Once saved, a value is hidden. The list shows key names only. **Reveal** is a
|
||||
separate action, and it is written to the audit log.
|
||||
|
||||
Deleting a single key and deleting the whole group are separate operations.
|
||||
|
||||
## Using secrets in workflows
|
||||
|
||||
Add the group name to a step's `secret_refs`. At execution the group's pairs are
|
||||
injected into the step's environment:
|
||||
Add the group to a step's secret references. When the step runs, the group's
|
||||
pairs are available to it as environment variables:
|
||||
|
||||
```bash
|
||||
# secret_refs: ["registry"]
|
||||
# with the "registry" group attached to this step
|
||||
echo "$REGISTRY_PASSWORD" | docker login registry.example.com -u "$REGISTRY_USER" --password-stdin
|
||||
```
|
||||
|
||||
A workflow can also override `secret_refs` per step, without changing the
|
||||
library entry.
|
||||
A workflow can change which groups a step uses without changing the step in the
|
||||
library.
|
||||
|
||||
:::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
|
||||
in the UI. Vantage does not scrub step output.
|
||||
Values arrive as environment variables. If your script prints them, or runs with
|
||||
`set -x`, they end up in the run log, which anyone who can see the run can read.
|
||||
Vantage does not filter step output.
|
||||
:::
|
||||
|
||||
## Kubernetes External Secrets Operator
|
||||
|
||||
`GET /api/secrets/:group/values` returns a group's pairs for ESO, authenticated
|
||||
with a **bearer token** rather than a session.
|
||||
Kubernetes can read a secret group directly, using a token rather than a
|
||||
sign-in.
|
||||
|
||||
1. Generate the token at **Settings → Integrations**. It is shown once; only its
|
||||
SHA-256 is stored.
|
||||
1. Generate the token at **Settings → Integrations**. It is shown once, and
|
||||
Vantage stores only a fingerprint of it.
|
||||
2. Put it in a Kubernetes secret.
|
||||
3. Point an ESO `SecretStore` at the endpoint with that bearer token.
|
||||
3. Point an External Secrets Operator `SecretStore` at your Vantage address with
|
||||
that token.
|
||||
|
||||
The token is rotatable: generating a new one replaces the stored hash and
|
||||
invalidates the old one immediately.
|
||||
Generating a new token replaces the old one immediately.
|
||||
|
||||
:::danger This token reads every group
|
||||
It is instance-wide, not scoped to one group. Treat it as a credential to the
|
||||
|
||||
+24
-34
@@ -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. Keys, workflows, monitors and consoles all point at these
|
||||
records.
|
||||
|
||||
## Enrolling a server
|
||||
|
||||
@@ -23,18 +23,17 @@ a one-liner to run as root on the target machine.
|
||||
| `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
|
||||
missed poll is not an outage.
|
||||
takes a little while to be marked as such.
|
||||
|
||||
## Tags
|
||||
|
||||
A tag is a `key:value` label you put on a server. Tags are how you say what a
|
||||
machine **is** `env:prod`, `role:web`, `team:core-infra` so that you can find
|
||||
it later, and so that a [workflow](./workflows.md) can target it without you
|
||||
machine is, such as `env:prod`, `role:web` or `team:core-infra`, so that you can
|
||||
find it later and so a [workflow](./workflows.md) can target it without you
|
||||
naming it by hand.
|
||||
|
||||
There is no tag library to manage first. A tag exists because a server carries
|
||||
it, and it stops existing when the last server carrying it drops it.
|
||||
There is no tag library to set up first. A tag exists as soon as a server
|
||||
carries it, and disappears when the last server carrying it drops it.
|
||||
|
||||
### The rules
|
||||
|
||||
@@ -45,25 +44,22 @@ it, and it stops existing when the last server carrying it drops it.
|
||||
| Value length | up to 64 characters |
|
||||
| Per server | up to 20 tags |
|
||||
|
||||
Neither half may be empty, and keys beginning `sys:` are reserved for tags
|
||||
Vantage may derive from inventory later, so a tag you write today can never
|
||||
collide with one invented for you tomorrow.
|
||||
Neither half may be empty, and keys beginning `sys:` are reserved for Vantage's
|
||||
own use.
|
||||
|
||||
Anything outside those rules is refused with a message naming the rule, rather
|
||||
than quietly saved in a shape you did not intend. Uppercase is not folded to
|
||||
lowercase for you `Env` is a mistake, not a synonym for `env`.
|
||||
Anything outside those rules is refused, with a message naming the rule.
|
||||
Uppercase is not corrected for you, so `Env` and `env` are different tags.
|
||||
|
||||
### Editing a server's tags
|
||||
|
||||
On the server detail page, **Edit** beside the tag chips. Saving replaces the
|
||||
whole set: what you see in the editor is exactly what the server will have.
|
||||
There is no per-tag merge, so if two people edit the same server at once, the
|
||||
last save wins outright rather than producing a blend of the two.
|
||||
On the server's page, click **Edit** beside the tags. Saving replaces the whole
|
||||
set, so what you see in the editor is exactly what the server ends up with. If
|
||||
two people edit the same server at once, the last save wins.
|
||||
|
||||
### Filtering the fleet
|
||||
|
||||
The **Servers** list has a picker per tag key in use. Choosing values from more
|
||||
than one key narrows the list a server must match **all** of them, not any.
|
||||
than one key narrows the list, because a server must match **all** of them.
|
||||
Untagged servers appear only when no filter is set.
|
||||
|
||||
:::tip A filtered fleet view is a link
|
||||
@@ -96,16 +92,13 @@ 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
|
||||
agent runs the platform's package manager and reports back.
|
||||
- **Update agent** pushes `UpdateAgentCmd` with a target version; the agent
|
||||
downloads the release, verifies it and replaces itself. See
|
||||
- **Apply updates** runs the machine's own package manager and reports back.
|
||||
- **Update agent** upgrades the Vantage agent on that machine. 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
|
||||
for.
|
||||
It runs immediately, on that machine. If you need ordering, health checks or a
|
||||
test machine first, build it as a [workflow](./workflows.md) instead.
|
||||
:::
|
||||
|
||||
### Console
|
||||
@@ -114,10 +107,8 @@ 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
|
||||
on any non-Linux host. This is a deliberate scope decision, not a gap being
|
||||
worked on.
|
||||
Windows agents register, run workflow steps and report inventory. They do not
|
||||
manage `authorized_keys`.
|
||||
|
||||
## Removing a server
|
||||
|
||||
@@ -138,7 +129,6 @@ no longer running to remove them. Revoke and let the agent apply the change
|
||||
|
||||
## Agent tokens
|
||||
|
||||
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
|
||||
machine.
|
||||
Each server has its own token, which exists in full only in the agent's config
|
||||
file on that machine. Vantage stores a fingerprint of it and cannot show it to
|
||||
you again. If a token is lost, enrol the machine again.
|
||||
|
||||
+65
-91
@@ -4,31 +4,14 @@ title: Settings
|
||||
sidebar_label: Settings
|
||||
---
|
||||
|
||||
One page, three groups: **Access**, **Monitoring** and **Integrations**. Plus
|
||||
the licence, which has its own page.
|
||||
One page, three groups: **Access**, **Monitoring** and **Integrations**. Your
|
||||
licence has its own page.
|
||||
|
||||
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
|
||||
this instance behaves" produced two half-pages and a nav entry nobody could
|
||||
distinguish from Settings. The old path still redirects.
|
||||
:::
|
||||
|
||||
:::danger Upgrading breaks existing single sign-on until you re-register the callback URL
|
||||
Callback URLs are now per provider instead of one shared URL for the whole
|
||||
instance. If you already had single sign-on configured, it was carried
|
||||
forward automatically, but its callback URL changed and **sign-in through it
|
||||
will fail until you copy the new callback URL from its settings card and
|
||||
register it with your identity provider**. The migrated provider's card shows
|
||||
a dismissable warning as a reminder. Password sign-in is not affected by this
|
||||
change, so an administrator can always sign in locally to make the update.
|
||||
:::
|
||||
Settings need the `owner` or `admin` role.
|
||||
|
||||
## Access
|
||||
|
||||
### Members
|
||||
### People
|
||||
|
||||
Add, remove and re-role the people who can sign in.
|
||||
|
||||
@@ -38,112 +21,103 @@ Add, remove and re-role the people who can sign in.
|
||||
| `admin` | Everything except owner-only settings |
|
||||
| `member` | Servers, keys, workflows, monitors, secrets, console |
|
||||
|
||||
Local members authenticate with email and a bcrypt-hashed password.
|
||||
Local members sign in with an email address and a password.
|
||||
|
||||
#### Members managed by Vantage HQ
|
||||
#### People managed by Vantage HQ
|
||||
|
||||
On a cloud instance, people granted access from the HQ portal appear here as
|
||||
read-only rows with a link to the portal.
|
||||
On a cloud instance, anyone granted access from the Vantage HQ portal appears
|
||||
here as a read-only row with a link back 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
|
||||
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).
|
||||
:::warning You cannot edit those people here
|
||||
Their role, password and access are owned by Vantage HQ, so changing or removing
|
||||
them has to be done there. See
|
||||
[People and roles](../hq/people-and-roles.md).
|
||||
:::
|
||||
|
||||
### Single sign-on
|
||||
|
||||
Add as many identity providers as you need: one instance can have several at
|
||||
once, each with its own name, its own button on the login page and its own
|
||||
callback URL.
|
||||
:::info Requires the single sign-on feature on your licence
|
||||
It is a per-instance feature you enable on a paid plan.
|
||||
:::
|
||||
|
||||
Pick a provider from the list of presets:
|
||||
Add as many identity providers as you need. Each has its own name, its own
|
||||
button on the login page and its own callback URL.
|
||||
|
||||
| Preset | You provide |
|
||||
| ---------------------- | ------------------------------------------- |
|
||||
| Microsoft Entra ID | Directory (tenant) ID |
|
||||
| Google Workspace | nothing further, the issuer is fixed |
|
||||
| Okta | Your Okta org domain |
|
||||
| GitHub | Client ID and client secret only |
|
||||
| Other (OpenID Connect) | The issuer URL of your identity provider |
|
||||
If you configured single sign-on on an older version, see
|
||||
[Upgrading](../operations/upgrading.md#single-sign-on-after-an-upgrade).
|
||||
|
||||
Every provider also needs a **Client ID** and **Client secret**; the secret is
|
||||
stored AES-256-GCM encrypted and never shown again after you save it.
|
||||
Start from a preset:
|
||||
|
||||
:::info GitHub requires a verified primary email
|
||||
Vantage signs a person in by their email address. GitHub is asked for the
|
||||
account's addresses and only accepts one that is **both** the account's
|
||||
primary address **and** marked verified: an address GitHub has not confirmed
|
||||
is not proof anyone controls it.
|
||||
| Preset | You provide |
|
||||
| ---------------------- | ---------------------------------------- |
|
||||
| Microsoft Entra ID | Directory (tenant) ID |
|
||||
| Google Workspace | Nothing further |
|
||||
| Okta | Your Okta org domain |
|
||||
| GitHub | Client ID and client secret only |
|
||||
| Other (OpenID Connect) | The issuer URL of your provider |
|
||||
|
||||
Every provider also needs a **Client ID** and **Client secret**. The secret is
|
||||
stored encrypted and is never shown again after you save it.
|
||||
|
||||
:::info GitHub needs a verified primary email
|
||||
Vantage identifies people by email address, and it only accepts a GitHub address
|
||||
that is both the account's primary address and confirmed by GitHub.
|
||||
:::
|
||||
|
||||
#### Callback URL
|
||||
|
||||
Each provider gets its own callback URL, shown on its settings card with a
|
||||
copy button. This is the address you register with the identity provider when
|
||||
you set up the application on their side: each provider is registered
|
||||
separately, even if you have several with the same identity provider.
|
||||
Each provider's card shows its callback URL with a copy button. That is the
|
||||
address you register with the identity provider when you set up the application
|
||||
on their side. Register each provider separately, even where several use the
|
||||
same identity provider.
|
||||
|
||||
#### Turning off password sign-in
|
||||
|
||||
You can disable local (email and password) sign-in once at least one provider
|
||||
is enabled. Vantage refuses to save a change that would leave nobody able to
|
||||
sign in, whether that change comes from the local login toggle or from
|
||||
disabling the last enabled provider. Keep at least one option open until every
|
||||
person who needs access can reach the new one.
|
||||
Once at least one provider is enabled you can turn off email and password
|
||||
sign-in. Vantage refuses any change that would leave nobody able to sign in,
|
||||
whether that is switching off passwords or disabling your last provider. Keep
|
||||
one route open until everyone who needs access can use the new one.
|
||||
|
||||
## Monitoring
|
||||
|
||||
- **Alert defaults** for monitors.
|
||||
- **Notification channels** their own page. See
|
||||
[Notification channels](./notification-channels.md).
|
||||
|
||||
## Integrations
|
||||
|
||||
### Workflow log retention
|
||||
|
||||
How long run logs are kept.
|
||||
- **Offline threshold**, how long a server may go unheard from before it is
|
||||
marked offline. The default is 5 minutes.
|
||||
- **Offline alerts**, the [notification channels](./notification-channels.md) to
|
||||
tell when that happens.
|
||||
- **Notification channels** have [their own page](./notification-channels.md).
|
||||
- **Workflow log retention**, how long run logs are kept.
|
||||
|
||||
| Value | Meaning |
|
||||
| -------- | -------------- |
|
||||
| unset | 30 days |
|
||||
| a number | that many days |
|
||||
| `0` | forever |
|
||||
| `0` | keep forever |
|
||||
|
||||
### ESO read token
|
||||
## Integrations
|
||||
|
||||
The bearer token External Secrets Operator uses to read secret groups. Shown
|
||||
once, stored as a SHA-256 hash, rotatable. See
|
||||
### External Secrets Operator token
|
||||
|
||||
The token Kubernetes uses to read your secret groups. It is shown once, stored
|
||||
only as a fingerprint, and can be replaced at any time. See
|
||||
[Secrets](./secrets.md#kubernetes-external-secrets-operator).
|
||||
|
||||
## Licence
|
||||
|
||||
`/settings/license` shows the deployment, tier, server allowance, enabled
|
||||
features and expiry.
|
||||
The **Licence** page, in the sidebar, shows your instance ID, whether you are
|
||||
cloud or self-hosted, your tier, server allowance, enabled features and expiry
|
||||
date.
|
||||
|
||||
On **self-hosted**, paste a licence here. This works even while the current
|
||||
licence is expired that is the way out of degraded mode.
|
||||
On a **self-hosted** install you paste your licence here. This works even while
|
||||
your current licence has expired, which is how you get an instance out of
|
||||
read-only 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
|
||||
instead.
|
||||
On a **cloud** instance there is nothing to paste. Licences are installed for
|
||||
you, and the page links to the portal instead.
|
||||
|
||||
See [Licensing and entitlements](../hq/licensing-and-entitlements.md).
|
||||
|
||||
## Sessions
|
||||
|
||||
Sessions are an opaque token in the `km_session` cookie, held in Redis with a
|
||||
24-hour TTL. There is no per-session management UI; restarting Redis signs
|
||||
everyone out and affects nothing else.
|
||||
|
||||
## Host and organisation guard
|
||||
|
||||
On a multi-tenant deployment, a request to `<slug>.vantage.<tld>` resolves the
|
||||
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
|
||||
protecting anything. If you serve the UI on a custom domain, set it to match.
|
||||
:::
|
||||
Signing in gives you a session that lasts 24 hours. There is no session list to
|
||||
manage. On a self-hosted install, restarting Redis signs everyone out and affects
|
||||
nothing else.
|
||||
|
||||
+15
-18
@@ -22,14 +22,12 @@ fingerprint, and never needs the private half for this path.
|
||||
|
||||
### Generate one on a server
|
||||
|
||||
Vantage can have an agent generate a keypair on a managed machine
|
||||
(`GenerateKeyCmd` over the command stream). The public half comes back to the
|
||||
library. You may optionally upload the private half too, in which case it is
|
||||
Vantage can have a managed machine generate a keypair for you. The public half
|
||||
comes back to the 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
|
||||
own endpoint and its own audit event.
|
||||
Vantage never displays stored private key material in a list. Retrieving one is
|
||||
a separate, deliberate action, and it is written to the audit log.
|
||||
|
||||
:::tip Why store a private key at all
|
||||
The [browser console](./browser-console.md) needs one to open an SSH session. If
|
||||
@@ -38,13 +36,13 @@ 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
|
||||
agent picks up the change.
|
||||
Assign a key to one or more servers. The agent picks up the change within about
|
||||
30 seconds.
|
||||
|
||||
## Revoking
|
||||
|
||||
Revocation is **soft**: the assignment gets a `revoked_at` timestamp rather than
|
||||
being deleted, so the history of who had access to what, and when, survives.
|
||||
Revoking marks the assignment revoked, with a timestamp, rather than erasing it,
|
||||
so the record of who had access to what, and when, survives.
|
||||
|
||||
The agent treats a revoked assignment as "not desired" and removes the line from
|
||||
`authorized_keys` on its next sync.
|
||||
@@ -60,13 +58,12 @@ Each poll:
|
||||
|
||||
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.
|
||||
4. If they differ, it writes a temporary file, then `os.Rename()`s it over the
|
||||
real one and sets mode `0600`.
|
||||
3. **If they match, it writes nothing.** That is true of almost every check.
|
||||
4. If they differ, it writes the new file alongside the old one and swaps it in
|
||||
one step.
|
||||
|
||||
The rename is atomic, so a machine that dies mid-write keeps the old file
|
||||
intact. There is no window in which `authorized_keys` is truncated or partial.
|
||||
The swap cannot be interrupted halfway, so a machine that loses power mid-change
|
||||
keeps its old, working file.
|
||||
|
||||
:::danger Vantage owns the whole file
|
||||
The agent rewrites `authorized_keys` to match the desired set. Keys added by
|
||||
@@ -77,5 +74,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
|
||||
hosting provider. Vantage has no backdoor and does not keep a break-glass key.
|
||||
the console, provided a private key is stored, or whatever out-of-band access
|
||||
your hosting provider offers. Vantage has no backdoor and does not keep a break-glass key.
|
||||
|
||||
@@ -9,8 +9,8 @@ against the security advisories published by that server's own distribution and
|
||||
raises a finding for anything not yet patched.
|
||||
|
||||
Requires the **vulnerability scanning** feature on your licence. Without it,
|
||||
agents collect nothing at all — there is no inventory stored and no findings
|
||||
page to read.
|
||||
nothing is collected and there is no findings page. See
|
||||
[Licensing and entitlements](../hq/licensing-and-entitlements.md).
|
||||
|
||||
## What gets scanned
|
||||
|
||||
@@ -20,10 +20,9 @@ report.
|
||||
|
||||
Windows servers are not scanned.
|
||||
|
||||
Some distributions publish no machine-readable advisory feed. Those servers
|
||||
show **unsupported** on their own page rather than appearing as having no
|
||||
vulnerabilities — the two are very different answers, and only one of them is
|
||||
good news.
|
||||
Some distributions publish no security advisories Vantage can read. Those
|
||||
servers are shown as **unsupported**, rather than as having no vulnerabilities.
|
||||
Those are very different answers, and only one of them is good news.
|
||||
|
||||
## Why versions look "wrong"
|
||||
|
||||
@@ -43,9 +42,9 @@ the accurate one for the package you are actually running.
|
||||
|
||||
## The board
|
||||
|
||||
`/vulnerabilities` groups findings by CVE. One row per CVE with the number of
|
||||
affected servers, expandable to the individual servers — the same CVE across
|
||||
forty machines is one decision, not forty.
|
||||
The **Vulnerabilities** page groups findings by CVE, one row each, with the
|
||||
number of servers affected. Expand a row to see them. The same CVE across forty
|
||||
machines is usually one decision, not forty.
|
||||
|
||||
Severity counts at the top filter the list when clicked. The state tabs switch
|
||||
between **open**, **accepted** and **fixed**.
|
||||
@@ -60,8 +59,8 @@ A finding with a known fixed version gets an **Apply updates** button, which
|
||||
runs the same OS update the server page offers. There is no separate patching
|
||||
mechanism.
|
||||
|
||||
Vantage never patches automatically. An unattended upgrade triggered by a third
|
||||
party's data feed is a fleet-wide change nobody chose.
|
||||
Vantage never patches automatically. Applying updates is always something you
|
||||
ask for.
|
||||
|
||||
## Accepting a finding
|
||||
|
||||
@@ -72,23 +71,21 @@ or one with no vendor fix published at all.
|
||||
a reason that is recorded in the audit log along with your name. On that date it
|
||||
reopens by itself.
|
||||
|
||||
The expiry is required. A dismissal with no end date is how a finding gets
|
||||
forgotten, and it is exactly what an auditor will ask to see.
|
||||
An expiry date is required, so nothing is dismissed permanently by accident.
|
||||
|
||||
## Alerts
|
||||
|
||||
Alert rules live with your notification channels, under
|
||||
**Settings → Notification Channels**. A rule has a minimum severity, an optional
|
||||
server tag filter, and one or more channels.
|
||||
Alert rules live with your
|
||||
[notification channels](./notification-channels.md). A rule has a minimum
|
||||
severity, an optional server tag filter, and the channels to notify.
|
||||
|
||||
A rule sends **one digest per scan** summarising what newly opened — never one
|
||||
message per finding. A database refresh can open several hundred findings at
|
||||
once, and a message each would flood the channel.
|
||||
A rule sends **one summary per scan** covering everything newly found, rather
|
||||
than one message per finding. A single update to the security data can raise
|
||||
hundreds at once.
|
||||
|
||||
Findings that were already open do not re-alert.
|
||||
|
||||
## Fleet-wide package search
|
||||
|
||||
`GET /api/packages/search?name=openssl` answers which servers run a given
|
||||
package and at what version, across the whole fleet. Useful during an incident
|
||||
before a finding exists for it.
|
||||
Search your whole fleet for a package by name to see which servers have it and
|
||||
at what version. Useful during an incident, before there is a finding for it.
|
||||
|
||||
+65
-82
@@ -4,10 +4,9 @@ title: Workflows and steps
|
||||
sidebar_label: Workflows
|
||||
---
|
||||
|
||||
A **step** is a reusable script with declared inputs, outputs and secret
|
||||
references. A **workflow** composes steps in order and targets a set of servers.
|
||||
Running one dispatches the steps to each target's agent and streams the output
|
||||
back live.
|
||||
A **step** is a reusable script with its own inputs, outputs and secrets. A
|
||||
**workflow** puts steps in order and aims them at a set of servers. Running one
|
||||
sends the steps to each server and streams the output back as it happens.
|
||||
|
||||
## Steps
|
||||
|
||||
@@ -15,12 +14,12 @@ 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 |
|
||||
| Name and description | How you recognise it in the library |
|
||||
| Interpreter | `bash` or `powershell` |
|
||||
| Script | What it runs |
|
||||
| Inputs | Named parameters, with defaults |
|
||||
| Outputs | Values this step passes on |
|
||||
| Secrets | Vault groups made available to it |
|
||||
|
||||
### Passing values between steps
|
||||
|
||||
@@ -34,42 +33,36 @@ echo "$HOSTNAME"
|
||||
echo "HOSTNAME=$HOSTNAME" >> $WORKFLOW_ENV
|
||||
```
|
||||
|
||||
That is the whole mechanism. `declared_outputs` documents what a step exports so
|
||||
the designer can show it; the file is what actually carries the value.
|
||||
That is the whole mechanism. Listing a step's outputs documents them for the
|
||||
designer, but writing to that file is what actually passes a value on.
|
||||
|
||||
### Secrets
|
||||
|
||||
List a vault group in `secret_refs` and its key/value pairs are injected as
|
||||
environment variables when the step runs. They are not written to the run log
|
||||
unless your own script echoes them. See [Secrets](./secrets.md).
|
||||
Add a vault group to a step and its pairs are available as environment variables
|
||||
while it runs. They do not appear in the run log unless your own script prints
|
||||
them. See [Secrets](./secrets.md).
|
||||
|
||||
### The workspace
|
||||
|
||||
Every run gets a per-run working directory on each target. Steps share it, so
|
||||
one step can leave a file for the next. The agent removes it at the end of the
|
||||
run (`CleanupWorkspaceCmd`).
|
||||
Every run gets its own working directory on each server. Steps share it, so one
|
||||
step can leave a file for the next. It is deleted when the run finishes.
|
||||
|
||||
Do not use it for anything that must outlive the run.
|
||||
|
||||
## Default steps
|
||||
|
||||
A small library is seeded into every organisation at boot from the image, so a
|
||||
new install is not staring at an empty page.
|
||||
Vantage ships a small library of ready-made steps, so a 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.
|
||||
They are reinstalled every time Vantage restarts, so any edit or deletion would
|
||||
come back anyway. Vantage refuses the change rather than letting it quietly
|
||||
revert.
|
||||
|
||||
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
|
||||
shared library permanently, a file has to be committed to the repository and the
|
||||
server image rebuilt.
|
||||
To adapt one, override its script inside the workflow that uses it. That change
|
||||
belongs to the workflow and is left alone.
|
||||
:::
|
||||
|
||||
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
|
||||
|
||||
1. **Workflows → New**.
|
||||
@@ -81,11 +74,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 | Stop this server's run. Other servers carry on |
|
||||
| Continue | Record the failure and run the next step anyway |
|
||||
| Retry | Try again up to the limit you set, then count it as a failure |
|
||||
|
||||
### Per-step overrides
|
||||
|
||||
@@ -97,27 +90,21 @@ scoped to that workflow.
|
||||
|
||||
A workflow names servers two ways, and it can use both at once:
|
||||
|
||||
- **Target servers** an explicit list you pick from the fleet.
|
||||
- **Target tags** a `key:value` selector matched against
|
||||
[server tags](./servers.md#tags). More than one key ANDs: a server must carry
|
||||
every pair to match.
|
||||
- **Target servers**, a list you pick by hand.
|
||||
- **Target tags**, matched against [server tags](./servers.md#tags). Give more
|
||||
than one tag and a server must carry all of them to match.
|
||||
|
||||
A run goes to the **union** of the two, with duplicates removed. A server that is
|
||||
both named explicitly and matched by the selector runs once, not twice. This is
|
||||
what lets a workflow say "every production web server, plus this one box I am
|
||||
watching" without maintaining a list.
|
||||
A run goes to both sets combined. A server that is named by hand and also matched
|
||||
by a tag runs once. That is how a workflow can say "every production web server,
|
||||
plus this one machine I am watching" without you keeping a list up to date.
|
||||
|
||||
The designer shows the resolved count as you edit, so you can see how many
|
||||
machines a change to the selector just added or removed before you save.
|
||||
|
||||
:::warning An empty selector matches nothing
|
||||
Clearing the tag selector does not mean "all servers". A workflow with no named
|
||||
servers and no tags matches nothing and is refused at run time rather than
|
||||
reported as a success over zero machines.
|
||||
|
||||
The alternative reading, where an empty field means the whole fleet, turns a
|
||||
cleared box into a fleet-wide run. That is not a mistake anyone should be able to
|
||||
make by deleting text.
|
||||
Clearing the tags does not mean "all servers". A workflow with no servers and no
|
||||
tags matches nothing, and running it is refused rather than reported as a
|
||||
success over zero machines.
|
||||
:::
|
||||
|
||||
Tags are read **at run time**, not when you save. Tag a new machine `env:prod`
|
||||
@@ -127,31 +114,29 @@ machine from every workflow that selected on it.
|
||||
|
||||
### Offline servers are still targeted
|
||||
|
||||
A server matched by tag is dispatched to even if its agent is offline, and that
|
||||
step fails visibly on that machine. Vantage does not quietly shrink your target
|
||||
list to the machines that happened to be reachable a patch run that skipped
|
||||
three servers and reported success is worse than one that failed on three and
|
||||
said so.
|
||||
A server is still targeted when its agent is offline, and the run fails visibly
|
||||
on that machine. Vantage does not quietly drop unreachable servers from a run,
|
||||
because a patch run that skipped three servers and called itself a success is
|
||||
harder to spot than one that failed.
|
||||
|
||||
Re-run the workflow once they are back, or fix the agent first.
|
||||
|
||||
## Running
|
||||
|
||||
**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.
|
||||
**Run** records the exact steps being run, then sends them to each server
|
||||
straight away.
|
||||
|
||||
:::info Runs freeze their steps
|
||||
The snapshot is why editing a step tomorrow never rewrites what happened today.
|
||||
A run shows the script that actually executed, not the current library version.
|
||||
Editing a step tomorrow never changes what a past run shows. A run always
|
||||
displays the script that actually ran.
|
||||
:::
|
||||
|
||||
Targets run **in parallel**; steps within one server run **in order**.
|
||||
|
||||
## Schedules
|
||||
|
||||
A workflow can carry a schedule, and Vantage will start it the same way a person
|
||||
would — the same dispatch, the same snapshot, the same run page. A scheduled run
|
||||
is an ordinary run with `schedule` recorded as who triggered it.
|
||||
A workflow can run on a schedule. A scheduled run is an ordinary run, on the
|
||||
same run page, with the schedule recorded as what started it.
|
||||
|
||||
Open a workflow, choose **Edit**, and tick **Run on a schedule**. The expression
|
||||
is standard five-field cron:
|
||||
@@ -175,10 +160,10 @@ than the browser, so what you see is exactly what will fire.
|
||||
|
||||
### Timezones
|
||||
|
||||
A schedule stores an IANA timezone by name — `Europe/London`, not an offset.
|
||||
That is what makes a 02:00 job stay at 02:00 across a daylight-saving change
|
||||
instead of drifting an hour for half the year. An unknown zone is refused when
|
||||
you save it, not at 2am.
|
||||
A schedule stores a timezone by name, such as `Europe/London`, rather than an
|
||||
offset. That keeps a 02:00 job at 02:00 across daylight-saving changes instead
|
||||
of drifting by an hour for half the year. A timezone Vantage does not recognise
|
||||
is refused when you save it.
|
||||
|
||||
### Overlaps are skipped, not queued
|
||||
|
||||
@@ -189,28 +174,27 @@ should fall behind visibly rather than pile up.
|
||||
|
||||
### Missed occurrences
|
||||
|
||||
If the control plane was not running when an occurrence was due, it still fires
|
||||
when the control plane comes back — but only within **one hour** of the due
|
||||
time. Anything older is recorded as missed and dropped. A job missed by ten
|
||||
minutes during an upgrade should still run; one missed by two days should not
|
||||
suddenly fire at lunchtime.
|
||||
If Vantage was not running when a scheduled run was due, it still runs when
|
||||
Vantage comes back, as long as that is within **one hour** of the due time.
|
||||
Anything older is recorded as missed and skipped, so a job missed during a short
|
||||
upgrade catches up, while one missed for two days does not suddenly start at
|
||||
lunchtime.
|
||||
|
||||
Either kind of skip is shown on the workflow's schedule panel, with the time it
|
||||
was due and why it did not run.
|
||||
|
||||
## Watching a run
|
||||
|
||||
Step stdout and stderr stream back as chunks, are appended to a log file on the
|
||||
server, and the UI follows them live. Each step records status, attempts, exit
|
||||
code and its exported environment.
|
||||
Output streams back as it happens and the page follows it live. Each step
|
||||
records its status, how many attempts it took, its exit code and any values it
|
||||
passed on.
|
||||
|
||||
**Cancel** stops a run in progress. Steps already running on an agent finish;
|
||||
nothing further is dispatched.
|
||||
|
||||
## Log retention
|
||||
|
||||
Run logs are swept on a schedule set by `workflow_log_retention_days` in
|
||||
Settings:
|
||||
How long run logs are kept is set under **Settings → Monitoring**:
|
||||
|
||||
| Value | Meaning |
|
||||
| -------- | -------------- |
|
||||
@@ -220,16 +204,15 @@ Settings:
|
||||
|
||||
## Import and export
|
||||
|
||||
Steps export to a JSON file (`vantage.step/v1`) and import back, which is how
|
||||
you move a step between instances or keep one in version control. There is also
|
||||
a parse endpoint that turns a pasted script into a draft step by reading its
|
||||
declared inputs and outputs.
|
||||
A step exports to a file and imports back, which is how you move one between
|
||||
instances or keep it in version control. You can also paste a script and have
|
||||
Vantage turn it into a draft step for you.
|
||||
|
||||
## Practical notes
|
||||
|
||||
- A step is a script. It runs as root, on the target, with no sandbox. Review
|
||||
what you import.
|
||||
- Keep steps small and single-purpose; compose them in the workflow. That is
|
||||
what makes the library reusable rather than a folder of near-duplicates.
|
||||
- Keep steps small and single-purpose, and combine them in the workflow. A
|
||||
library of small steps stays reusable.
|
||||
- PowerShell steps only make sense on Windows targets and bash steps on Linux
|
||||
ones. Nothing stops you targeting the wrong one; the step simply fails.
|
||||
|
||||
+33
-43
@@ -4,30 +4,27 @@ title: Workloads
|
||||
sidebar_label: Workloads
|
||||
---
|
||||
|
||||
A **workload** is one Docker container or one systemd service. Each Linux
|
||||
server reports what it runs, and you can start, stop and restart those
|
||||
workloads — and read a snapshot of their logs — without opening a console.
|
||||
A **workload** is one Docker container or one systemd service. Each Linux server
|
||||
reports what it is running, and you can start, stop and restart those workloads,
|
||||
and read their recent logs, without opening a console.
|
||||
|
||||
Available on every instance. No licence feature is required.
|
||||
|
||||
## What gets reported
|
||||
|
||||
Linux servers only. Agents report every 60 seconds, and an unchanged list costs
|
||||
a single small message rather than the whole thing again.
|
||||
Linux servers only, reported every 60 seconds.
|
||||
|
||||
- **Containers** — every container, running or not, with its image, published
|
||||
- **Containers**: every container, running or not, with its image, published
|
||||
ports, health, restart count and the compose stack it belongs to.
|
||||
- **Services** — systemd units that are running or failed, plus units that are
|
||||
enabled but currently stopped. The platform's own units (`systemd-*`,
|
||||
`user@*`, `session-*`) are filtered out; a typical host has 300 of them and
|
||||
they bury the ten you care about.
|
||||
- **Services**: systemd units that are running, failed, or enabled but stopped.
|
||||
The operating system's own units are hidden, since a typical host has hundreds
|
||||
of them and they bury the ones you care about.
|
||||
|
||||
Windows servers report no workloads at all.
|
||||
|
||||
## Docker not in use is not an error
|
||||
|
||||
Three different things look identical if you are careless, and only one of them
|
||||
is a problem:
|
||||
Three states look similar, and only one of them is a problem:
|
||||
|
||||
| What you see | What it means |
|
||||
| ------------ | ------------- |
|
||||
@@ -37,54 +34,47 @@ is a problem:
|
||||
|
||||
## Stacks are grouped
|
||||
|
||||
Compose stacks appear first, grouped under the stack name, then loose
|
||||
containers, then services. A stack is one thing even when it is six containers,
|
||||
and a flat list turns one decision into six rows.
|
||||
Compose stacks appear first, grouped under the stack name, then individual
|
||||
containers, then services.
|
||||
|
||||
The stack name comes from Docker's own `com.docker.compose.project` label. No
|
||||
compose file is read from disk — a file on disk may not be what is running.
|
||||
The stack name comes from Docker itself, so it reflects what is actually
|
||||
running.
|
||||
|
||||
## Controlling a workload
|
||||
|
||||
Start, stop and restart are **owner or admin only**, and every action is
|
||||
written to the audit log naming you, the server and the target.
|
||||
|
||||
The agent refuses to act on itself. `vantage-agent.service` is shown with its
|
||||
buttons disabled: a server that stops its own agent goes offline, and the only
|
||||
way back is SSH or physical access — which is exactly what this page exists to
|
||||
avoid needing.
|
||||
The Vantage agent will not act on itself, and its buttons are disabled. A server
|
||||
that stopped its own agent would go offline, and getting it back would need SSH
|
||||
or physical access.
|
||||
|
||||
A stop that never finishes is not reported as success. Both `docker stop` and
|
||||
`systemctl stop` run under a 90-second limit, and a timeout comes back as a
|
||||
real error.
|
||||
A stop that never finishes is not reported as a success. Vantage waits up to 90
|
||||
seconds and then reports the failure.
|
||||
|
||||
## Reading logs
|
||||
|
||||
Logs are **owner or admin only** and every read is audited. Unlike workflow
|
||||
logs, a container's output cannot be masked: it is arbitrary, and a startup
|
||||
banner or a stack trace may contain credentials nobody declared.
|
||||
Reading logs is **owner or admin only**, and every read is audited. A
|
||||
container's output cannot be filtered the way a workflow's can, and a startup
|
||||
banner or stack trace may contain credentials nobody expected.
|
||||
|
||||
A log read returns a snapshot of at most **500 lines or 256KB**, whichever
|
||||
limit is reached first, with the most recent output kept. When either limit
|
||||
binds, the dialog says so — a truncated log must never be read as a complete
|
||||
one.
|
||||
You get the most recent output, up to **500 lines or 256KB**, whichever comes
|
||||
first. If it was cut short, the dialog says so.
|
||||
|
||||
There is no live following. The [browser console](./browser-console.md) already
|
||||
gives you a real terminal on the same server, where `docker logs -f` works
|
||||
properly with its own scrollback.
|
||||
There is no live tail here. For that, use the
|
||||
[browser console](./browser-console.md), which gives you a real terminal on the
|
||||
same server.
|
||||
|
||||
## Refreshing
|
||||
|
||||
Opening a server's Workloads panel asks its agent to report immediately, so
|
||||
what is on screen is current rather than up to a minute old. That matters
|
||||
because the panel has a Restart button on it: a stale row is not just a wrong
|
||||
impression, it is a wrong action aimed at something that already died.
|
||||
Opening a server's Workloads panel asks its agent to report straight away, so
|
||||
what you see is current rather than up to a minute old. That matters when the
|
||||
next thing you click is Restart.
|
||||
|
||||
If the agent is offline the refresh fails visibly rather than queueing. A
|
||||
command whose target cannot be reached must say so.
|
||||
If the agent is offline, the refresh reports a failure rather than waiting.
|
||||
|
||||
## Fleet view
|
||||
|
||||
**Workloads** in the sidebar searches the whole fleet by image, stack or state
|
||||
— "which of these servers is still on the old image" — and links each result
|
||||
back to its server.
|
||||
**Workloads** in the sidebar searches your whole fleet by image, stack or state,
|
||||
which is how you answer questions like "which servers are still on the old
|
||||
image". Each result links back to its server.
|
||||
|
||||
Reference in New Issue
Block a user