feat: documentation site
Docusaurus 3 docs-only site at docsite/, served statically by nginx under /docs on the marketing host. Covers getting started (self-hosted install through first server and first licence), the control plane, Vantage HQ, a reference section and operations. Wired into docker-compose.site.yml as docsite (3005:80) and into the image build workflow, rebuilding on its own directory only. Never added to the self-hosted compose file.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
---
|
||||
id: ssh-keys
|
||||
title: SSH keys
|
||||
sidebar_label: SSH keys
|
||||
---
|
||||
|
||||
Vantage holds a library of public keys and decides, per server, which ones
|
||||
belong in `/root/.ssh/authorized_keys`. The agent makes the file match.
|
||||
|
||||
:::info root only
|
||||
Vantage manages `/root/.ssh/authorized_keys` and nothing else. There is no
|
||||
per-user key management. The agent runs as root because writing that file
|
||||
requires it.
|
||||
:::
|
||||
|
||||
## Adding a key
|
||||
|
||||
### Upload one you already have
|
||||
|
||||
**Keys → Add key**, paste the public half. Vantage stores the public key and its
|
||||
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
|
||||
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.
|
||||
|
||||
:::tip Why store a private key at all
|
||||
The [browser console](./browser-console.md) needs one to open an SSH session. If
|
||||
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.
|
||||
|
||||
## 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.
|
||||
|
||||
The agent treats a revoked assignment as "not desired" and removes the line from
|
||||
`authorized_keys` on its next sync.
|
||||
|
||||
:::warning Revoking does not close open sessions
|
||||
It removes the key from the file. An SSH session already established stays up
|
||||
until it ends. Kill sessions on the machine if that matters.
|
||||
:::
|
||||
|
||||
## What the agent actually does
|
||||
|
||||
Each poll:
|
||||
|
||||
1. `SyncKeys` 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`.
|
||||
|
||||
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.
|
||||
|
||||
:::danger Vantage owns the whole file
|
||||
The agent rewrites `authorized_keys` to match the desired set. Keys added by
|
||||
hand on the machine are removed on the next change. If a key must survive, put
|
||||
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.
|
||||
Reference in New Issue
Block a user