---
id: what-is-vantage
title: What is Vantage
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.
## The pieces
```mermaid
flowchart TD
W["Web UI
servers · keys · workflows · monitors
secrets · audit · console · settings"]
S["Server
REST :8080 · gRPC :9090
MongoDB · Redis · guacd"]
A["Agent
one per managed server
Linux and Windows"]
W -->|REST, cookie session| S
S -->|gRPC over TLS| A
A -.->|outbound only| 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 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 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.
## 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.
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.
## Two request patterns
| 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.
## Next
- [Cloud or self-hosted](./cloud-vs-self-hosted.md) which one you want
- [Self-hosted install](./self-hosted-install.md) stand it up