docs: Self review of doc pages
This commit is contained in:
@@ -4,64 +4,73 @@ title: Claim a Free licence
|
||||
sidebar_label: Claim a Free licence
|
||||
---
|
||||
|
||||
A self-hosted install runs unlicensed until you give it a licence. Free is a
|
||||
real tier in both deployments, and you can claim one for your install from the
|
||||
HQ portal.
|
||||
A self-hosted install stays read-only until you give it a licence. You claim a
|
||||
Free one from Vantage HQ, and it takes a couple of minutes.
|
||||
|
||||
:::warning An unlicensed install is read-only
|
||||
You can sign in and look around, but adding servers, keys, workflows and
|
||||
everything else is refused until a licence is installed. Do this before
|
||||
[adding your first server](./first-server.md).
|
||||
:::
|
||||
|
||||
## What a licence is
|
||||
|
||||
A signed file. It carries the instance ID it belongs to, the tier, the server
|
||||
allowance, feature toggles and an expiry. The control plane verifies the
|
||||
signature locally.
|
||||
A signed file that names your instance, its tier, how many servers you may
|
||||
manage, which features are enabled and when it expires. Your install checks the
|
||||
signature itself, so it never has to reach Vantage HQ to work.
|
||||
|
||||
A running instance does not need HQ to be reachable.
|
||||
|
||||
:::info One Free per account, per deployment.
|
||||
The limit is enforced per account **and** deployment, so a Free cloud instance does not stop you claiming Free on a self-hosted install.
|
||||
:::info One Free licence per account, per deployment
|
||||
A Free cloud instance does not use up your Free self-hosted one. They are
|
||||
separate.
|
||||
:::
|
||||
|
||||
## 1. Find your instance ID
|
||||
|
||||
In the control plane, go to **Settings → Licence**. The instance ID is shown there.
|
||||
Open the **Licence** page from the sidebar of your install. The instance ID is
|
||||
shown at the top, and it is the value Vantage HQ asks for.
|
||||
|
||||
## 2. Create a free license
|
||||
## 2. Create the instance in Vantage HQ
|
||||
|
||||
1. Sign in at [Vantage HQ](https://vantage-hq.hostxtra.co.uk). If you have no
|
||||
account, see [Accounts and signup](../hq/accounts-and-signup.md).
|
||||
2. Click on the **Buy A Plan** button.
|
||||
3. Click on **Self Hosted** then click on the **Free** plan, then finally Paste the instance ID and give it a name you will recognise.
|
||||
account yet, see [Accounts and signup](../hq/accounts-and-signup.md).
|
||||
2. On **Overview**, choose **License my own install**. Once you already have an
|
||||
instance, the same page offers **Buy a plan** instead.
|
||||
3. Choose **Self-hosted**, then the **Free** plan.
|
||||
4. Paste your instance ID, give the instance a name you will recognise, and
|
||||
click **Create licence**.
|
||||
|
||||
You will then see the new instance on the **Overview** page.
|
||||
The new instance now appears on the **Overview** page.
|
||||
|
||||
## 3. Downloading the free license
|
||||
## 3. Download the licence
|
||||
|
||||
With the instance created go to the **Overview** page and expand the new instance.
|
||||
|
||||
Click on the **View Instance Settings** button. You can then click on the **Download License** or the **Copy to clipboard** button.
|
||||
Expand the new instance on **Overview** and click **View Instance Settings**.
|
||||
From there, use **Download licence** or **Copy to clipboard**.
|
||||
|
||||
## 4. Install the licence
|
||||
|
||||
Download the licence from HQ and paste it in the control plane at
|
||||
**Settings → Licence**.
|
||||
Back in your install, open the **Licence** page, paste the licence and save.
|
||||
Your instance confirms the licence was issued to it, then shows your tier,
|
||||
server allowance and expiry date.
|
||||
|
||||
The instance validates the signature, checks the ID matches its own, and
|
||||
starts reporting the tier, allowance and expiry.
|
||||
|
||||
:::info Cloud instances do **not** require installing the license as this is done automatically.
|
||||
:::info Cloud instances need none of this
|
||||
A cloud instance is licensed automatically when it is created. These steps are
|
||||
for self-hosted installs only.
|
||||
:::
|
||||
|
||||
## Renewing
|
||||
|
||||
Free licences are renewable from HQ within a renewal window near expiry;
|
||||
outside that window you cannot renew early. See [Free tier](../hq/free-tier.md).
|
||||
Free licences run for a year. The renew button appears in Vantage HQ seven days
|
||||
before expiry and stays available after it, so a lapsed instance can still be
|
||||
rescued. See [Free tier](../hq/free-tier.md).
|
||||
|
||||
## Moving the install to new hardware
|
||||
|
||||
Rebuilding produces a new instance ID, and a licence binds to a ID. Use
|
||||
**Relink** in HQ to move the licence across. The number of relinks per term is
|
||||
capped; the portal shows how many you have left.
|
||||
A rebuilt install gets a new instance ID, and a licence only works for the ID it
|
||||
was issued to. Use **Relink** in Vantage HQ to move the licence across. You get
|
||||
three relinks per term, and the portal shows how many are left.
|
||||
|
||||
## Next
|
||||
|
||||
- [Add your first server](./first-server.md)
|
||||
- [Licensing and entitlements](../hq/licensing-and-entitlements.md)
|
||||
- [Buying a paid self-hosted licence](../hq/self-hosted-instances.md)
|
||||
|
||||
@@ -4,64 +4,62 @@ title: Cloud or self-hosted
|
||||
sidebar_label: Cloud or self-hosted
|
||||
---
|
||||
|
||||
Vantage runs in two deployments. They are the same software; what differs is
|
||||
who operates it and how licensing, users and data lifecycle work.
|
||||
Vantage runs in two ways. It is the same software; what differs is who runs it,
|
||||
and how licensing and user accounts work.
|
||||
|
||||
## At a glance
|
||||
|
||||
| | Cloud | Self-hosted |
|
||||
| --------------------- | --------------------------------------------------- | ------------------------------ |
|
||||
| Who runs it | We do | You do |
|
||||
| Where you sign in | `<your-slug>.vantage.hostxtra.co.uk` | Your own hostname |
|
||||
| Database and backups | Ours | Yours |
|
||||
| Licence | Written for you when you buy or create the instance | Pasted in, or claimed from HQ |
|
||||
| Team members | Granted from HQ; the instance holds a projection | Created in the instance itself |
|
||||
| Free tier | Yes, one per account | Yes, one per account |
|
||||
| Expired Free instance | Eventually deleted, after warning | Never deleted |
|
||||
| | Cloud | Self-hosted |
|
||||
| --------------------- | ------------------------------------------- | ------------------------------ |
|
||||
| Who runs it | We do | You do |
|
||||
| Where you sign in | `<your-slug>.vantage.hostxtra.co.uk` | Your own hostname |
|
||||
| Database and backups | Ours | Yours |
|
||||
| Licence | Installed for you | You paste it in |
|
||||
| Team members | Granted from Vantage HQ | Created in the instance itself |
|
||||
| Free tier | Yes, one per account | Yes, one per account |
|
||||
| Expired Free instance | Eventually deleted, after warning emails | Never deleted |
|
||||
|
||||
## Cloud
|
||||
|
||||
You create an instance from the HQ portal and it exists a few seconds later,
|
||||
already licensed. People you grant access to get a real user inside that
|
||||
instance see [People and roles](../hq/people-and-roles.md) but HQ owns their
|
||||
password, role and existence.
|
||||
You create an instance from the Vantage HQ portal and it is ready seconds later,
|
||||
already licensed. People you grant access to get a real account inside that
|
||||
instance, but Vantage HQ owns their password and role. See
|
||||
[People and roles](../hq/people-and-roles.md).
|
||||
|
||||
:::info The instance does not phone home
|
||||
A grant writes a user row into the control plane once. After that the instance
|
||||
authenticates that person entirely on its own. HQ being down does not stop
|
||||
anyone signing in to a running instance.
|
||||
:::
|
||||
Your instance keeps working whether or not Vantage HQ is reachable. Signing in
|
||||
and managing servers never depend on it.
|
||||
|
||||
Cloud instances on the Free tier are reaped after their licence expires, with
|
||||
warning emails first. See [Free tier](../hq/free-tier.md).
|
||||
Cloud instances on the Free tier are deleted some time after their licence
|
||||
expires, with warning emails first. See [Free tier](../hq/free-tier.md).
|
||||
|
||||
## Self-hosted
|
||||
|
||||
You run the Docker Compose stack on your own infrastructure. Nothing about the
|
||||
control plane requires an internet connection to HQ at runtime a licence is a
|
||||
signed file, verified locally.
|
||||
You run Vantage with Docker Compose on your own infrastructure. It needs no
|
||||
connection to us at runtime, because a licence is a signed file your install
|
||||
checks for itself.
|
||||
|
||||
Two ways to get one:
|
||||
|
||||
1. **Free** link the install to an HQ account and claim it
|
||||
([Claim a Free licence](./claim-free-licence.md)).
|
||||
2. **Paid** buy from HQ, which creates a placeholder, then paste the install's
|
||||
real instance UUID to bind and issue
|
||||
([Self-hosted instances](../hq/self-hosted-instances.md)).
|
||||
1. **Free.** Link the install to a Vantage HQ account and claim it. See
|
||||
[Claim a Free licence](./claim-free-licence.md).
|
||||
2. **Paid.** Buy from Vantage HQ, then paste your install's instance ID to have
|
||||
the licence issued. See
|
||||
[Self-hosted instances](../hq/self-hosted-instances.md).
|
||||
|
||||
Self-hosted users are local (or OIDC). There is no projection from HQ, and the
|
||||
three member endpoints in HQ refuse to touch a self-hosted instance at all.
|
||||
People who sign in to a self-hosted install are created in the install itself,
|
||||
either with a password or through single sign-on. Vantage HQ cannot add them for
|
||||
you.
|
||||
|
||||
## Which should you pick
|
||||
|
||||
Pick cloud if you want the thing running now and do not want to own a MongoDB.
|
||||
Pick cloud if you want it running today and would rather not run a database.
|
||||
Pick self-hosted if your policy requires the control plane inside your own
|
||||
network, or the servers you manage cannot reach the public internet.
|
||||
network, or the servers you manage cannot reach the internet.
|
||||
|
||||
Moving between them is a migration, not a switch instances are bound to a
|
||||
deployment at creation, and a licence binds to an instance UUID.
|
||||
Moving between the two means migrating your data, and a new licence, since a
|
||||
licence is tied to one instance.
|
||||
|
||||
## Next
|
||||
|
||||
- [Self-hosted install](./self-hosted-install.md)
|
||||
- [Accounts and signup](../hq/accounts-and-signup.md) if you are going cloud
|
||||
- [Accounts and signup](../hq/accounts-and-signup.md), if you are going cloud
|
||||
|
||||
@@ -6,67 +6,82 @@ sidebar_label: First login
|
||||
|
||||
A fresh install has no users and no instance. The first visit creates both.
|
||||
|
||||
## 1. Bootstrap
|
||||
## 1. Create the first account
|
||||
|
||||
Open the control plane in a browser. Because no user exists, you land on
|
||||
`/setup`.
|
||||
Open your Vantage address in a browser. Because no user exists yet, you land on
|
||||
the setup page.
|
||||
|
||||
Fill in:
|
||||
|
||||
| Field | Notes |
|
||||
| ------------- | ------------------------------------- |
|
||||
| Instance name | Display name. Shown throughout the UI |
|
||||
| Email | Becomes your sign-in identity |
|
||||
| Password | Stored bcrypt-hashed |
|
||||
| Field | Notes |
|
||||
| ---------------- | --------------------------------------------------------- |
|
||||
| Instance name | Also used to derive your instance's own subdomain |
|
||||
| Owner email | Becomes your sign-in identity |
|
||||
| Password | At least 8 characters |
|
||||
| Confirm password | Must match |
|
||||
|
||||
Submitting creates the instance and its **owner** you.
|
||||
**Setup Instance** creates the instance and makes you its **owner**.
|
||||
|
||||
:::warning Bootstrap works exactly once
|
||||
The endpoint is open only while the database has no users. As soon as the first
|
||||
one exists, There is no second chance to create the first owner, so record the
|
||||
credentials before you continue.
|
||||
:::warning Your instance gets its own address
|
||||
If you installed on a name like `vantage.example.com`, an instance called Acme
|
||||
signs in at `acme.vantage.example.com`, and each instance keeps its own sign-in.
|
||||
Make sure DNS and your reverse proxy cover that subdomain, or use a wildcard.
|
||||
:::
|
||||
|
||||
## 2. Copy the Instance ID
|
||||
:::warning Setup runs exactly once
|
||||
It is only available while the database has no users. Once yours exists, the
|
||||
page closes for good, so record the email and password before you continue.
|
||||
:::
|
||||
|
||||
Once you have finished setup you will see the successfully created page.
|
||||
## 2. Copy the instance ID
|
||||
|
||||
This will show the Instance ID. You will need this ID when creating a license in the HQ.
|
||||
The confirmation page, headed **Instance created**, shows your instance ID and
|
||||
your sign-in address. You need that ID to claim a licence in Vantage HQ, and it
|
||||
is the reference support works from. You can find it again later on the
|
||||
**Licence** page in the sidebar.
|
||||
|
||||
## 3. Sign in
|
||||
|
||||
Click the continue to sign in button on the successful setup page.
|
||||
|
||||
You will be taken to `/login`. Sign in with the email and password you just set.
|
||||
Click **Go to sign in**, then sign in with the email and password you just set.
|
||||
|
||||
## 4. Look around
|
||||
|
||||
You land on the servers dashboard, which is empty. The sidebar is the whole
|
||||
product:
|
||||
You land on the servers page, which is empty. The sidebar is the whole product:
|
||||
|
||||
| Section | What it does |
|
||||
| --------- | ------------------------------------------ |
|
||||
| Servers | The server enrol, inspect, console, update |
|
||||
| Keys | SSH public keys and their assignments |
|
||||
| Workflows | Compose and run scripted work |
|
||||
| Steps | The reusable step library |
|
||||
| Monitors | HTTP, TCP, ICMP and TLS checks |
|
||||
| Secrets | The encrypted vault |
|
||||
| Audit | Every mutating action |
|
||||
| Settings | Members, SSO, alerts, retention, licence |
|
||||
| Section | What it does |
|
||||
| --------------- | ------------------------------------------------ |
|
||||
| Servers | Your fleet: enrol, inspect, console, update |
|
||||
| Monitors | HTTP, TCP, ping and certificate checks |
|
||||
| Vulnerabilities | Known security issues in installed packages |
|
||||
| Workloads | Containers and services running on your servers |
|
||||
| SSH Keys | Public keys and which servers they are on |
|
||||
| Secrets | The encrypted vault |
|
||||
| Workflows | Compose and run scripted work |
|
||||
| Steps | The reusable step library |
|
||||
| Audit Log | A record of everything that changed |
|
||||
| Licence | Your tier, allowance and expiry |
|
||||
| Settings | People, sign-in, alerts and integrations |
|
||||
|
||||
## 5. Add the rest of your team
|
||||
**Licence** and **Settings** are shown only to owners and admins.
|
||||
|
||||
Go to **Settings → Access**. Add members with a role:
|
||||
## 5. Install your licence
|
||||
|
||||
| Role | Can |
|
||||
| -------- | -------------------------------------------------- |
|
||||
| `owner` | Everything, including billing-adjacent settings |
|
||||
| `admin` | Everything except owner-only settings |
|
||||
| `member` | Day-to-day work servers, keys, workflows, monitors |
|
||||
Until a licence is installed, the instance is read-only: you can look, but you
|
||||
cannot add servers or anything else. Continue with
|
||||
[Claim a Free licence](./claim-free-licence.md).
|
||||
|
||||
Settings and organisation management require `owner` or `admin`.
|
||||
## 6. Add the rest of your team
|
||||
|
||||
If you would rather not manage passwords, configure single sign-on instead: see [Settings](../vantage/settings.md#single-sign-on).
|
||||
Go to **Settings → Access** and add people with a role:
|
||||
|
||||
You can add more than one identity provider; each gets its own button on the login page, and no buttons appear at all until at least one provider is configured.
|
||||
| Role | Can |
|
||||
| -------- | ---------------------------------------------------- |
|
||||
| `owner` | Everything |
|
||||
| `admin` | Everything except owner-only settings |
|
||||
| `member` | Day-to-day work: servers, keys, workflows, monitors |
|
||||
|
||||
Changing settings, and adding or removing people, needs `owner` or `admin`.
|
||||
|
||||
If you would rather not manage passwords, you can use single sign-on instead,
|
||||
which is available on paid plans. See
|
||||
[Settings](../vantage/settings.md#single-sign-on).
|
||||
|
||||
@@ -4,64 +4,67 @@ title: Add your first server
|
||||
sidebar_label: Add your first server
|
||||
---
|
||||
|
||||
Enrolling a server means running one command on it. The control plane issues a
|
||||
short-lived token, the install script fetches the agent and writes a config, and
|
||||
the machine registers itself.
|
||||
Enrolling a server means running one command on it. Vantage issues a short-lived
|
||||
token, the install script fetches the agent and writes a config file, and the
|
||||
machine registers itself.
|
||||
|
||||
:::info You need a licence first
|
||||
An unlicensed install is read-only, so **Add server** will be refused until a
|
||||
licence is in place. If you have not done that yet, start with
|
||||
[Claim a Free licence](./claim-free-licence.md).
|
||||
:::
|
||||
|
||||
## 1. Create the enrolment
|
||||
|
||||
In the UI, go to **Servers → Add server** Then click the **Generate Install Command** button.
|
||||
This generates a server ID and a pre-registration token
|
||||
Go to **Servers → Add server**, then click **Generate install command**. Vantage
|
||||
creates a server record and an enrolment token for it.
|
||||
|
||||
:::warning The token is single-use and lives one hour
|
||||
It is the only credential in the flow, and it is spent the moment the agent registers.
|
||||
:::warning The token is single-use and lasts one hour
|
||||
It is the only credential in the flow, and it is spent the moment the agent
|
||||
registers. If it expires, generate a new command rather than reusing the old one.
|
||||
:::
|
||||
|
||||
## 2. Run the one-liner
|
||||
|
||||
### Linux
|
||||
|
||||
Run the generated install script as root.
|
||||
|
||||
Here is an example of the install script:
|
||||
Run the generated command as root. It looks like this:
|
||||
|
||||
```bash
|
||||
curl -fsSL "https://vantage.example.com/install?server_id=<id>&token=<token>" | bash
|
||||
```
|
||||
|
||||
What the script does:
|
||||
The script:
|
||||
|
||||
1. Detects architecture `x86_64` and `aarch64` only; anything else exits.
|
||||
2. Downloads the binary and `checksums.txt`, and **verifies the SHA-256**, aborting on a mismatch.
|
||||
3. Installs to `/usr/local/bin/vantage-agent`, mode `0755`.
|
||||
4. Writes the config file at `/etc/vantage/config.yaml`
|
||||
1. This contains the server ID, the pre-registration token and the gRPC host.
|
||||
5. Writes the systemd service file `/etc/systemd/system/vantage-agent.service` and starts the agent.
|
||||
1. Checks the architecture. Only `x86_64` and `aarch64` are supported.
|
||||
2. Downloads the agent and verifies its SHA-256 checksum, stopping on a mismatch.
|
||||
3. Installs the agent to `/usr/local/bin/vantage-agent`.
|
||||
4. Writes `/etc/vantage/config.yaml` with the server ID, the enrolment token and
|
||||
the address the agent connects to.
|
||||
5. Installs and starts the `vantage-agent` systemd service.
|
||||
|
||||
### Windows
|
||||
|
||||
Run this from an elevated PowerShell prompt:
|
||||
|
||||
```powershell
|
||||
irm "https://vantage.example.com/install.ps1?server_id=<id>&token=<token>" | iex
|
||||
```
|
||||
|
||||
Run from an elevated PowerShell.
|
||||
It writes the config to `%ProgramData%\vantage\config.yaml`, installs the agent
|
||||
as a Windows service and starts it.
|
||||
|
||||
What the script does:
|
||||
|
||||
1. Creates the config at `%ProgramData%\vantage\config.yaml`.
|
||||
1. This contains the server ID, the pre-registration token and the gRPC host.
|
||||
2. Downloads the agent MSI from Gitea.
|
||||
3. Installs the MSI and creates the Windows service.
|
||||
4. Starts the agent.
|
||||
|
||||
:::info Windows agents do **not** manage `authorized_keys` as this is a Linux-only function.
|
||||
:::info Windows servers do not get SSH key management
|
||||
Windows agents register, report inventory and run workflow steps. Managing
|
||||
`authorized_keys` is a Linux-only feature.
|
||||
:::
|
||||
|
||||
## 3. Watch it come up
|
||||
|
||||
The server appears immediately as `pending`. Within one poll interval, 30 seconds it becomes `active`.
|
||||
The server appears as `pending` straight away, and becomes `active` within about
|
||||
30 seconds.
|
||||
|
||||
Check the systemd logs using the following commands:
|
||||
On Linux you can watch the agent itself:
|
||||
|
||||
```bash
|
||||
systemctl status vantage-agent
|
||||
@@ -70,28 +73,30 @@ journalctl -u vantage-agent -f
|
||||
|
||||
## 4. Confirm it works
|
||||
|
||||
Open the server's detail page. Within a minute or two you should see:
|
||||
Open the server's page. Within a minute or two you should see:
|
||||
|
||||
- Status `active`, with a recent last-seen timestamp.
|
||||
- Inventory CPU, memory, swap, partitions, kernel. Metrics refresh every 30
|
||||
seconds; the full static snapshot every 15 minutes.
|
||||
- Pending OS updates, checked hourly.
|
||||
- Status `active`, with a recent last-seen time.
|
||||
- Inventory: CPU, memory, swap, partitions and kernel. Metrics refresh every 30
|
||||
seconds, and the fuller snapshot every 15 minutes.
|
||||
- Any pending OS updates, which the agent checks for hourly.
|
||||
|
||||
## If it does not appear
|
||||
|
||||
| Symptom | Cause |
|
||||
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Script exits at "Unsupported architecture" | Not amd64 or arm64 |
|
||||
| "Checksum mismatch!" | Interrupted download, or a proxy rewriting the body. Re-run |
|
||||
| "Could not determine latest agent version" | The host cannot reach `gitea.hostxtra.co.uk`, or no `agent/v*` release exists |
|
||||
| Service runs, server stays `pending` | The machine cannot reach `GRPC_HOST`. Test it from that machine |
|
||||
| Registers once then goes `offline` | Reachable for `Register` but not for the poll usually a firewall that permits the initial connection but drops the long-lived one |
|
||||
| Symptom | What to check |
|
||||
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
|
||||
| Script stops at "Unsupported architecture" | The machine is not 64-bit x86 or ARM |
|
||||
| "Checksum mismatch!" | An interrupted download, or a proxy rewriting the response. Run it again |
|
||||
| "Could not determine latest agent version" | The machine cannot reach the release host, or `GITEA_HOST` is not set on your control plane |
|
||||
| Service runs, server stays `pending` | The machine cannot reach the agent port. Test it from that machine, not from the control plane |
|
||||
| Registers, then goes `offline` | A firewall or proxy allows the first connection but drops the long-lived one |
|
||||
| "Server limit reached" | Your licence allowance is full. Raise it in Vantage HQ, or remove a server you no longer manage |
|
||||
|
||||
A server is marked `offline` when its last-seen time passes the threshold; that
|
||||
sweep runs every two minutes, so allow for it before concluding anything.
|
||||
A server is marked `offline` once it has not been seen for a while, and that
|
||||
check runs every couple of minutes, so give it a moment before concluding
|
||||
anything.
|
||||
|
||||
## Next Steps
|
||||
## Next steps
|
||||
|
||||
- [Assign an SSH key](../vantage/ssh-keys.md)
|
||||
- [Run a workflow](../vantage/workflows.md)
|
||||
- [Claim a Free licence](./claim-free-licence.md)
|
||||
- [Watch something with a monitor](../vantage/monitors.md)
|
||||
|
||||
@@ -4,52 +4,46 @@ title: Install Vantage (self-hosted)
|
||||
sidebar_label: Self-hosted install
|
||||
---
|
||||
|
||||
This installs the control plane on a host you own. Budget about fifteen minutes.
|
||||
This puts the control plane on a host you own. Budget about fifteen minutes.
|
||||
|
||||
## Before you start
|
||||
|
||||
You need:
|
||||
|
||||
- A Linux host with **Docker** and the **Compose plugin**.
|
||||
- A DNS name pointing at it. You will use it for both the web UI and, with a
|
||||
port, for agents.
|
||||
- A reverse proxy terminating TLS in front of the web UI. gRPC on `:9090` is
|
||||
reached directly by agents.
|
||||
- Two ports reachable from every machine you intend to manage: the web port for
|
||||
people, and **9090** for agents.
|
||||
- Outbound access from the control plane, and from every managed machine, to
|
||||
`gitea.hostxtra.co.uk`, which serves the agent releases.
|
||||
- A DNS name pointing at that host. People use it for the web UI, and your
|
||||
agents use it too.
|
||||
- A reverse proxy in front of Vantage that terminates TLS. It needs to handle
|
||||
both the web UI and the agent port, `9090`, which speaks HTTP/2.
|
||||
- Those two ports reachable: the web port from wherever your people are, and
|
||||
`9090` from every machine you intend to manage.
|
||||
- Outbound access from the control plane, and from each managed machine, to
|
||||
`gitea.hostxtra.co.uk`, which serves the agent downloads.
|
||||
|
||||
The stack itself brings MongoDB, Redis and guacd with it. You do not need to
|
||||
provide a database.
|
||||
The stack brings MongoDB, Redis and the console daemon with it, so there is no
|
||||
database to provide.
|
||||
|
||||
## 1. Get the compose file
|
||||
|
||||
Put `deploy/docker-compose.yml` from the repository in a working directory, for
|
||||
example `/opt/vantage`.
|
||||
## 1. Get the Compose file
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/vantage/data && cd /opt/vantage
|
||||
# copy docker-compose.yml here
|
||||
mkdir -p /opt/vantage && cd /opt/vantage
|
||||
curl -fsSLO https://gitea.hostxtra.co.uk/mrhid6/vantage/raw/branch/main/deploy/docker/docker-compose.yml
|
||||
```
|
||||
|
||||
The `server` service bind-mounts `./data`, which is where workflow run logs are
|
||||
written. Create it before first boot so it is not owned by root-in-container in
|
||||
a way you did not intend.
|
||||
|
||||
## 2. Write the environment file
|
||||
|
||||
Create `/opt/vantage/.env`:
|
||||
|
||||
```bash
|
||||
# The host:port agents dial. NOT the web URL this port speaks gRPC.
|
||||
# The host:port your agents connect to. This is not the web URL;
|
||||
# this port speaks gRPC.
|
||||
GRPC_HOST=vantage.example.com:9090
|
||||
|
||||
|
||||
# 32 bytes as 64 hex characters. Generate with the command below.
|
||||
# 32 bytes as 64 hex characters. Generate it with the command below.
|
||||
KEY_ENCRYPTION_KEY=
|
||||
|
||||
# Optional: where workflow run logs are written inside the container.
|
||||
# The host serving agent downloads.
|
||||
GITEA_HOST=gitea.hostxtra.co.uk
|
||||
```
|
||||
|
||||
Generate the encryption key:
|
||||
@@ -58,17 +52,27 @@ Generate the encryption key:
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
:::danger Keep the encryption key
|
||||
`KEY_ENCRYPTION_KEY` encrypts SSH private keys, vault secrets, OIDC client
|
||||
secrets and console credentials with AES-256-GCM. Lose it and every one of those
|
||||
becomes unreadable there is no recovery path. Back it up somewhere other than
|
||||
the server it protects, and never rotate it without a planned re-encryption.
|
||||
Then make sure the `server` service passes `GITEA_HOST` through, by adding this
|
||||
line to its `environment:` block in `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
GITEA_HOST: ${GITEA_HOST}
|
||||
```
|
||||
|
||||
Without it, the install command you hand to a new server cannot work out which
|
||||
agent to download.
|
||||
|
||||
:::danger Keep the encryption key safe
|
||||
`KEY_ENCRYPTION_KEY` encrypts SSH private keys, vault secrets, single sign-on
|
||||
client secrets and console credentials. If you lose it, all of those become
|
||||
unreadable and there is no way to recover them. Back it up somewhere other than
|
||||
the server it protects, and do not change it once the install is in use.
|
||||
:::
|
||||
|
||||
:::warning `GRPC_HOST` has no default
|
||||
The server refuses to boot without it. There is deliberately no fallback to the
|
||||
web host: that would hand every agent a port that does not speak gRPC, and the
|
||||
failure would only surface later, on each agent, as a connection error.
|
||||
The server will not start without it. There is deliberately no fallback to your
|
||||
web address, because that port does not speak the protocol agents use, and the
|
||||
mistake would only show up later as every agent failing to connect.
|
||||
:::
|
||||
|
||||
## 3. Start the stack
|
||||
@@ -78,31 +82,37 @@ docker compose up -d
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
Five services come up: `mongo`, `redis`, `guacd`, `server` and `web`.
|
||||
Five services start: `mongo`, `redis`, `guacd`, `server` and `web`.
|
||||
|
||||
Check the server got through boot:
|
||||
Check the server got through startup:
|
||||
|
||||
```bash
|
||||
docker compose logs -f server
|
||||
```
|
||||
|
||||
Boot runs database migrations, builds indexes and seeds the default workflow
|
||||
step library. Index builders for auth and settings are **fatal on failure** —
|
||||
they enforce tenant isolation, so the server would rather not start than start
|
||||
without them.
|
||||
On first boot it prepares the database and loads the built-in workflow step
|
||||
library. If it stops during that, it will say why, and it is meant to stop
|
||||
rather than run in a half-prepared state.
|
||||
|
||||
## 4. Put a proxy in front
|
||||
|
||||
Point your reverse proxy at `web` on port `3000` and terminate TLS there. The
|
||||
web app calls the REST API through a Next rewrite, so you do not need to expose
|
||||
`8080` publicly.
|
||||
web app reaches the API internally, so there is no need to publish port `8080`.
|
||||
|
||||
Do **not** proxy `9090`. Agents connect to it directly over TLS.
|
||||
Agents connect to port `9090`. Vantage does not terminate TLS itself, so put
|
||||
that port behind your proxy too, with a certificate valid for the name in
|
||||
`GRPC_HOST`. The proxy must speak HTTP/2 through to Vantage. Many do not do so
|
||||
by default, and the symptom is agents that register once and then stop
|
||||
responding.
|
||||
|
||||
For a private network where TLS is not required, you can instead set
|
||||
`tls: false` in each [agent's config](../reference/agent-config.md) and let
|
||||
agents reach the port directly.
|
||||
|
||||
## 5. First sign-in
|
||||
|
||||
Open your hostname in a browser. With no users in the database, you are sent to
|
||||
`/setup`.
|
||||
Open your hostname in a browser. With no users in the database yet, you are sent
|
||||
to the setup page.
|
||||
|
||||
Continue with [First login](./first-login.md).
|
||||
|
||||
@@ -113,23 +123,24 @@ Continue with [First login](./first-login.md).
|
||||
| `docker compose ps` | five services `running` |
|
||||
| `curl -s localhost:8080/auth/bootstrap-status` | JSON saying bootstrap is needed |
|
||||
| `nc -z your-host 9090` | open |
|
||||
| `docker compose logs server \| grep -i fatal` | nothing |
|
||||
| `docker compose logs server` | no fatal errors |
|
||||
|
||||
## Common install problems
|
||||
|
||||
**Server exits immediately.** Almost always a missing `GRPC_HOST`. The log line
|
||||
**The server exits immediately.** Almost always a missing `GRPC_HOST`. The log
|
||||
names it.
|
||||
|
||||
**Agents register but never go active.** They reached `:9090` for `Register` but
|
||||
cannot sustain the poll, or `GRPC_HOST` names a host they resolve differently.
|
||||
Check from the managed machine, not from the control plane host.
|
||||
**Agents register but never go active.** They reached port `9090` once but
|
||||
cannot hold the connection, or your proxy is not passing HTTP/2 through. Test
|
||||
from the managed machine, not from the control plane host.
|
||||
|
||||
**Secrets pages error.** `KEY_ENCRYPTION_KEY` is empty or not 64 hex characters.
|
||||
**Secrets pages show an error.** `KEY_ENCRYPTION_KEY` is empty or is not 64 hex
|
||||
characters.
|
||||
|
||||
More in [Troubleshooting](../reference/troubleshooting.md).
|
||||
|
||||
## What this install does not include
|
||||
## What is not included
|
||||
|
||||
The website, the HQ portal and this documentation site are hosted by us and are
|
||||
not part of a self-hosted install. It deliberately runs none of them, and in
|
||||
particular never holds the licence signing key.
|
||||
The marketing site, the Vantage HQ portal and this documentation site are hosted
|
||||
by us. A self-hosted install runs none of them, and it never holds the key that
|
||||
signs licences.
|
||||
|
||||
@@ -5,59 +5,52 @@ sidebar_label: What is Vantage
|
||||
---
|
||||
|
||||
Vantage manages a fleet of servers from one place. It began as SSH key
|
||||
management and grew outwards: key assignment, scripted workflow execution,
|
||||
service monitoring, a secrets vault, a browser-based console and OS update
|
||||
management.
|
||||
management and grew outwards: key assignment, scripted workflows, service
|
||||
monitoring, a secrets vault, a browser console and OS update management.
|
||||
|
||||
## The pieces
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
W["Web UI<br/>servers · keys · workflows · monitors<br/>secrets · audit · console · settings"]
|
||||
S["Server<br/>REST :8080 · gRPC :9090<br/>MongoDB · Redis · guacd"]
|
||||
S["Vantage server<br/>the control plane"]
|
||||
A["Agent<br/>one per managed server<br/>Linux and Windows"]
|
||||
W -->|REST, cookie session| S
|
||||
S -->|gRPC over TLS| A
|
||||
A -.->|outbound only| S
|
||||
W -->|you sign in here| S
|
||||
S -->|sends work| A
|
||||
A -.->|connects outbound| S
|
||||
```
|
||||
|
||||
**The server** holds all state and does all decision-making. It exposes a REST
|
||||
API on `:8080` for the web UI and a gRPC API on `:9090` for agents. MongoDB
|
||||
stores everything durable; Redis stores sessions and nothing else.
|
||||
**The server** is the control plane. It holds all your data and makes all the
|
||||
decisions.
|
||||
|
||||
**The agent** is a single Go binary running as root on each managed server. It
|
||||
polls the control plane every 30 seconds for desired key state, and holds a
|
||||
bidirectional command stream so the server can push work run a workflow step,
|
||||
generate a key, apply updates without waiting for the next poll.
|
||||
**The agent** is a single small program running on each managed server. It asks
|
||||
the control plane what it should be doing, and holds an open connection so
|
||||
Vantage can send it work without waiting.
|
||||
|
||||
**The web UI** is the operator interface. Everything it does goes through the
|
||||
REST API, which is the actual security boundary; the UI only ever makes things
|
||||
convenient.
|
||||
**The web UI** is what you use. Everything it can do goes through the same API
|
||||
that enforces your permissions, so nothing is possible in the UI that would not
|
||||
be permitted elsewhere.
|
||||
|
||||
## How agents connect
|
||||
|
||||
The agent dials **out** to the control plane. There is no inbound listener on a
|
||||
managed server, no port to open and no NAT traversal to arrange. If the machine
|
||||
can reach your Vantage host on the gRPC port, it can be managed.
|
||||
The agent always connects **outbound**. There is no listener on a managed
|
||||
server, no port to open and no NAT to work around. If the machine can reach your
|
||||
Vantage address, it can be managed.
|
||||
|
||||
That direction is why `GRPC_HOST` exists as an explicit setting: the agent has
|
||||
to be told a `host:port` it can reach, and there is no safe default the server
|
||||
could guess on its behalf.
|
||||
That is why you tell Vantage its own agent address (`GRPC_HOST`) when you install
|
||||
it: the agent has to be given an address it can reach, and Vantage cannot guess
|
||||
one for you.
|
||||
|
||||
## Two request patterns
|
||||
## Keeping things current
|
||||
|
||||
| Pattern | Used for | Why |
|
||||
| ----------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| Poll, every 30s | desired SSH key state | Key changes are not urgent, and polling survives a dropped connection with no reconnection logic |
|
||||
| Push, over the command stream | workflow steps, key generation, updates, agent self-update | Clicking Run should not wait up to 30 seconds |
|
||||
|
||||
## Multi-tenancy
|
||||
|
||||
Every document in the database carries an instance ID, and every query is scoped
|
||||
by it. One deployment can therefore host many independent tenants. On a
|
||||
self-hosted install that mechanism is still there you simply have one tenant.
|
||||
| What | How it works |
|
||||
| ------------------------- | ------------------------------------------------------------------------- |
|
||||
| SSH keys on a server | The agent checks every 30 seconds and only writes when something changed |
|
||||
| Workflow steps, updates | Sent to the agent straight away, so clicking Run does not wait for a check |
|
||||
| Inventory | Reported every 30 seconds, with a fuller snapshot every 15 minutes |
|
||||
| Pending OS updates | Checked hourly |
|
||||
|
||||
## Next
|
||||
|
||||
- [Cloud or self-hosted](./cloud-vs-self-hosted.md) which one you want
|
||||
- [Self-hosted install](./self-hosted-install.md) stand it up
|
||||
- [Cloud or self-hosted](./cloud-vs-self-hosted.md), to pick which one you want
|
||||
- [Self-hosted install](./self-hosted-install.md), to stand it up
|
||||
|
||||
@@ -20,9 +20,9 @@ role:
|
||||
Reading is open to any signed-in member. Every mutation except changing your own
|
||||
password requires `owner` or `admin`. Billing is owner-only.
|
||||
|
||||
The three words are the same as the control plane's roles, on purpose but they
|
||||
are separate things. Your account role governs the portal; your role _inside_ an
|
||||
instance governs that instance.
|
||||
These are the same three words your instances use, but they are separate things.
|
||||
Your account role controls what you can do in the portal. Your role inside an
|
||||
instance controls what you can do there.
|
||||
|
||||
## Signing up
|
||||
|
||||
@@ -38,14 +38,19 @@ Verification links are valid for **24 hours**.
|
||||
|
||||
## Signing in
|
||||
|
||||
Use the Email and password used in the signup form to login to the HQ, signing in to HQ does not sign you in to an instance, and vice versa.
|
||||
Sign in at [Vantage HQ](https://vantage-hq.hostxtra.co.uk) with the email and
|
||||
password from the signup form.
|
||||
|
||||
HQ and your Vantage instances have separate sessions: signing in to HQ does not
|
||||
sign you in to an instance, and signing in to an instance does not sign you in
|
||||
to HQ.
|
||||
|
||||
## What comes next
|
||||
|
||||
| You want | Go to |
|
||||
| ------------------------------ | ------------------------------------------------------------- |
|
||||
| A Vantage instance we run | [Cloud instances](./cloud-instances.md) |
|
||||
| To license an install you run | [Self-hosted instances](./self-hosted-instances.md) |
|
||||
| To licence an install you run | [Self-hosted instances](./self-hosted-instances.md) |
|
||||
| To add colleagues | [People and roles](./people-and-roles.md) |
|
||||
| To understand tiers and limits | [Licensing and entitlements](./licensing-and-entitlements.md) |
|
||||
|
||||
@@ -55,4 +60,4 @@ Three destinations: **Overview**, **People**, **Billing**.
|
||||
|
||||
- Overview lists your instances.
|
||||
- People shows all the account members and their roles.
|
||||
- Billing show the current subscriptions and subscription management.
|
||||
- Billing shows your current subscriptions and lets you manage them.
|
||||
|
||||
+16
-12
@@ -12,25 +12,29 @@ customer reference and nothing sensitive.
|
||||
The Billing page requires the **owner-only** account role.
|
||||
:::
|
||||
|
||||
## Buying A Plan
|
||||
## Buying a plan
|
||||
|
||||
Buying a plan license can be found in Vantage HQ by clicking on the **Buy a Plan** button on the **Overview** page.
|
||||
In Vantage HQ, click **Buy a plan** on the **Overview** page.
|
||||
|
||||
### Cloud
|
||||
|
||||
On the **Buy A Plan** page you will need to select the **Deployment** to **Cloud** then chose your **Billing** cycle (Monthly or Annually).
|
||||
1. Set **Deployment** to **Cloud**.
|
||||
2. Choose a **Billing** cycle, monthly or annual.
|
||||
3. Choose a **Plan** and configure its features and server allowance.
|
||||
4. Enter an **Instance name** and click **Continue to payment**.
|
||||
|
||||
Then select your desired **Plan** and configure the features.
|
||||
|
||||
Finally specify the **Instance Name** and click the **Continue to payment** button.
|
||||
The instance is created and licensed as soon as payment confirms.
|
||||
|
||||
### Self-hosted
|
||||
|
||||
On the **Buy A Plan** page you will need to select the **Deployment** to **Self-Hosted** then chose your **Billing** cycle (Monthly or Annually).
|
||||
1. Set **Deployment** to **Self-hosted**.
|
||||
2. Choose a **Billing** cycle, monthly or annual.
|
||||
3. Choose a **Plan** and configure its features and server allowance.
|
||||
4. Enter an **Instance name** and click **Continue to payment**.
|
||||
|
||||
Then select your desired **Plan** and configure the features.
|
||||
|
||||
Finally specify the **Instance Name** and click the **Continue to payment** button.
|
||||
Payment creates a placeholder instance with no licence yet. You then paste your
|
||||
install's instance ID to have the licence issued. See
|
||||
[Self-hosted instances](./self-hosted-instances.md).
|
||||
|
||||
## Cancelling and failed payments
|
||||
|
||||
@@ -38,7 +42,7 @@ Cancelling, or a payment going past due, takes **no immediate licence action**.
|
||||
Your licence runs to its grace-padded expiry and then lapses normally. There is
|
||||
no mid-term cut-off.
|
||||
|
||||
For a cloud Free instance, lapsing eventually leads to deletion see
|
||||
For a cloud Free instance, lapsing eventually leads to deletion. See
|
||||
[Free tier](./free-tier.md). Paid instances are not deleted.
|
||||
|
||||
## Renewals
|
||||
@@ -47,4 +51,4 @@ At renewal the subscription bills again and the licence is reissued for the new
|
||||
term. It is also the only moment a scheduled **reduction** takes effect.
|
||||
|
||||
- Self-hosted customers: download and paste the reissued licence.
|
||||
- Cloud customers: the license is automatically linked to the instance.
|
||||
- Cloud customers: nothing to do. The licence is written to the instance for you.
|
||||
|
||||
+16
-16
@@ -9,18 +9,19 @@ A cloud instance is a Vantage control plane we run for you, reachable at
|
||||
|
||||
## Creating one
|
||||
|
||||
1. **Overview → New instance**.
|
||||
2. Choose a name and a slug.
|
||||
3. Create.
|
||||
1. On **Overview**, choose **Create a cloud instance**. Once you already have an
|
||||
instance, the same page offers **Buy a plan** instead.
|
||||
2. Choose **Cloud**, then the plan you want.
|
||||
3. Give the instance a name and confirm.
|
||||
|
||||
The instance is provisioned with you as its owner, and a Free licence is issued
|
||||
immediately. The owner user inside it gets your HQ password hash **copied**, not
|
||||
shared see [People and roles](./people-and-roles.md).
|
||||
immediately. Your Vantage HQ password gets you into it, though the two are kept
|
||||
in step rather than shared. See [People and roles](./people-and-roles.md).
|
||||
|
||||
### Slugs
|
||||
|
||||
The slug becomes your hostname label, so it is lowercase, and some names are
|
||||
reserved. Pick something you can say on a phone call.
|
||||
Your instance's address comes from the name you choose, lowercased, with some
|
||||
names reserved. Pick something short that you can say on a phone call.
|
||||
|
||||
:::warning One Free instance per account, per deployment
|
||||
Creating a second Free cloud instance is refused. If you want another, it needs
|
||||
@@ -41,9 +42,9 @@ affect anyone signing in or any agent syncing.
|
||||
|
||||
Each instance on Overview is one record. Closed, it is a row. Open, it shows:
|
||||
|
||||
- **Licence contents** tier, server allowance, features, expiry.
|
||||
- **Members** who has access and with what instance role.
|
||||
- **Actions** grant access, change configuration, renew.
|
||||
- **Licence contents**: tier, server allowance, features and expiry.
|
||||
- **Members**: who has access, and with what role.
|
||||
- **Actions**: grant access, change configuration, renew.
|
||||
|
||||
## Members
|
||||
|
||||
@@ -53,14 +54,15 @@ Granting access writes a real user into the instance. Covered fully in
|
||||
## Changing what it can do
|
||||
|
||||
Server allowance and per-instance features (browser console, single sign-on) are
|
||||
part of the instance's **entitlement**. Changing it goes through billing see
|
||||
part of the instance's **entitlement**, the configuration your licence is cut
|
||||
from. Changing it goes through billing. See
|
||||
[Licensing and entitlements](./licensing-and-entitlements.md) and
|
||||
[Billing](./billing.md).
|
||||
|
||||
## Renaming
|
||||
|
||||
The display name is free to change. The slug is the hostname and is not
|
||||
casually changed ask support if you need it.
|
||||
The display name is free to change. The slug is part of your hostname, so ask
|
||||
support if you need that changed.
|
||||
|
||||
## What happens if the licence lapses
|
||||
|
||||
@@ -73,6 +75,4 @@ runs to its grace-padded expiry and then lapses.
|
||||
|
||||
## Deleting
|
||||
|
||||
Ask support. Deletion is performed by the control plane, not by HQ the control
|
||||
plane is the only service that knows which collections carry the instance ID,
|
||||
and duplicating that list into HQ would be a list that drifts.
|
||||
Ask support.
|
||||
|
||||
+9
-15
@@ -4,7 +4,8 @@ title: Free tier
|
||||
sidebar_label: Free tier
|
||||
---
|
||||
|
||||
Free is a real tier in both deployments not a trial that turns into nothing.
|
||||
Free is a permanent tier. It is available whether we host Vantage for you or you
|
||||
host it yourself.
|
||||
|
||||
## What you get
|
||||
|
||||
@@ -23,16 +24,15 @@ features on a paid plan.
|
||||
## One per account, per deployment
|
||||
|
||||
The limit is enforced per account **and** deployment. A Free cloud instance does
|
||||
not prevent a Free self-hosted one they are separate slots.
|
||||
not prevent a Free self-hosted one; they are separate slots.
|
||||
|
||||
## Renewing
|
||||
|
||||
Free licences have a term and must be renewed from the portal.
|
||||
Free licences run for a year and are renewed from the portal.
|
||||
|
||||
- The renew button appears **7 days before expiry**.
|
||||
- It stays available **after** expiry, right up until the instance is reaped —
|
||||
so the same button rescues a lapsed instance rather than needing a second
|
||||
mechanism.
|
||||
- It stays available **after** expiry, right up until a lapsed cloud instance is
|
||||
deleted, so the same button rescues one.
|
||||
- Renewing outside that window is refused, and the message names the date it
|
||||
opens.
|
||||
|
||||
@@ -55,19 +55,13 @@ There is no restore. If a cloud Free instance is approaching that date and you
|
||||
want to keep it, renew it, or move it to a paid plan.
|
||||
:::
|
||||
|
||||
Deletion is carried out by the control plane rather than by HQ. HQ sends the
|
||||
warnings because it knows the billing address; the control plane performs the
|
||||
delete because it is the only service that knows which collections carry the
|
||||
instance ID.
|
||||
|
||||
## Moving off Free
|
||||
|
||||
Change the instance's configuration to a paid tier and check out. Your data
|
||||
stays where it is a tier change reissues a licence, it does not rebuild
|
||||
stays where it is: a tier change reissues a licence, it does not rebuild
|
||||
anything.
|
||||
|
||||
## Relinks
|
||||
|
||||
Free instances get the same relink allowance as paid ones: three per term. That
|
||||
cap exists to put a human in front of a fourth attempt, not to obstruct a
|
||||
genuine rebuild.
|
||||
Free instances get the same allowance as paid ones: three relinks per term. If
|
||||
you genuinely need more, ask support.
|
||||
|
||||
@@ -10,7 +10,7 @@ A **licence** is a signed statement of what one instance may do. An
|
||||
## Tiers
|
||||
|
||||
Three tiers, in both deployments. The allowances are identical across cloud and
|
||||
self-hosted what differs is the term on offer, not what you get.
|
||||
self-hosted; what differs is the term on offer, not what you get.
|
||||
|
||||
| | Free | Professional | Enterprise |
|
||||
| --------------------- | --------- | ------------ | --------------------- |
|
||||
@@ -23,17 +23,18 @@ self-hosted what differs is the term on offer, not what you get.
|
||||
|
||||
The server count is **metered**: the base allowance comes with the tier, and you
|
||||
buy additional servers on top. That is why Professional shows a real number
|
||||
rather than "unlimited" the number you actually have is the one in your
|
||||
rather than "unlimited": the number you actually have is the one in your
|
||||
entitlement.
|
||||
|
||||
## Features
|
||||
|
||||
Two are per-instance toggles rather than tier bundles:
|
||||
Three features are enabled per instance rather than bundled into a tier:
|
||||
|
||||
| Feature | What it enables |
|
||||
| --------- | -------------------------------------------------------------------- |
|
||||
| `console` | The [browser console](../vantage/browser-console.md) |
|
||||
| `oidc` | Per-instance [single sign-on](../vantage/settings.md#single-sign-on) |
|
||||
| Browser console | The [browser console](../vantage/browser-console.md) |
|
||||
| Single sign-on | [Sign-in through your identity provider](../vantage/settings.md#single-sign-on) |
|
||||
| Vulnerability scanning| [Package vulnerability scanning](../vantage/vulnerabilities.md) |
|
||||
|
||||
No tier includes them by default; you enable them on the instances that need
|
||||
them.
|
||||
@@ -62,26 +63,35 @@ happens at renewal.
|
||||
|
||||
## What a licence carries
|
||||
|
||||
Instance UUID, deployment, tier, resolved limits, features, term and expiry —
|
||||
all signed.
|
||||
Your instance ID, whether it is cloud or self-hosted, the tier, your limits,
|
||||
which features are enabled, and when it expires. All of it is signed.
|
||||
|
||||
Two properties follow from that:
|
||||
|
||||
- **A licence is bound to one instance UUID.** Moving it takes a
|
||||
[relink](./self-hosted-instances.md#relinking).
|
||||
- **A licence is a snapshot.** Editing a plan later never rewrites an issued
|
||||
licence, the same way editing a workflow step never rewrites a past run.
|
||||
- **A licence works for one instance only.** Moving it to a rebuilt install
|
||||
takes a [relink](./self-hosted-instances.md#relinking).
|
||||
- **A licence is a snapshot.** Changing a plan later does not rewrite a licence
|
||||
already issued.
|
||||
|
||||
Verification is local. Your instance does not call HQ to check a licence, and
|
||||
signing happens only in HQ.
|
||||
|
||||
## Expiry and grace
|
||||
## Expiry, grace and degraded mode
|
||||
|
||||
Expiry is padded with a grace period. Past that, the instance goes into degraded
|
||||
mode: it keeps running and keeps your data, but stops letting you do everything.
|
||||
Expiry is padded with a few days' grace. Past that, an instance goes into
|
||||
**degraded mode**, which means:
|
||||
|
||||
The way out is a current licence renew or purchase, then paste it (self-hosted)
|
||||
or let it be written for you (cloud).
|
||||
- It keeps running, and all of your data stays exactly where it is.
|
||||
- You can still sign in and read everything.
|
||||
- Adding or changing anything is refused.
|
||||
- Deleting things still works, so you can get back under a reduced allowance.
|
||||
- Applying OS updates still works, because security patching is never blocked.
|
||||
|
||||
A brand-new self-hosted install behaves the same way until you install its first
|
||||
licence.
|
||||
|
||||
The way out is a current licence: renew or purchase, then paste it
|
||||
(self-hosted) or let it be written for you (cloud).
|
||||
|
||||
## Server limits in practice
|
||||
|
||||
|
||||
+24
-31
@@ -26,14 +26,11 @@ Owners and admins invite; billing is owner-only.
|
||||
3. They receive a link and set their own password at `/accept-invite`.
|
||||
|
||||
:::info Why you cannot set their password
|
||||
An invitation creates a person with an **empty password hash**, which cannot
|
||||
authenticate at all until they set one. If the inviter chose it, that password
|
||||
would be a shared credential to every instance the person is later granted
|
||||
access to.
|
||||
An invited person cannot sign in at all until they set their own password. If
|
||||
you chose it for them, it would be a shared password to every instance they are
|
||||
later given access to.
|
||||
|
||||
The verification endpoint knows the difference: a token belonging to a
|
||||
passwordless person reports that a password is needed and is left unspent, so
|
||||
the link still works when they get to it.
|
||||
Their invitation link stays valid until they use it to set that password.
|
||||
:::
|
||||
|
||||
### Removing someone
|
||||
@@ -43,26 +40,26 @@ happens to their instance access.
|
||||
|
||||
## Instance access
|
||||
|
||||
Granting access to a **cloud** instance creates a real user inside that
|
||||
instance's control plane, with `auth_source: "hq"`.
|
||||
Granting access to a **cloud** instance creates a real account inside that
|
||||
instance, marked as managed by Vantage HQ.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
P["HQ account member"] -->|grant| U["Control-plane user<br/>auth_source: hq"]
|
||||
U --> I["The instance authenticates<br/>this user like any other"]
|
||||
P["Person in your Vantage HQ account"] -->|you grant access| U["Account inside the instance"]
|
||||
U --> I["They sign in at the instance,<br/>like anyone else"]
|
||||
```
|
||||
|
||||
The instance authenticates that user exactly as it authenticates anyone else,
|
||||
with **no runtime dependency on HQ**. Revoking deletes the row the control
|
||||
plane has no disabled state, and a row that exists is a row that can sign in.
|
||||
They then sign in at the instance itself, and that keeps working whether or not
|
||||
Vantage HQ is reachable. Revoking removes the account outright, so access ends
|
||||
immediately.
|
||||
|
||||
### Granting
|
||||
|
||||
On an instance record, **Members → Add**, choose an account member and an
|
||||
instance role (`owner`, `admin`, `member`).
|
||||
|
||||
One person holds at most one user per instance, so granting twice is refused
|
||||
rather than quietly creating a second user.
|
||||
One person gets one account per instance, so granting twice is refused rather
|
||||
than quietly creating a second.
|
||||
|
||||
### Roles inside an instance
|
||||
|
||||
@@ -71,28 +68,24 @@ instance `owner`, or the reverse.
|
||||
|
||||
### Revoking
|
||||
|
||||
Removes the user from the instance immediately. Any live session ends with the
|
||||
session, since the user row backing it is gone.
|
||||
Removes their access immediately, and ends any session they have open.
|
||||
|
||||
:::warning Self-hosted instances cannot be granted from HQ
|
||||
All three member endpoints refuse when the instance is self-hosted. Manage those
|
||||
users in the instance itself, at **Settings → Access**.
|
||||
Vantage HQ cannot add or remove people in a self-hosted install. Manage them in
|
||||
the install itself, at **Settings → Access**.
|
||||
:::
|
||||
|
||||
## Passwords
|
||||
|
||||
Your HQ password is the single source of truth for every user projected from it.
|
||||
Changing it in the portal rehashes it and copies the hash to every instance you
|
||||
have been granted.
|
||||
One Vantage HQ password covers you and every cloud instance you have been given
|
||||
access to. Change it in the portal and it changes everywhere, within about 15
|
||||
minutes at worst if an instance is briefly unreachable.
|
||||
|
||||
Propagation is best-effort and immediate; a background pass compares and repairs
|
||||
every 15 minutes, so a temporarily unreachable instance catches up on its own.
|
||||
|
||||
There is no local password-change endpoint for those users in the control plane,
|
||||
so there is never a second writer for the hash.
|
||||
Those people cannot change that password inside an instance, so there is only
|
||||
ever one place it is set.
|
||||
|
||||
:::warning HQ-managed users are read-only in the instance
|
||||
Changing the role of, or deleting, an `hq`-sourced user inside the control plane
|
||||
is refused with `409`. Do it from the portal. The UI shows those rows read-only
|
||||
with a link back here, but the API is the boundary; the UI is the courtesy.
|
||||
Changing the role of, or removing, someone managed by Vantage HQ has to be done
|
||||
from the portal. Inside the instance those rows are read-only, with a link back
|
||||
here.
|
||||
:::
|
||||
|
||||
@@ -19,54 +19,57 @@ buying in order to build it.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Buy in HQ"] --> B["Placeholder instance<br/>awaiting_link, no licence"]
|
||||
B --> C["Install Vantage<br/>get its instance UUID"]
|
||||
C --> D["Paste the UUID<br/>claim-link"]
|
||||
D --> E["Licence issued<br/>bound to that UUID"]
|
||||
A["Buy in Vantage HQ"] --> B["Placeholder instance<br/>no licence yet"]
|
||||
B --> C["Install Vantage<br/>find its instance ID"]
|
||||
C --> D["Paste your install's ID"]
|
||||
D --> E["Licence issued<br/>for that instance"]
|
||||
```
|
||||
|
||||
1. **Overview → Buy self-hosted**, choose tier, term and configuration.
|
||||
2. Complete checkout. HQ creates a **placeholder** instance in state
|
||||
`awaiting_link` with no licence attached.
|
||||
1. On **Overview**, choose **License my own install**, or **Buy a plan** if you
|
||||
already have an instance. Pick **Self-hosted**, then your tier, billing cycle
|
||||
and configuration.
|
||||
2. Complete checkout. Vantage HQ creates a **placeholder** instance, waiting to
|
||||
be linked, with no licence yet.
|
||||
3. [Install Vantage](../getting-started/self-hosted-install.md) if you have not
|
||||
already, and find its instance UUID at **Settings → Licence**.
|
||||
4. Back in HQ, open the placeholder and paste the UUID.
|
||||
5. The licence is issued, bound to that UUID. Download it and paste it into your
|
||||
install.
|
||||
already, and find its instance ID on the **Licence** page.
|
||||
4. Back in Vantage HQ, open the placeholder and paste that ID.
|
||||
5. The licence is issued. Download it and paste it into your install.
|
||||
|
||||
:::info Why there is a placeholder at all
|
||||
A licence binds to an instance UUID, and at the moment of payment that UUID may
|
||||
not exist yet. Issuing early would mean issuing to nothing; refusing to sell
|
||||
until you had installed would be the wrong order. The placeholder holds the
|
||||
purchase until there is something to bind to.
|
||||
:::info Why there is a placeholder
|
||||
A licence is issued to one instance, and at the moment you pay, that install may
|
||||
not exist yet. The placeholder holds your purchase until it does.
|
||||
:::
|
||||
|
||||
## Linking an existing install
|
||||
## Linking an install you already have
|
||||
|
||||
If the install already exists, **Link an instance** takes the UUID directly. A
|
||||
UUID already claimed by another account is refused with a conflict.
|
||||
If the install exists before the purchase, the flow is the same: buy, then open
|
||||
the placeholder from **Overview**, choose **Link install** and paste its instance
|
||||
ID. An ID already claimed by another account is refused.
|
||||
|
||||
For a Free licence there is no placeholder step. See
|
||||
[Claim a Free licence](../getting-started/claim-free-licence.md).
|
||||
|
||||
## Relinking
|
||||
|
||||
Rebuilding the host produces a new instance UUID, and the old licence no longer
|
||||
matches. **Relink** moves the licence to the new UUID and reissues.
|
||||
Rebuilding the host gives you a new instance ID, which your old licence does not
|
||||
match. **Relink** moves the licence across and reissues it.
|
||||
|
||||
The number of relinks per term is capped, and the portal shows how many you have
|
||||
left. This is not meant to obstruct disaster recovery if you have exhausted
|
||||
them for a real reason, ask support.
|
||||
left. If you have used them all for a genuine reason, ask support.
|
||||
|
||||
## Installing the licence
|
||||
|
||||
Paste it at **Settings → Licence** in your install. The instance verifies the
|
||||
signature and checks that the UUID matches its own.
|
||||
Paste it on the **Licence** page in your install. It confirms the licence was
|
||||
issued to that instance before applying it.
|
||||
|
||||
Pasting works even while the current licence is expired that endpoint is
|
||||
exempt from the licence check, because it is the route out of degraded mode.
|
||||
Pasting works even while your current licence has expired, because that is how
|
||||
you get out of degraded mode.
|
||||
|
||||
## Keeping it current
|
||||
|
||||
Your install does not fetch licences. When a licence is reissued renewal,
|
||||
configuration change, relink download the new one from HQ and paste it in.
|
||||
Your install never downloads a licence by itself. Whenever one is reissued, on
|
||||
renewal, on a configuration change or after a relink, download it from Vantage
|
||||
HQ and paste it in.
|
||||
|
||||
:::warning Nothing reminds your install
|
||||
The control plane knows only what its licence says. Expiry emails come from HQ,
|
||||
|
||||
+6
-4
@@ -7,9 +7,9 @@ slug: /
|
||||
|
||||
# Vantage documentation
|
||||
|
||||
Vantage is a self-hosted, multi-tenant infrastructure control plane. It manages
|
||||
SSH keys, runs scripted workflows, watches services, stores secrets, opens
|
||||
browser consoles and applies OS updates across a fleet of servers.
|
||||
Vantage manages a fleet of servers from one place: SSH keys, scripted workflows,
|
||||
service monitoring, a secrets vault, browser consoles and OS updates. Run it
|
||||
yourself, or let us run it for you.
|
||||
|
||||
A central server drives a lightweight agent installed on each managed machine.
|
||||
The agent connects **outbound only**, so managed servers need no inbound
|
||||
@@ -20,14 +20,16 @@ firewall holes.
|
||||
| If you want to | Read |
|
||||
| --------------------------------------- | --------------------------------------------------------------- |
|
||||
| Understand what the pieces are | [What is Vantage](./getting-started/what-is-vantage.md) |
|
||||
| Decide who should run it | [Cloud or self-hosted](./getting-started/cloud-vs-self-hosted.md) |
|
||||
| Run it on your own hardware | [Self-hosted install](./getting-started/self-hosted-install.md) |
|
||||
| Licence a self-hosted install | [Claim a Free licence](./getting-started/claim-free-licence.md) |
|
||||
| Enrol your first machine | [Add your first server](./getting-started/first-server.md) |
|
||||
| Manage your account, licence or billing | [Vantage HQ](./hq/accounts-and-signup.md) |
|
||||
| Look something up | [Reference](./reference/environment-variables.md) |
|
||||
|
||||
## The two products
|
||||
|
||||
**Vantage** is the control plane the thing you sign in to in order to manage
|
||||
**Vantage** is the control plane, the thing you sign in to in order to manage
|
||||
servers. It runs either on your own infrastructure or as a cloud instance we
|
||||
run for you.
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ Each server's detail page shows the version it reported at its last sync.
|
||||
|
||||
## Updating from the UI
|
||||
|
||||
**Servers → _a server_ → Update agent** pushes `UpdateAgentCmd` with a target
|
||||
version. The agent then:
|
||||
Open a server and choose **Update agent**. The agent then:
|
||||
|
||||
1. Downloads the binary for its platform from the release.
|
||||
2. Verifies the SHA-256 against `checksums.txt`.
|
||||
@@ -35,8 +34,8 @@ irm https://vantage.example.com/update.ps1 | iex
|
||||
```
|
||||
|
||||
It does the same download, checksum and replace, then restarts the service. Use
|
||||
this when the control plane cannot push for example, when the machine is
|
||||
reachable but its command stream is not.
|
||||
this when Vantage cannot reach the agent to push the update, but you can still
|
||||
reach the machine.
|
||||
|
||||
## Rolling out across a fleet
|
||||
|
||||
@@ -54,9 +53,8 @@ Do one, confirm it returns to `active`, then do the rest.
|
||||
|
||||
## Version compatibility
|
||||
|
||||
The agent API is versioned to tolerate an agent older than the control plane. The
|
||||
reverse an agent newer than the control plane is not a case anyone tests.
|
||||
Upgrade the control plane first.
|
||||
An agent older than your control plane is supported. An agent newer than it is
|
||||
not, so upgrade the control plane first.
|
||||
|
||||
Agents report their version on every poll, so a fleet running mixed
|
||||
versions is visible in the server list rather than something you have to go
|
||||
|
||||
@@ -11,9 +11,8 @@ either one restores to something unusable.
|
||||
|
||||
| Store | Contents | Back up |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
|
||||
| MongoDB | Everything durable servers, keys, assignments, workflows, runs, monitors, incidents, secrets, settings, audit | **Yes** |
|
||||
| MongoDB | Everything durable: servers, keys, assignments, workflows, runs and their logs, monitors, incidents, secrets, settings, audit | **Yes** |
|
||||
| Redis | Sessions only | No. Losing it signs everyone out and nothing else |
|
||||
| `./data` bind mount | Workflow run logs | Optional |
|
||||
| `KEY_ENCRYPTION_KEY` | Not stored anywhere by the app | **Yes, separately** |
|
||||
|
||||
:::danger The database alone is not a backup
|
||||
@@ -50,7 +49,7 @@ nothing writes during the restore.
|
||||
cp /opt/vantage/.env /secure-location/vantage.env
|
||||
```
|
||||
|
||||
Treat it as a credential in its own right it holds the encryption key.
|
||||
Treat it as a credential in its own right, since it holds the encryption key.
|
||||
|
||||
## What a restore gives you
|
||||
|
||||
@@ -62,7 +61,7 @@ What it does **not** do is reconcile the world. After a restore:
|
||||
- Agents reconnect with their existing tokens, since the token hashes are in the
|
||||
database.
|
||||
- If the restore is older than an enrolment, that server's token hash is missing
|
||||
and the agent will fail to authenticate re-enrol it.
|
||||
and the agent will fail to authenticate. Re-enrol it.
|
||||
- The next agent poll rewrites `authorized_keys` to match the restored desired
|
||||
state, which may remove keys added since the backup.
|
||||
|
||||
@@ -74,8 +73,8 @@ What it does **not** do is reconcile the world. After a restore:
|
||||
| Environment file | On change, held in a password manager or secret store |
|
||||
| Restore rehearsal | Occasionally, into a throwaway host |
|
||||
|
||||
The rehearsal is the part that gets skipped and the part that finds the
|
||||
problems.
|
||||
Rehearse a restore now and again. It is the step most often skipped, and the one
|
||||
that finds the problems.
|
||||
|
||||
## Cloud instances
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ sidebar_label: Upgrading
|
||||
---
|
||||
|
||||
Upgrading the control plane is a pull and a recreate. Agents are versioned and
|
||||
upgraded separately see [Agent updates](./agent-updates.md).
|
||||
upgraded separately. See [Agent updates](./agent-updates.md).
|
||||
|
||||
:::info Cloud instances upgrade themselves
|
||||
This page is for self-hosted installs. If your instance is hosted by us, there
|
||||
@@ -26,11 +26,11 @@ renamed or removed.
|
||||
|
||||
## What happens on boot
|
||||
|
||||
1. **Migrations** run, recording markers so each runs once.
|
||||
2. **Indexes** are ensured. Auth and settings index builders are fatal on
|
||||
failure; secret and workflow ones only warn.
|
||||
3. **Default steps** are reseeded from the image, overwriting the `default`
|
||||
library which is why those steps are read-only.
|
||||
1. The database is brought up to date. Each change runs once.
|
||||
2. The built-in workflow steps are reinstalled, which is why those steps cannot
|
||||
be edited.
|
||||
|
||||
If Vantage cannot complete either safely, it stops rather than run half-prepared.
|
||||
|
||||
Watch it:
|
||||
|
||||
@@ -46,6 +46,16 @@ docker compose logs -f server
|
||||
- **Check your `.env`** still supplies everything required. A newly required
|
||||
variable stops the boot rather than defaulting to something unsafe.
|
||||
|
||||
## Single sign-on after an upgrade
|
||||
|
||||
Each identity provider now has its own callback URL. If you configured single
|
||||
sign-on on an older version it was carried over, but its callback URL changed,
|
||||
and sign-in through it fails until you copy the new one from its card in
|
||||
**Settings** and register it with your identity provider. The card shows a
|
||||
reminder until you dismiss it.
|
||||
|
||||
Password sign-in is unaffected, so you can always sign in locally to fix this.
|
||||
|
||||
## Downgrading
|
||||
|
||||
There is no automatic downgrade. Migrations do not roll back, so returning to an
|
||||
@@ -57,7 +67,7 @@ is the reason the backup is not optional.
|
||||
The stack is not designed for it. `docker compose up -d` recreates the server
|
||||
container, which is a short interruption:
|
||||
|
||||
- Agents reconnect on their own they retry, and the poll loop is idempotent.
|
||||
- Agents reconnect on their own.
|
||||
- Workflow runs in progress lose their command stream. Steps already dispatched
|
||||
finish on the agent, but their results have nowhere to go. **Do not upgrade
|
||||
during a run.**
|
||||
@@ -67,5 +77,4 @@ container, which is a short interruption:
|
||||
|
||||
- Confirm every service is `running`.
|
||||
- Confirm servers return to `active` within a couple of poll intervals.
|
||||
- Open a page that touches encryption a secret group to confirm
|
||||
`KEY_ENCRYPTION_KEY` came through.
|
||||
- Open a secret group, to confirm `KEY_ENCRYPTION_KEY` came through.
|
||||
|
||||
@@ -20,15 +20,15 @@ Directory `0700`, file `0600`. The install script sets both.
|
||||
```yaml
|
||||
server_url: "vantage.yourdomain.com:9090"
|
||||
server_id: "<uuid>"
|
||||
pre_reg_token: "<token>" # removed after the first successful Register()
|
||||
agent_token: "" # written by the agent after Register()
|
||||
pre_reg_token: "<token>" # cleared once the agent has registered
|
||||
agent_token: "" # written by the agent when it registers
|
||||
poll_interval: 30s
|
||||
tls: true
|
||||
```
|
||||
|
||||
| Field | Meaning |
|
||||
| --------------- | --------------------------------------------------------------------- |
|
||||
| `server_url` | `host:port` of the gRPC endpoint. Comes from the server's `GRPC_HOST` |
|
||||
| `server_url` | The `host:port` the agent connects to. Comes from your `GRPC_HOST` |
|
||||
| `server_id` | The identity issued when the enrolment was created |
|
||||
| `pre_reg_token` | Single-use, one hour. Cleared once registration succeeds |
|
||||
| `agent_token` | The permanent credential, written by the agent itself |
|
||||
@@ -36,8 +36,8 @@ tls: true
|
||||
| `tls` | Whether to use TLS. Leave `true` |
|
||||
|
||||
:::danger This file is the credential
|
||||
`agent_token` is plaintext here and nowhere else the control plane holds only
|
||||
its SHA-256. Anyone who can read this file can act as this agent.
|
||||
`agent_token` exists in full only in this file. Anyone who can read it can act
|
||||
as this agent.
|
||||
:::
|
||||
|
||||
## Service management
|
||||
@@ -77,5 +77,5 @@ rm -rf /etc/vantage
|
||||
systemctl daemon-reload
|
||||
```
|
||||
|
||||
Keys already written to `authorized_keys` remain on disk the agent is no
|
||||
longer running to remove them. Revoke first if that matters.
|
||||
Keys already written to `authorized_keys` remain on disk, because the agent is
|
||||
no longer running to remove them. Revoke first if that matters.
|
||||
|
||||
@@ -13,16 +13,18 @@ it is absent.
|
||||
| -------------------------- | --------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `GRPC_HOST` | **yes** | | The `host:port` agents dial. Boot fails without it. There is deliberately no fallback to the web host: that would hand every agent a port that does not speak gRPC |
|
||||
| `MONGO_URI` | no | `mongodb://localhost:27017` | The database name is taken from the URI path, falling back to `vantage`. There is no separate `MONGO_DB` |
|
||||
| `REDIS_ADDR` | no | `localhost:6379` | Sessions, and the bus that routes agent commands between server replicas. Every replica must point at the **same** Redis |
|
||||
| `REDIS_ADDR` | no | `localhost:6379` | Where sessions are held. If you run more than one copy of Vantage, they must all point at the same Redis |
|
||||
| `REDIS_USERNAME` | no | | Redis 6+ ACL user. Leave empty against a legacy `requirepass` instance, which authenticates with the password alone |
|
||||
| `REDIS_PASSWORD` | no | | Leave empty for an unauthenticated Redis. Both of these exist so an install can use a managed Redis rather than the bundled one |
|
||||
| `KEY_ENCRYPTION_KEY` | yes in practice | | 64 hex characters (32 bytes) for AES-256-GCM. Required for private keys, vault secrets, OIDC client secrets and console credentials |
|
||||
| `GITEA_HOST` | yes | `gitea.example.com` | Used to build the install scripts and agent download URLs. The default is a placeholder that will not resolve |
|
||||
| `GITEA_HOST` | yes in practice | `gitea.example.com` | Host serving agent releases; used to build the install scripts and download URLs. The default is a placeholder that will not resolve, so set it to `gitea.hostxtra.co.uk` |
|
||||
| `GUACD_ADDR` | no | `guacd:4822` | The [browser console](../vantage/browser-console.md) daemon |
|
||||
| `PROXY_ADVERTISE_HOST` | no | `server` | The hostname **guacd** uses to reach the control plane's console relay. Wrong here and every console session fails at connect with guacd unable to resolve the relay |
|
||||
| `PROXY_LISTEN_HOST` | no | `0.0.0.0` | Interface the ephemeral relay listeners bind. Narrow it only if guacd shares a known interface |
|
||||
| `POD_IP` | no | | Kubernetes only, set by the Helm chart from the downward API. Overrides `PROXY_ADVERTISE_HOST`, because a console relay belongs to one replica and a Service address names all of them |
|
||||
| `APP_ROOT_LABEL` | no | `vantage` | The app root label for the host and session organisation guard |
|
||||
| `APP_ROOT_LABEL` | no | `vantage` | The label Vantage expects in its own hostname, used to match a browser session to the right instance |
|
||||
| `VANTAGE_LICENSE` | no | | A licence supplied at startup, so an automated install does not have to paste one in |
|
||||
| `VANTAGE_TRIVY_DB_REF` | no | `ghcr.io/aquasecurity/trivy-db:2` | Where the vulnerability database is pulled from. Point it at a mirror for an air-gapped install |
|
||||
| `VANTAGE_VULNDB_DISABLED` | no | | `true` switches [vulnerability scanning](../vantage/vulnerabilities.md) off entirely. Findings already stored are still served, and still shown as stale |
|
||||
|
||||
:::danger `KEY_ENCRYPTION_KEY` has no recovery path
|
||||
It encrypts SSH private keys, vault secrets, OIDC client secrets and console
|
||||
@@ -38,8 +40,8 @@ protecting anything.
|
||||
### Not configurable
|
||||
|
||||
The HTTP port (`8080`) and the gRPC port (`9090`) are fixed in the server. The
|
||||
`HTTP_PORT` and `GRPC_PORT` entries in the shipped Compose file are inert —
|
||||
remap with Docker's port publishing instead.
|
||||
`HTTP_PORT` and `GRPC_PORT` entries in the shipped Compose file have no effect.
|
||||
Remap the ports with Docker instead.
|
||||
|
||||
## Agent
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@ sidebar_label: Ports and networking
|
||||
| Port | Service | Who connects | Expose publicly |
|
||||
| ------- | ----------- | -------------------------------- | --------------- |
|
||||
| `3000` | web | Browsers, via your reverse proxy | Yes, behind TLS |
|
||||
| `8080` | server REST | The web app | No |
|
||||
| `8080` | server API | The web app | No, firewall it |
|
||||
| `9090` | server gRPC | Agents | **Yes** |
|
||||
| `4822` | guacd | The server | No |
|
||||
| `4822` | guacd | The server | No, firewall it |
|
||||
| `27017` | MongoDB | The server | No |
|
||||
| `6379` | Redis | The server | No |
|
||||
|
||||
@@ -35,11 +35,10 @@ NAT is not an obstacle. The only requirement is that the machine can reach
|
||||
`GRPC_HOST`.
|
||||
|
||||
**The console rides the agent's connection too.** guacd never dials the target
|
||||
directly; the server pushes a command down the agent's existing outbound gRPC
|
||||
stream on `9090`, and the agent relays the protocol traffic from its own
|
||||
loopback. No route from the control plane to the target's address is needed,
|
||||
and no new inbound port opens on the target — the same connection that carries
|
||||
key sync carries console traffic. This is what makes the console work for a
|
||||
directly. Vantage sends the request down the connection the agent already holds
|
||||
on port `9090`, and the agent connects to the service locally on that machine. No route from the control plane to the target's address is needed,
|
||||
and no new inbound port opens on the target. The same connection that keeps keys
|
||||
in sync carries console traffic, which is what makes the console work for a
|
||||
machine behind NAT on a private subnet, as long as its agent is online.
|
||||
|
||||
## What to open
|
||||
@@ -55,8 +54,8 @@ machine behind NAT on a private subnet, as long as its agent is online.
|
||||
- Anything a server-run [monitor](../vantage/monitors.md) checks.
|
||||
- SMTP, if you use an SMTP notification channel.
|
||||
|
||||
No route to the machines you intend to console is needed — that traffic rides
|
||||
the agent's existing outbound `9090` connection instead.
|
||||
No route to the machines you intend to console is needed. That traffic uses the
|
||||
connection the agent already holds.
|
||||
|
||||
### Outbound from a managed machine
|
||||
|
||||
@@ -68,14 +67,17 @@ the agent's existing outbound `9090` connection instead.
|
||||
|
||||
Terminate TLS for the web UI at your reverse proxy.
|
||||
|
||||
gRPC on `9090` is reached directly by agents with `tls: true`, so that port needs
|
||||
a valid certificate for the name in `GRPC_HOST`. If you proxy it, the proxy must
|
||||
speak HTTP/2 end to end many do not by default, and the symptom is agents that
|
||||
register and then fail to hold the command stream.
|
||||
Vantage does not terminate TLS itself, so port `9090` needs the same treatment:
|
||||
put it behind your proxy with a certificate valid for the name in `GRPC_HOST`.
|
||||
The proxy has to pass HTTP/2 through to Vantage. Many do not do that by default,
|
||||
and the symptom is agents that register once and then stop responding.
|
||||
|
||||
On a private network you can skip TLS instead, by setting `tls: false` in each
|
||||
[agent's config](./agent-config.md).
|
||||
|
||||
## Reverse proxy notes
|
||||
|
||||
- Point the proxy at `web:3000`. The web app reaches the REST API internally, so
|
||||
- Point the proxy at `web:3000`. The web app reaches the API internally, so
|
||||
`8080` does not need publishing.
|
||||
- The console uses a **WebSocket** at `/api/console/tunnel`. A proxy that does
|
||||
not forward upgrade headers breaks the console and nothing else.
|
||||
@@ -85,8 +87,8 @@ register and then fail to hold the command stream.
|
||||
## Air-gapped and restricted networks
|
||||
|
||||
The control plane needs outbound access to fetch agent releases. Managed
|
||||
machines need it too, unless you distribute the agent binary yourself and write
|
||||
the config by hand the install script's only job is to do those two things.
|
||||
machines need it too, unless you distribute the agent yourself and write its
|
||||
config by hand, which is all the install script does.
|
||||
|
||||
Licence verification is entirely local, so a licensed install works with no
|
||||
outbound access to HQ at all.
|
||||
|
||||
+42
-137
@@ -1,154 +1,59 @@
|
||||
---
|
||||
id: rest-api
|
||||
title: REST API
|
||||
sidebar_label: REST API
|
||||
title: Automating Vantage
|
||||
sidebar_label: Automating Vantage
|
||||
---
|
||||
|
||||
The control plane's HTTP API, on port `8080`. The web UI is a client of it and
|
||||
has no privileges it does not.
|
||||
Everything the web UI does, it does through Vantage's own API, so anything you
|
||||
can do on screen you can also do from a script.
|
||||
|
||||
## Authentication
|
||||
The routes mirror the product: `/api/servers`, `/api/keys`, `/api/workflows`,
|
||||
`/api/monitors`, `/api/secrets`, `/api/audit`, and so on.
|
||||
|
||||
Most endpoints take a session: an opaque 32-byte token in the `km_session`
|
||||
cookie, with the body in Redis for 24 hours.
|
||||
## Where it is
|
||||
|
||||
One endpoint takes a bearer token instead the External Secrets Operator read
|
||||
path.
|
||||
On a self-hosted install the API is served on port `8080`, behind the same
|
||||
reverse proxy as the web UI, under `/api` and `/auth`. On a cloud instance it is
|
||||
your instance hostname.
|
||||
|
||||
## Unauthenticated
|
||||
## Signing in
|
||||
|
||||
```
|
||||
GET /install /install.ps1 # dynamic agent install scripts
|
||||
GET /update /update.ps1
|
||||
GET /auth/bootstrap-status
|
||||
POST /auth/bootstrap /auth/login /auth/logout
|
||||
GET /auth/me
|
||||
GET /auth/providers # {local_enabled, providers:[{id,name,preset}]} — no issuer, client ID or secret
|
||||
GET /auth/oidc/:providerId/start · /auth/oidc/:providerId/callback
|
||||
GET /api/secrets/:group/values # bearer token (ESO)
|
||||
Most calls use a session, exactly as the browser does:
|
||||
|
||||
```bash
|
||||
curl -c cookies.txt -X POST https://vantage.example.com/auth/login \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"email":"you@example.com","password":"..."}'
|
||||
|
||||
curl -b cookies.txt https://vantage.example.com/api/servers
|
||||
```
|
||||
|
||||
`/install` and `/install.ps1` take `server_id` and `token` as query parameters
|
||||
and return a shell script with the newest agent version substituted in.
|
||||
Sessions last 24 hours. Your role applies exactly as it does in the UI: a
|
||||
`member` calling an owner-only route is refused.
|
||||
|
||||
`POST /auth/bootstrap` works only while the database has no users.
|
||||
## The one exception
|
||||
|
||||
## Session-authenticated, under `/api`
|
||||
Kubernetes reads secret groups with a token instead of a session, so that it
|
||||
does not need an account. See
|
||||
[Secrets](../vantage/secrets.md#kubernetes-external-secrets-operator).
|
||||
|
||||
### Servers
|
||||
## Things worth knowing
|
||||
|
||||
```
|
||||
GET,POST /servers
|
||||
GET,POST /servers/new
|
||||
GET,DELETE /servers/:id
|
||||
POST /servers/:id/generate-key
|
||||
POST /servers/:id/update-agent
|
||||
POST /servers/:id/apply-updates
|
||||
```
|
||||
- **Reads always work. Changes need a valid licence.** Without one, the instance
|
||||
is read-only and any call that changes something is refused. Deleting things,
|
||||
applying OS updates and installing a licence are always allowed, so you can
|
||||
always get back under your allowance or out of read-only mode.
|
||||
- **Some features are licensed.** The browser console, single sign-on and
|
||||
vulnerability scanning are refused if your licence does not include them.
|
||||
- **Some things cannot be changed here.** A cloud instance refuses a pasted
|
||||
licence, and people managed by Vantage HQ cannot be re-roled or deleted inside
|
||||
the instance.
|
||||
- **Errors are JSON**, with an `error` field naming the reason.
|
||||
- **Everything that changes something is audited**, whether it came from the UI
|
||||
or from a script. See [Audit log](../vantage/audit-log.md).
|
||||
|
||||
### Keys
|
||||
## Vantage HQ
|
||||
|
||||
```
|
||||
GET,POST /keys
|
||||
GET,DELETE /keys/:id
|
||||
GET /keys/:id/private-key
|
||||
POST /keys/:id/assign
|
||||
DELETE /keys/:id/assign/:serverId
|
||||
```
|
||||
|
||||
### Workflows and steps
|
||||
|
||||
```
|
||||
GET,POST /steps
|
||||
PUT,DELETE /steps/:id
|
||||
GET /steps/:id/export
|
||||
POST /steps/import · /steps/seed-defaults · /steps/parse
|
||||
GET /steps/usage
|
||||
GET,POST /workflows
|
||||
GET,PUT,DELETE /workflows/:id
|
||||
POST /workflows/:id/run
|
||||
GET /workflows/:id/runs
|
||||
GET /runs/:runId
|
||||
POST /runs/:runId/cancel
|
||||
GET /runs/:runId/servers/:serverId/logs
|
||||
GET /runs/:runId/servers/:serverId/logs/stream
|
||||
```
|
||||
|
||||
`PUT` and `DELETE` on a step whose source is `default` answer `409`. See
|
||||
[Workflows](../vantage/workflows.md#default-steps).
|
||||
|
||||
### Monitors and channels
|
||||
|
||||
```
|
||||
GET,POST /monitors
|
||||
GET,PUT,DELETE /monitors/:id
|
||||
GET /monitors/:id/incidents · /monitors/:id/uptime
|
||||
GET,POST /channels
|
||||
PUT,DELETE /channels/:id
|
||||
POST /channels/:id/test
|
||||
```
|
||||
|
||||
### Secrets
|
||||
|
||||
```
|
||||
GET,POST /secrets
|
||||
GET,PUT,DELETE /secrets/:group
|
||||
POST /secrets/:group/reveal
|
||||
DELETE /secrets/:group/:key
|
||||
```
|
||||
|
||||
### Console
|
||||
|
||||
```
|
||||
POST /console/connect
|
||||
GET /console/tunnel # websocket
|
||||
```
|
||||
|
||||
### Other
|
||||
|
||||
```
|
||||
GET /audit
|
||||
GET /agent/latest-version
|
||||
GET,PUT /settings (owner|admin)
|
||||
POST /settings/secrets-token (owner|admin)
|
||||
GET /license
|
||||
POST /license (self-hosted only)
|
||||
GET,POST /org/users
|
||||
PUT /org/users/:id/role
|
||||
DELETE /org/users/:id
|
||||
GET,POST /auth/providers (owner|admin)
|
||||
PUT,DELETE /auth/providers/:id (owner|admin)
|
||||
POST /auth/providers/:id/test · /auth/providers/:id/ack-notice (owner|admin)
|
||||
GET /auth/presets (owner|admin)
|
||||
```
|
||||
|
||||
## Notable refusals
|
||||
|
||||
| Endpoint | Condition | Status |
|
||||
| -------------------------------------------------- | ------------------------------ | ------------------- |
|
||||
| `POST /license` | deployment is `cloud` | `409 cloud_managed` |
|
||||
| `PUT,DELETE /steps/:id` | the step's source is `default` | `409` |
|
||||
| `PUT /org/users/:id/role`, `DELETE /org/users/:id` | the user's auth source is `hq` | `409` |
|
||||
|
||||
`POST /license` is exempt from the licence check, so pasting a valid licence
|
||||
works while the current one is expired that is the way out of degraded mode.
|
||||
|
||||
## Multi-tenancy
|
||||
|
||||
Every request is scoped to the instance resolved from the session. On a
|
||||
multi-tenant deployment, a request arriving at `<slug>.vantage.<tld>` also has
|
||||
its host checked against the session's instance, and a mismatch is rejected.
|
||||
|
||||
## Errors
|
||||
|
||||
Errors are JSON with an `error` field. Customer-facing endpoints in the HQ API
|
||||
answer `404` rather than `403` for another account's resource, because a `403`
|
||||
confirms the resource exists; the control plane's own API is single-tenant per
|
||||
session and does not need that distinction.
|
||||
|
||||
## Admin API
|
||||
|
||||
Vantage HQ is a separate hosted service with its own API and its own session.
|
||||
Its behaviour is described in the [Vantage HQ](../hq/accounts-and-signup.md)
|
||||
section rather than here; the two services share no session and no
|
||||
authentication.
|
||||
The portal is a separate service with its own sign-in, described in the
|
||||
[Vantage HQ](../hq/accounts-and-signup.md) section. A Vantage session does not
|
||||
work there, and an HQ session does not work in your instance.
|
||||
|
||||
@@ -8,13 +8,12 @@ Symptoms, in the order people hit them.
|
||||
|
||||
## The server will not start
|
||||
|
||||
**Exits immediately on boot.** Almost always a missing `GRPC_HOST` the server
|
||||
**Exits immediately on boot.** Almost always a missing `GRPC_HOST`. The server
|
||||
refuses to start rather than guess a value that would break every agent later.
|
||||
|
||||
**Fails during index creation.** The auth and settings index builders are fatal
|
||||
on failure by design: those unique indexes are what enforce tenant isolation,
|
||||
so starting without them is worse than not starting. Check the MongoDB user's
|
||||
permissions and whether a conflicting index already exists.
|
||||
**Fails while preparing the database.** Vantage stops rather than run without
|
||||
the safeguards it sets up at startup. Check the MongoDB user's permissions and
|
||||
whether an old, conflicting index is already there.
|
||||
|
||||
**Starts, but every secret operation errors.** `KEY_ENCRYPTION_KEY` is missing
|
||||
or is not 64 hex characters.
|
||||
@@ -22,15 +21,15 @@ or is not 64 hex characters.
|
||||
## Nobody can sign in
|
||||
|
||||
**`/setup` appears when users already exist.** The server is pointed at a
|
||||
different database than you think. Check the database name in `MONGO_URI` —
|
||||
it comes from the URI path, not a separate variable.
|
||||
different database than you think. Check the database name in `MONGO_URI`,
|
||||
which is taken from the end of the URI.
|
||||
|
||||
**Sessions do not stick.** Redis is unreachable, or the cookie is being dropped
|
||||
because the site is served over plain HTTP.
|
||||
|
||||
**"Wrong organisation" style rejections.** The host and session guard is
|
||||
comparing the request host's label against the session's organisation. Check
|
||||
`APP_ROOT_LABEL`.
|
||||
**"Wrong organisation" style rejections.** Vantage compares the address you
|
||||
browsed to against the instance your session belongs to. On a custom domain,
|
||||
check `APP_ROOT_LABEL`.
|
||||
|
||||
**OIDC redirects and then fails.** The callback URL registered with the provider
|
||||
must match exactly. Keep one local owner account so a broken provider is not a
|
||||
@@ -44,12 +43,12 @@ Work through it in this order:
|
||||
2. What does it say? `journalctl -u vantage-agent -f`.
|
||||
3. Can that machine reach the endpoint? Test `GRPC_HOST` **from the machine**,
|
||||
not from the control plane host.
|
||||
4. Was the token already used or expired? It is single-use and lives one hour —
|
||||
create a fresh enrolment rather than reusing the old command.
|
||||
4. Was the token already used, or older than an hour? Generate a fresh install
|
||||
command rather than reusing the old one.
|
||||
|
||||
| Symptom | Cause |
|
||||
| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| Registers, then goes `offline` within minutes | Something permits the short `Register` call but drops the long-lived stream. Usually a proxy or idle-timeout middlebox |
|
||||
| Registers, then goes `offline` within minutes | The short registration call gets through but the long-lived connection is dropped, usually by a proxy or an idle timeout |
|
||||
| Stays `pending` forever | Registration never happened. Token spent, or the endpoint unreachable |
|
||||
| Flaps between `active` and `offline` | Intermittent path, or a poll interval longer than the offline threshold |
|
||||
|
||||
@@ -67,15 +66,15 @@ instantaneous.
|
||||
|
||||
## A workflow run fails or hangs
|
||||
|
||||
- **Hangs at dispatch.** The target's command stream is not connected the
|
||||
- **Hangs at dispatch.** The target's command stream is not connected; the
|
||||
server may be `offline`.
|
||||
- **Fails immediately with an interpreter error.** A bash step on a Windows
|
||||
target, or PowerShell on Linux.
|
||||
- **A value does not reach the next step.** Values pass through the file at
|
||||
`$WORKFLOW_ENV`, one `KEY=value` per line. Declaring an output does not export
|
||||
it.
|
||||
- **A secret is empty.** The group is not in the step's `secret_refs`, or the
|
||||
key name differs from the environment variable you are reading.
|
||||
`$WORKFLOW_ENV`, one `KEY=value` per line. Listing an output does not pass it
|
||||
on by itself.
|
||||
- **A secret is empty.** The group is not attached to that step, or the key name
|
||||
differs from the variable you are reading.
|
||||
- **Logs stop mid-run.** A reverse proxy read timeout cut the stream. The run
|
||||
itself continues; reload the page.
|
||||
|
||||
@@ -85,8 +84,8 @@ instantaneous.
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| Connects, then closes at once | guacd unreachable. Check `GUACD_ADDR` and that the container is running |
|
||||
| SSH rejects the key | The stored key has no private half, or is not on the target |
|
||||
| RDP fails on retry | Credentials are single-use and consumed at tunnel open enter them 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 |
|
||||
| RDP fails on retry | Credentials are single-use and consumed at tunnel open. Enter them again |
|
||||
| Hangs, then disconnects | The agent could not reach the service on that machine, or setting up the session timed out. The audit log records which |
|
||||
| Fails only in production | The reverse proxy is not forwarding WebSocket upgrade headers |
|
||||
|
||||
## Monitors report down when the service is up
|
||||
@@ -98,7 +97,7 @@ instantaneous.
|
||||
|
||||
## Notifications are not arriving
|
||||
|
||||
Use the channel **Test** button it goes through the real delivery path, so a
|
||||
Use the channel **Test** button. It goes through the real delivery path, so a
|
||||
test that arrives proves credentials, network path and destination.
|
||||
|
||||
If the test fails: a webhook returning 300 or above counts as a failure, SMTP
|
||||
@@ -109,9 +108,9 @@ needs `host`, `port`, `from` and `to`, and Telegram needs both `token` and
|
||||
|
||||
| Symptom | Cause |
|
||||
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| `409 cloud_managed` when pasting | It is a cloud instance. Licences are written by HQ; there is nothing to paste |
|
||||
| Licence rejected as not matching | It is bound to a different instance UUID. Relink in HQ |
|
||||
| Instance degraded despite a valid-looking licence | It has expired past its grace period. Pasting still works that endpoint stays available specifically so it can |
|
||||
| "Managed by Vantage HQ" when pasting | It is a cloud instance, which is licensed for you. There is nothing to paste |
|
||||
| Licence rejected as not matching | It was issued to a different instance ID. Relink it in Vantage HQ |
|
||||
| Instance degraded despite a valid-looking licence | It expired more than a few days ago. Pasting a new one still works, which is how you recover |
|
||||
| Cannot enrol another server | The server allowance is reached. Raise it in HQ or remove one |
|
||||
|
||||
## HQ portal problems
|
||||
@@ -129,5 +128,5 @@ docker compose logs --tail=200 server
|
||||
journalctl -u vantage-agent --no-pager -n 200 # on the affected machine
|
||||
```
|
||||
|
||||
Include your instance UUID from **Settings → Licence** it is the reference
|
||||
Include your instance ID from the **Licence** page, which is the reference
|
||||
support works from.
|
||||
|
||||
+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.
|
||||
|
||||
+1
-1
@@ -14,8 +14,8 @@ const sidebars: SidebarsConfig = {
|
||||
"getting-started/cloud-vs-self-hosted",
|
||||
"getting-started/self-hosted-install",
|
||||
"getting-started/first-login",
|
||||
"getting-started/first-server",
|
||||
"getting-started/claim-free-licence",
|
||||
"getting-started/first-server",
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user