From fab87c82c62780340f768ed9b775c2b8bf68526f Mon Sep 17 00:00:00 2001 From: domrichardson <100129001+domrichardson@users.noreply.github.com> Date: Wed, 24 Jun 2026 15:48:13 +0100 Subject: [PATCH] feat: Updated brand to be vantage --- .gitea/workflows/agent-release.yml | 10 +- .gitea/workflows/server-deploy.yml | 4 +- agent/cmd/main.go | 6 +- agent/go.mod | 2 +- agent/internal/config/config.go | 4 +- agent/internal/grpc/client.go | 8 +- .../pb/{keymanager.pb.go => vantage.pb.go} | 38 +-- agent/internal/keys/keys.go | 8 +- agent/internal/sync/sync.go | 26 +-- claude.md | 34 +-- deploy/agent.service | 8 +- deploy/docker-compose.migrate.yml | 17 ++ deploy/docker-compose.yml | 2 +- deploy/migrate/agent-migrate.sh | 219 ++++++++++++++++++ deploy/migrate/server-migrate.sh | 124 ++++++++++ .../v1/vantage.proto} | 6 +- server/Dockerfile | 6 +- server/cmd/main.go | 12 +- server/go.mod | 2 +- server/internal/api/handlers.go | 66 +++--- .../pb/{keymanager.pb.go => vantage.pb.go} | 92 ++++---- server/internal/grpc/server.go | 18 +- server/internal/services/dispatch.go | 4 +- server/internal/services/keys.go | 4 +- server/internal/services/servers.go | 4 +- server/internal/services/sync.go | 4 +- web/app/layout.tsx | 2 +- web/app/servers/[id]/page.tsx | 2 +- web/app/servers/new/page.tsx | 8 +- web/components/Sidebar.tsx | 4 +- web/package-lock.json | 4 +- web/package.json | 2 +- 32 files changed, 555 insertions(+), 195 deletions(-) rename agent/internal/grpc/pb/{keymanager.pb.go => vantage.pb.go} (74%) create mode 100644 deploy/docker-compose.migrate.yml create mode 100644 deploy/migrate/agent-migrate.sh create mode 100644 deploy/migrate/server-migrate.sh rename proto/{keymanager/v1/keymanager.proto => vantage/v1/vantage.proto} (94%) rename server/internal/grpc/pb/{keymanager.pb.go => vantage.pb.go} (60%) diff --git a/.gitea/workflows/agent-release.yml b/.gitea/workflows/agent-release.yml index 2f2433d..8202307 100644 --- a/.gitea/workflows/agent-release.yml +++ b/.gitea/workflows/agent-release.yml @@ -32,20 +32,20 @@ jobs: mkdir -p dist GOOS=linux GOARCH=amd64 go build \ -ldflags="-s -w -X main.Version=${VERSION}" \ - -o dist/keymanager-agent-linux-amd64 ./cmd + -o dist/vantage-agent-linux-amd64 ./cmd GOOS=linux GOARCH=arm64 go build \ -ldflags="-s -w -X main.Version=${VERSION}" \ - -o dist/keymanager-agent-linux-arm64 ./cmd + -o dist/vantage-agent-linux-arm64 ./cmd - name: Checksums working-directory: agent/dist - run: sha256sum keymanager-agent-linux-amd64 keymanager-agent-linux-arm64 > checksums.txt + run: sha256sum vantage-agent-linux-amd64 vantage-agent-linux-arm64 > checksums.txt - name: Create release uses: https://gitea.com/actions/gitea-release-action@v1 with: token: ${{ secrets.RELEASE_TOKEN }} files: | - agent/dist/keymanager-agent-linux-amd64 - agent/dist/keymanager-agent-linux-arm64 + agent/dist/vantage-agent-linux-amd64 + agent/dist/vantage-agent-linux-arm64 agent/dist/checksums.txt diff --git a/.gitea/workflows/server-deploy.yml b/.gitea/workflows/server-deploy.yml index 7c7e10c..27be513 100644 --- a/.gitea/workflows/server-deploy.yml +++ b/.gitea/workflows/server-deploy.yml @@ -23,13 +23,13 @@ jobs: - name: Build and push server image run: | - IMAGE="${{ vars.DOCKER_HOST }}/${{ github.repository_owner }}/keymanager/server:latest" + IMAGE="${{ vars.DOCKER_HOST }}/${{ github.repository_owner }}/vantage/server:latest" docker build -t "$IMAGE" -f server/Dockerfile server/ docker push "$IMAGE" - name: Build and push web image run: | - IMAGE="${{ vars.DOCKER_HOST }}/${{ github.repository_owner }}/keymanager/web:latest" + IMAGE="${{ vars.DOCKER_HOST }}/${{ github.repository_owner }}/vantage/web:latest" docker build \ --build-arg NEXT_PUBLIC_API_URL="${{ vars.API_URL }}" \ -t "$IMAGE" \ diff --git a/agent/cmd/main.go b/agent/cmd/main.go index f49ff27..d1bbc6d 100644 --- a/agent/cmd/main.go +++ b/agent/cmd/main.go @@ -7,8 +7,8 @@ import ( "os/signal" "syscall" - "github.com/mrhid6/keymanager/agent/internal/config" - agentsync "github.com/mrhid6/keymanager/agent/internal/sync" + "github.com/mrhid6/vantage/agent/internal/config" + agentsync "github.com/mrhid6/vantage/agent/internal/sync" ) var Version = "dev" @@ -32,7 +32,7 @@ func main() { ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() - log.Printf("keymanager-agent %s starting (server=%s, poll=%s)", Version, cfg.ServerURL, cfg.PollInterval) + log.Printf("vantage-agent %s starting (server=%s, poll=%s)", Version, cfg.ServerURL, cfg.PollInterval) if err := agentsync.Run(ctx, cfg, Version); err != nil { log.Fatalf("agent error: %v", err) } diff --git a/agent/go.mod b/agent/go.mod index 321268f..b2d64ed 100644 --- a/agent/go.mod +++ b/agent/go.mod @@ -1,4 +1,4 @@ -module github.com/mrhid6/keymanager/agent +module github.com/mrhid6/vantage/agent go 1.26 diff --git a/agent/internal/config/config.go b/agent/internal/config/config.go index 47d0ba8..ad72da7 100644 --- a/agent/internal/config/config.go +++ b/agent/internal/config/config.go @@ -7,7 +7,7 @@ import ( "gopkg.in/yaml.v3" ) -const ConfigPath = "/etc/keymanager/config.yaml" +const ConfigPath = "/etc/vantage/config.yaml" type Config struct { ServerURL string `yaml:"server_url"` @@ -38,7 +38,7 @@ func Save(cfg *Config) error { if err != nil { return err } - if err := os.MkdirAll("/etc/keymanager", 0700); err != nil { + if err := os.MkdirAll("/etc/vantage", 0700); err != nil { return err } return os.WriteFile(ConfigPath, data, 0600) diff --git a/agent/internal/grpc/client.go b/agent/internal/grpc/client.go index 7a44926..db3910c 100644 --- a/agent/internal/grpc/client.go +++ b/agent/internal/grpc/client.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/mrhid6/keymanager/agent/internal/grpc/pb" + "github.com/mrhid6/vantage/agent/internal/grpc/pb" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -19,7 +19,7 @@ func init() { type Client struct { conn *grpc.ClientConn - client pb.KeyManagerClient + client pb.VantageClient } func New(serverURL string, useTLS bool) (*Client, error) { @@ -48,7 +48,7 @@ func New(serverURL string, useTLS bool) (*Client, error) { return &Client{ conn: conn, - client: pb.NewKeyManagerClient(conn), + client: pb.NewVantageClient(conn), }, nil } @@ -107,6 +107,6 @@ func (c *Client) UploadGeneratedKey(serverID, agentToken, publicKey, privateKey, // CommandStream opens a long-lived bidirectional stream for server-pushed commands. // The caller controls the stream lifetime via ctx. -func (c *Client) CommandStream(ctx context.Context) (pb.KeyManager_CommandStreamClient, error) { +func (c *Client) CommandStream(ctx context.Context) (pb.Vantage_CommandStreamClient, error) { return c.client.CommandStream(ctx) } diff --git a/agent/internal/grpc/pb/keymanager.pb.go b/agent/internal/grpc/pb/vantage.pb.go similarity index 74% rename from agent/internal/grpc/pb/keymanager.pb.go rename to agent/internal/grpc/pb/vantage.pb.go index da52687..ee3b194 100644 --- a/agent/internal/grpc/pb/keymanager.pb.go +++ b/agent/internal/grpc/pb/vantage.pb.go @@ -1,4 +1,4 @@ -// Hand-written gRPC bindings for keymanager.proto (agent side, JSON codec). +// Hand-written gRPC bindings for vantage.proto (agent side, JSON codec). package pb @@ -87,21 +87,21 @@ type CommandResult struct { // CommandStream client-side interface -type KeyManager_CommandStreamClient interface { +type Vantage_CommandStreamClient interface { Send(*AgentMessage) error Recv() (*ServerCommand, error) grpc.ClientStream } -type keyManagerCommandStreamClient struct { +type vantageCommandStreamClient struct { grpc.ClientStream } -func (c *keyManagerCommandStreamClient) Send(m *AgentMessage) error { +func (c *vantageCommandStreamClient) Send(m *AgentMessage) error { return c.ClientStream.SendMsg(m) } -func (c *keyManagerCommandStreamClient) Recv() (*ServerCommand, error) { +func (c *vantageCommandStreamClient) Recv() (*ServerCommand, error) { m := new(ServerCommand) if err := c.ClientStream.RecvMsg(m); err != nil { return nil, err @@ -111,7 +111,7 @@ func (c *keyManagerCommandStreamClient) Recv() (*ServerCommand, error) { // CommandStream server-side interface (included for completeness) -type KeyManager_CommandStreamServer interface { +type Vantage_CommandStreamServer interface { Send(*ServerCommand) error Recv() (*AgentMessage, error) grpc.ServerStream @@ -133,22 +133,22 @@ func (s *keyManagerCommandStreamServer) Recv() (*AgentMessage, error) { return m, nil } -type KeyManagerClient interface { +type VantageClient interface { Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) SyncKeys(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) UploadGeneratedKey(ctx context.Context, in *UploadKeyRequest, opts ...grpc.CallOption) (*UploadKeyResponse, error) - CommandStream(ctx context.Context, opts ...grpc.CallOption) (KeyManager_CommandStreamClient, error) + CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) } -type UnimplementedKeyManagerServer struct{} +type UnimplementedVantageServer struct{} -func (UnimplementedKeyManagerServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) { +func (UnimplementedVantageServer) Register(context.Context, *RegisterRequest) (*RegisterResponse, error) { return nil, status.Errorf(codes.Unimplemented, "not implemented") } -func (UnimplementedKeyManagerServer) SyncKeys(context.Context, *SyncRequest) (*SyncResponse, error) { +func (UnimplementedVantageServer) SyncKeys(context.Context, *SyncRequest) (*SyncResponse, error) { return nil, status.Errorf(codes.Unimplemented, "not implemented") } -func (UnimplementedKeyManagerServer) UploadGeneratedKey(context.Context, *UploadKeyRequest) (*UploadKeyResponse, error) { +func (UnimplementedVantageServer) UploadGeneratedKey(context.Context, *UploadKeyRequest) (*UploadKeyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "not implemented") } @@ -156,13 +156,13 @@ type keyManagerClient struct { cc grpc.ClientConnInterface } -func NewKeyManagerClient(cc grpc.ClientConnInterface) KeyManagerClient { +func NewVantageClient(cc grpc.ClientConnInterface) VantageClient { return &keyManagerClient{cc} } func (c *keyManagerClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) { out := new(RegisterResponse) - if err := c.cc.Invoke(ctx, "/keymanager.v1.KeyManager/Register", in, out, opts...); err != nil { + if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/Register", in, out, opts...); err != nil { return nil, err } return out, nil @@ -170,7 +170,7 @@ func (c *keyManagerClient) Register(ctx context.Context, in *RegisterRequest, op func (c *keyManagerClient) SyncKeys(ctx context.Context, in *SyncRequest, opts ...grpc.CallOption) (*SyncResponse, error) { out := new(SyncResponse) - if err := c.cc.Invoke(ctx, "/keymanager.v1.KeyManager/SyncKeys", in, out, opts...); err != nil { + if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/SyncKeys", in, out, opts...); err != nil { return nil, err } return out, nil @@ -178,17 +178,17 @@ func (c *keyManagerClient) SyncKeys(ctx context.Context, in *SyncRequest, opts . func (c *keyManagerClient) UploadGeneratedKey(ctx context.Context, in *UploadKeyRequest, opts ...grpc.CallOption) (*UploadKeyResponse, error) { out := new(UploadKeyResponse) - if err := c.cc.Invoke(ctx, "/keymanager.v1.KeyManager/UploadGeneratedKey", in, out, opts...); err != nil { + if err := c.cc.Invoke(ctx, "/vantage.v1.Vantage/UploadGeneratedKey", in, out, opts...); err != nil { return nil, err } return out, nil } -func (c *keyManagerClient) CommandStream(ctx context.Context, opts ...grpc.CallOption) (KeyManager_CommandStreamClient, error) { +func (c *keyManagerClient) CommandStream(ctx context.Context, opts ...grpc.CallOption) (Vantage_CommandStreamClient, error) { desc := &grpc.StreamDesc{StreamName: "CommandStream", ServerStreams: true, ClientStreams: true} - stream, err := c.cc.NewStream(ctx, desc, "/keymanager.v1.KeyManager/CommandStream", opts...) + stream, err := c.cc.NewStream(ctx, desc, "/vantage.v1.Vantage/CommandStream", opts...) if err != nil { return nil, err } - return &keyManagerCommandStreamClient{stream}, nil + return &vantageCommandStreamClient{stream}, nil } diff --git a/agent/internal/keys/keys.go b/agent/internal/keys/keys.go index 56ed6c4..1e01ae2 100644 --- a/agent/internal/keys/keys.go +++ b/agent/internal/keys/keys.go @@ -12,8 +12,8 @@ import ( const authorizedKeysPath = "/root/.ssh/authorized_keys" const sshConfigPath = "/root/.ssh/config" -const managedConfigPath = "/root/.ssh/keymanager.conf" -const includeDirective = "Include /root/.ssh/keymanager.conf" +const managedConfigPath = "/root/.ssh/vantage.conf" +const includeDirective = "Include /root/.ssh/vantage.conf" func ReadAuthorizedKeys() ([]string, error) { data, err := os.ReadFile(authorizedKeysPath) @@ -140,7 +140,7 @@ func GenerateKeyPair(keyPath string, opts KeyGenOptions) (string, error) { } // AddSSHIdentity writes an IdentityFile entry for keyPath into the managed -// keymanager.conf include file, and ensures ~/.ssh/config includes it. +// vantage.conf include file, and ensures ~/.ssh/config includes it. func AddSSHIdentity(keyPath string) error { if err := os.MkdirAll(filepath.Dir(sshConfigPath), 0700); err != nil { return fmt.Errorf("mkdir .ssh: %w", err) @@ -204,7 +204,7 @@ func RemoveSSHIdentity(keyPath string) error { return nil } -// ensureIncludeDirective adds "Include /root/.ssh/keymanager.conf" to the top +// ensureIncludeDirective adds "Include /root/.ssh/vantage.conf" to the top // of ~/.ssh/config if it is not already present. The Include must appear before // any Host stanzas to be effective for all connections. func ensureIncludeDirective() error { diff --git a/agent/internal/sync/sync.go b/agent/internal/sync/sync.go index 8985891..b16e693 100644 --- a/agent/internal/sync/sync.go +++ b/agent/internal/sync/sync.go @@ -15,10 +15,10 @@ import ( "strings" "time" - "github.com/mrhid6/keymanager/agent/internal/config" - grpcclient "github.com/mrhid6/keymanager/agent/internal/grpc" - "github.com/mrhid6/keymanager/agent/internal/grpc/pb" - "github.com/mrhid6/keymanager/agent/internal/keys" + "github.com/mrhid6/vantage/agent/internal/config" + grpcclient "github.com/mrhid6/vantage/agent/internal/grpc" + "github.com/mrhid6/vantage/agent/internal/grpc/pb" + "github.com/mrhid6/vantage/agent/internal/keys" ) func Run(ctx context.Context, cfg *config.Config, version string) error { @@ -178,7 +178,7 @@ func connectAndHandleStream(ctx context.Context, cfg *config.Config) error { func handleDeleteKey(cmd *pb.ServerCommand) { label := cmd.DeleteKey.Label - keyPath := fmt.Sprintf("/root/.ssh/keymanager_%s", strings.ReplaceAll(label, " ", "_")) + keyPath := fmt.Sprintf("/root/.ssh/vantage_%s", strings.ReplaceAll(label, " ", "_")) if err := keys.RemoveSSHIdentity(keyPath); err != nil { log.Printf("remove ssh identity failed (cmd=%s): %v", cmd.CommandId, err) @@ -196,13 +196,13 @@ func handleUpdateAgent(cmd *pb.ServerCommand) { u := cmd.UpdateAgent arch := runtime.GOARCH // "amd64" or "arm64" tag := "agent%2Fv" + u.Version - binaryURL := fmt.Sprintf("%s/mrhid6/keymanager/releases/download/%s/keymanager-agent-linux-%s", u.GiteaBaseURL, tag, arch) - checksumURL := fmt.Sprintf("%s/mrhid6/keymanager/releases/download/%s/checksums.txt", u.GiteaBaseURL, tag) + binaryURL := fmt.Sprintf("%s/mrhid6/vantage/releases/download/%s/vantage-agent-linux-%s", u.GiteaBaseURL, tag, arch) + checksumURL := fmt.Sprintf("%s/mrhid6/vantage/releases/download/%s/checksums.txt", u.GiteaBaseURL, tag) log.Printf("updating agent to v%s from %s (cmd=%s)", u.Version, u.GiteaBaseURL, cmd.CommandId) // Download binary - tmpBin := "/tmp/keymanager-agent-update" + tmpBin := "/tmp/vantage-agent-update" if err := downloadFile(binaryURL, tmpBin); err != nil { log.Printf("update download failed (cmd=%s): %v", cmd.CommandId, err) return @@ -214,7 +214,7 @@ func handleUpdateAgent(cmd *pb.ServerCommand) { log.Printf("update checksum fetch failed (cmd=%s): %v", cmd.CommandId, err) return } - if err := verifyChecksum(tmpBin, fmt.Sprintf("keymanager-agent-linux-%s", arch), checksumData); err != nil { + if err := verifyChecksum(tmpBin, fmt.Sprintf("vantage-agent-linux-%s", arch), checksumData); err != nil { log.Printf("update checksum mismatch (cmd=%s): %v", cmd.CommandId, err) os.Remove(tmpBin) return @@ -224,13 +224,13 @@ func handleUpdateAgent(cmd *pb.ServerCommand) { log.Printf("update chmod failed (cmd=%s): %v", cmd.CommandId, err) return } - if err := os.Rename(tmpBin, "/usr/local/bin/keymanager-agent"); err != nil { + if err := os.Rename(tmpBin, "/usr/local/bin/vantage-agent"); err != nil { log.Printf("update replace binary failed (cmd=%s): %v", cmd.CommandId, err) return } log.Printf("agent binary replaced, restarting service (cmd=%s)", cmd.CommandId) - exec.Command("systemctl", "restart", "keymanager-agent").Run() + exec.Command("systemctl", "restart", "vantage-agent").Run() } func downloadFile(url, dest string) error { @@ -290,7 +290,7 @@ func verifyChecksum(filePath, filename string, checksumData []byte) error { func handleGenerateKey(cfg *config.Config, cmd *pb.ServerCommand) { g := cmd.GenerateKey label := g.Label - keyPath := fmt.Sprintf("/root/.ssh/keymanager_%s", strings.ReplaceAll(label, " ", "_")) + keyPath := fmt.Sprintf("/root/.ssh/vantage_%s", strings.ReplaceAll(label, " ", "_")) opts := keys.KeyGenOptions{ KeyType: g.KeyType, @@ -352,7 +352,7 @@ func GenerateAndUpload(cfg *config.Config, label string) error { } defer client.Close() - keyPath := fmt.Sprintf("/root/.ssh/keymanager_%s", strings.ReplaceAll(label, " ", "_")) + keyPath := fmt.Sprintf("/root/.ssh/vantage_%s", strings.ReplaceAll(label, " ", "_")) pubKey, err := keys.GenerateKeyPair(keyPath, keys.KeyGenOptions{Comment: label}) if err != nil { return err diff --git a/claude.md b/claude.md index ce4eb70..9e637d5 100644 --- a/claude.md +++ b/claude.md @@ -1,4 +1,4 @@ -# KeyManager +# Vantage A self-hosted SSH key management system. A central server (Go + Next.js + MongoDB) manages public key assignments across servers. A lightweight Go agent runs on each managed server, polls the central server via gRPC, and atomically rewrites `/root/.ssh/authorized_keys` to match the desired state. @@ -34,7 +34,7 @@ A self-hosted SSH key management system. A central server (Go + Next.js + MongoD ## Repository Structure ``` -keymanager/ +vantage/ ├── agent/ │ ├── cmd/main.go │ └── internal/ @@ -56,7 +56,7 @@ keymanager/ │ ├── app/ │ └── components/ ├── proto/ -│ └── keymanager/v1/keymanager.proto +│ └── vantage/v1/vantage.proto ├── deploy/ │ ├── docker-compose.yml │ └── agent.service @@ -72,9 +72,9 @@ keymanager/ ```protobuf syntax = "proto3"; -package keymanager.v1; +package vantage.v1; -service KeyManager { +service Vantage { rpc Register(RegisterRequest) returns (RegisterResponse); rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); @@ -172,10 +172,10 @@ No streaming — polling only. Poll interval: **30 seconds**. ## Agent Lifecycle -### Config file — `/etc/keymanager/config.yaml` +### Config file — `/etc/vantage/config.yaml` ```yaml -server_url: "keymanager.yourdomain.com:9090" +server_url: "vantage.yourdomain.com:9090" server_id: "" pre_reg_token: "" # removed after first successful Register() agent_token: "" # written by agent after Register() @@ -216,15 +216,15 @@ Config file permissions: `0600`. Config directory: `0700`. - Uploads public key via `UploadGeneratedKey()` - Private key stays local on the machine -### Systemd unit — `/etc/systemd/system/keymanager-agent.service` +### Systemd unit — `/etc/systemd/system/vantage-agent.service` ```ini [Unit] -Description=KeyManager Agent +Description=Vantage Agent After=network.target [Service] -ExecStart=/usr/local/bin/keymanager-agent +ExecStart=/usr/local/bin/vantage-agent Restart=always RestartSec=10 User=root @@ -241,14 +241,14 @@ WantedBy=multi-user.target 2. Backend generates a short-lived pre-registration token (TTL: 1 hour) and a `server_id` 3. UI displays a one-liner install command with copy button: ```bash - curl -fsSL https://keymanager.yourdomain.com/install | \ + curl -fsSL https://vantage.yourdomain.com/install | \ bash -s -- --server-id= --token= ``` 4. Install script: - Detects arch (`amd64` / `arm64`) - Downloads agent binary from Gitea release - Verifies SHA-256 checksum - - Writes `/etc/keymanager/config.yaml` + - Writes `/etc/vantage/config.yaml` - Installs and starts systemd unit 5. On first `SyncKeys` call, server marks status as `active` @@ -259,7 +259,7 @@ The backend serves `/install` dynamically, injecting the latest agent version by ## Security - gRPC over TLS (Let's Encrypt or self-signed with cert pinning on the agent) -- Agent authenticates with a per-server token stored at `/etc/keymanager/config.yaml` (`0600`) +- Agent authenticates with a per-server token stored at `/etc/vantage/config.yaml` (`0600`) - Server stores `SHA-256(agent_token)` — never the plaintext token - Private keys generated by agents are encrypted at rest in MongoDB (AES-256) - `authorized_keys` written as `0600`, owned by root @@ -298,13 +298,13 @@ Build command: ```bash GOOS=linux GOARCH=amd64 go build \ -ldflags="-s -w -X main.Version=${VERSION}" \ - -o dist/keymanager-agent-linux-amd64 ./cmd + -o dist/vantage-agent-linux-amd64 ./cmd ``` Release assets: -- `keymanager-agent-linux-amd64` -- `keymanager-agent-linux-arm64` +- `vantage-agent-linux-amd64` +- `vantage-agent-linux-arm64` - `checksums.txt` ### Server deploy — `.gitea/workflows/server-deploy.yml` @@ -312,7 +312,7 @@ Release assets: Triggered on pushes to `main` touching `server/**`, `web/**`, or `proto/**`. Builds and pushes Docker images to the Gitea container registry, then deploys via SSH: ```bash -cd /opt/keymanager && docker compose pull && docker compose up -d --remove-orphans +cd /opt/vantage && docker compose pull && docker compose up -d --remove-orphans ``` ### Tagging convention diff --git a/deploy/agent.service b/deploy/agent.service index 08eaed8..60699fd 100644 --- a/deploy/agent.service +++ b/deploy/agent.service @@ -1,18 +1,18 @@ [Unit] -Description=KeyManager Agent -Documentation=https://github.com/your-org/keymanager +Description=Vantage Agent +Documentation=https://github.com/your-org/vantage After=network.target Wants=network-online.target [Service] Type=simple -ExecStart=/usr/local/bin/keymanager-agent +ExecStart=/usr/local/bin/vantage-agent Restart=always RestartSec=10 User=root StandardOutput=journal StandardError=journal -SyslogIdentifier=keymanager-agent +SyslogIdentifier=vantage-agent # Security hardening NoNewPrivileges=true diff --git a/deploy/docker-compose.migrate.yml b/deploy/docker-compose.migrate.yml new file mode 100644 index 0000000..65221bf --- /dev/null +++ b/deploy/docker-compose.migrate.yml @@ -0,0 +1,17 @@ +services: + migrate: + image: mongo:8 + depends_on: + mongo: + condition: service_healthy + volumes: + - ./migrate/server-migrate.sh:/migrate.sh:ro + command: bash /migrate.sh + environment: + MONGO_HOST: mongo + MONGO_PORT: "27017" + SRC_DB: keymanager + DST_DB: vantage + # Set DROP_SRC=true to automatically drop the keymanager database after migration + DROP_SRC: "false" + restart: "no" diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index f0a30a8..25bab5a 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -31,7 +31,7 @@ services: - "8080:8080" - "9090:9090" environment: - MONGO_URI: mongodb://mongo:27017/keymanager + MONGO_URI: mongodb://mongo:27017/vantage REDIS_ADDR: redis:6379 GITEA_HOST: ${GITEA_HOST} PUBLIC_HOST: ${PUBLIC_HOST} diff --git a/deploy/migrate/agent-migrate.sh b/deploy/migrate/agent-migrate.sh new file mode 100644 index 0000000..001d6a4 --- /dev/null +++ b/deploy/migrate/agent-migrate.sh @@ -0,0 +1,219 @@ +#!/usr/bin/env bash +# Migrates an existing keymanager-agent installation to vantage-agent. +# Run as root on each managed server. + +set -euo pipefail + +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' +info() { echo -e "${GREEN}[migrate]${NC} $*"; } +warn() { echo -e "${YELLOW}[migrate]${NC} $*"; } +die() { echo -e "${RED}[migrate]${NC} $*" >&2; exit 1; } + +[ "$(id -u)" -eq 0 ] || die "Must be run as root" + +GITEA_HOST="${GITEA_HOST:-}" +GITEA_OWNER="${GITEA_OWNER:-}" + +# --------------------------------------------------------------------------- +# 1. Detect old installation +# --------------------------------------------------------------------------- +OLD_BINARY="/usr/local/bin/keymanager-agent" +OLD_CONFIG_DIR="/etc/keymanager" +OLD_CONFIG="$OLD_CONFIG_DIR/config.yaml" +OLD_SERVICE="keymanager-agent" +OLD_SERVICE_FILE="/etc/systemd/system/${OLD_SERVICE}.service" +OLD_SSH_CONF="/root/.ssh/keymanager.conf" +OLD_SSH_CONFIG="/root/.ssh/config" + +NEW_BINARY="/usr/local/bin/vantage-agent" +NEW_CONFIG_DIR="/etc/vantage" +NEW_CONFIG="$NEW_CONFIG_DIR/config.yaml" +NEW_SERVICE="vantage-agent" +NEW_SERVICE_FILE="/etc/systemd/system/${NEW_SERVICE}.service" +NEW_SSH_CONF="/root/.ssh/vantage.conf" + +if [ ! -f "$OLD_CONFIG" ] && [ ! -f "$OLD_BINARY" ]; then + warn "No keymanager-agent installation found — nothing to migrate." + exit 0 +fi + +info "Found keymanager-agent installation. Starting migration to vantage-agent..." + +# --------------------------------------------------------------------------- +# 2. Stop and disable old service +# --------------------------------------------------------------------------- +if systemctl is-active --quiet "$OLD_SERVICE" 2>/dev/null; then + info "Stopping $OLD_SERVICE..." + systemctl stop "$OLD_SERVICE" +fi +if systemctl is-enabled --quiet "$OLD_SERVICE" 2>/dev/null; then + systemctl disable "$OLD_SERVICE" +fi + +# --------------------------------------------------------------------------- +# 3. Migrate config directory +# --------------------------------------------------------------------------- +if [ -f "$OLD_CONFIG" ] && [ ! -f "$NEW_CONFIG" ]; then + info "Migrating config: $OLD_CONFIG -> $NEW_CONFIG" + mkdir -p "$NEW_CONFIG_DIR" + chmod 0700 "$NEW_CONFIG_DIR" + cp "$OLD_CONFIG" "$NEW_CONFIG" + chmod 0600 "$NEW_CONFIG" +elif [ -f "$NEW_CONFIG" ]; then + warn "$NEW_CONFIG already exists — skipping config copy." +fi + +# --------------------------------------------------------------------------- +# 4. Migrate SSH managed conf file +# --------------------------------------------------------------------------- +if [ -f "$OLD_SSH_CONF" ]; then + info "Migrating SSH conf: $OLD_SSH_CONF -> $NEW_SSH_CONF" + + # Rewrite IdentityFile paths: /root/.ssh/keymanager_* -> /root/.ssh/vantage_* + sed 's|/root/\.ssh/keymanager_|/root/.ssh/vantage_|g' "$OLD_SSH_CONF" > "$NEW_SSH_CONF" + chmod 0600 "$NEW_SSH_CONF" +fi + +# Update Include directive in /root/.ssh/config +if [ -f "$OLD_SSH_CONFIG" ]; then + if grep -q "Include /root/.ssh/keymanager.conf" "$OLD_SSH_CONFIG"; then + info "Updating Include directive in $OLD_SSH_CONFIG" + sed -i 's|Include /root/\.ssh/keymanager\.conf|Include /root/.ssh/vantage.conf|g' "$OLD_SSH_CONFIG" + fi +fi + +# --------------------------------------------------------------------------- +# 5. Rename generated key files +# --------------------------------------------------------------------------- +shopt -s nullglob +OLD_KEYS=(/root/.ssh/keymanager_*) +if [ ${#OLD_KEYS[@]} -gt 0 ]; then + info "Renaming ${#OLD_KEYS[@]} key file(s)..." + for old_path in "${OLD_KEYS[@]}"; do + filename=$(basename "$old_path") + new_filename="${filename/keymanager_/vantage_}" + new_path="/root/.ssh/$new_filename" + if [ ! -e "$new_path" ]; then + cp "$old_path" "$new_path" + chmod "$(stat -c '%a' "$old_path")" "$new_path" + info " $old_path -> $new_path" + else + warn " $new_path already exists — skipping" + fi + done +fi +shopt -u nullglob + +# --------------------------------------------------------------------------- +# 6. Download new vantage-agent binary +# --------------------------------------------------------------------------- +ARCH="$(uname -m)" +case "$ARCH" in + x86_64) ARCH="amd64" ;; + aarch64) ARCH="arm64" ;; + *) die "Unsupported architecture: $ARCH" ;; +esac + +if [ -n "$GITEA_HOST" ] && [ -n "$GITEA_OWNER" ]; then + info "Fetching latest vantage-agent release from $GITEA_HOST..." + + RELEASE_JSON=$(curl -fsSL "https://${GITEA_HOST}/api/v1/repos/${GITEA_OWNER}/vantage/releases?limit=1&type=tag" 2>/dev/null || echo "") + + if [ -n "$RELEASE_JSON" ]; then + DOWNLOAD_URL=$(echo "$RELEASE_JSON" | grep -o "\"browser_download_url\":\"[^\"]*vantage-agent-linux-${ARCH}\"" | head -1 | cut -d'"' -f4) + CHECKSUM_URL=$(echo "$RELEASE_JSON" | grep -o "\"browser_download_url\":\"[^\"]*checksums\.txt\"" | head -1 | cut -d'"' -f4) + + if [ -n "$DOWNLOAD_URL" ]; then + info "Downloading $DOWNLOAD_URL..." + TMP_BIN="/tmp/vantage-agent-new" + curl -fsSL -o "$TMP_BIN" "$DOWNLOAD_URL" + + if [ -n "$CHECKSUM_URL" ]; then + TMP_SUMS="/tmp/vantage-checksums.txt" + curl -fsSL -o "$TMP_SUMS" "$CHECKSUM_URL" + EXPECTED=$(grep "vantage-agent-linux-${ARCH}" "$TMP_SUMS" | awk '{print $1}') + ACTUAL=$(sha256sum "$TMP_BIN" | awk '{print $1}') + [ "$EXPECTED" = "$ACTUAL" ] || die "Checksum mismatch! Expected $EXPECTED, got $ACTUAL" + rm -f "$TMP_SUMS" + info "Checksum verified." + fi + + chmod 0755 "$TMP_BIN" + mv "$TMP_BIN" "$NEW_BINARY" + info "Installed $NEW_BINARY" + else + warn "Could not find vantage-agent binary in release — skipping binary install." + fi + else + warn "Could not reach Gitea API — skipping binary download." + fi +elif [ -f "$OLD_BINARY" ]; then + warn "GITEA_HOST/GITEA_OWNER not set — skipping binary download." + warn "You must manually install the vantage-agent binary to $NEW_BINARY before starting the service." +fi + +# --------------------------------------------------------------------------- +# 7. Install new systemd service +# --------------------------------------------------------------------------- +info "Installing $NEW_SERVICE_FILE..." +cat > "$NEW_SERVICE_FILE" <<'EOF' +[Unit] +Description=Vantage Agent +Documentation=https://github.com/your-org/vantage +After=network.target +Wants=network-online.target + +[Service] +Type=simple +ExecStart=/usr/local/bin/vantage-agent +Restart=always +RestartSec=10 +User=root +StandardOutput=journal +StandardError=journal +SyslogIdentifier=vantage-agent +NoNewPrivileges=true +ProtectSystem=false +ProtectHome=false + +[Install] +WantedBy=multi-user.target +EOF + +systemctl daemon-reload +systemctl enable "$NEW_SERVICE" + +# --------------------------------------------------------------------------- +# 8. Start new service (only if binary exists) +# --------------------------------------------------------------------------- +if [ -f "$NEW_BINARY" ]; then + info "Starting $NEW_SERVICE..." + systemctl start "$NEW_SERVICE" + sleep 2 + if systemctl is-active --quiet "$NEW_SERVICE"; then + info "vantage-agent is running." + else + warn "vantage-agent failed to start. Check: journalctl -u vantage-agent" + fi +else + warn "Binary not yet installed — service NOT started." + warn "Install the binary then run: systemctl start vantage-agent" +fi + +# --------------------------------------------------------------------------- +# 9. Clean up old installation +# --------------------------------------------------------------------------- +info "Cleaning up old keymanager-agent files..." +rm -f "$OLD_SERVICE_FILE" +rm -f "$OLD_BINARY" +rm -rf "$OLD_CONFIG_DIR" +rm -f "$OLD_SSH_CONF" + +shopt -s nullglob +for old_key in /root/.ssh/keymanager_*; do + rm -f "$old_key" +done +shopt -u nullglob + +systemctl daemon-reload +info "Migration complete." diff --git a/deploy/migrate/server-migrate.sh b/deploy/migrate/server-migrate.sh new file mode 100644 index 0000000..c4a97e1 --- /dev/null +++ b/deploy/migrate/server-migrate.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +# Runs inside the migration container. +# Copies all collections + indexes from $SRC_DB to $DST_DB, +# verifies document counts, then optionally drops the source. + +set -euo pipefail + +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' +info() { echo -e "${GREEN}[migrate]${NC} $*"; } +warn() { echo -e "${YELLOW}[migrate]${NC} $*"; } +die() { echo -e "${RED}[migrate]${NC} $*" >&2; exit 1; } + +MONGO_HOST="${MONGO_HOST:-mongo}" +MONGO_PORT="${MONGO_PORT:-27017}" +SRC_DB="${SRC_DB:-keymanager}" +DST_DB="${DST_DB:-vantage}" +DROP_SRC="${DROP_SRC:-false}" + +MONGO_URI="mongodb://${MONGO_HOST}:${MONGO_PORT}" + +mongosh_eval() { + local db="$1"; local script="$2" + mongosh --quiet "${MONGO_URI}/${db}" --eval "$script" +} + +# --------------------------------------------------------------------------- +# 1. Wait for MongoDB to be reachable +# --------------------------------------------------------------------------- +info "Waiting for MongoDB at ${MONGO_HOST}:${MONGO_PORT}..." +for i in $(seq 1 30); do + mongosh --quiet "${MONGO_URI}/admin" --eval "db.adminCommand('ping')" >/dev/null 2>&1 && break + [ "$i" -eq 30 ] && die "MongoDB not reachable after 30 attempts." + sleep 2 +done +info "MongoDB is ready." + +# --------------------------------------------------------------------------- +# 2. Check source database +# --------------------------------------------------------------------------- +SRC_COLLECTIONS=$(mongosh_eval admin " + const names = db.getSiblingDB('${SRC_DB}').getCollectionNames(); + print(names.join(',')); +") + +if [ -z "$SRC_COLLECTIONS" ] || [ "$SRC_COLLECTIONS" = "," ]; then + warn "Source database '${SRC_DB}' has no collections — nothing to migrate." + warn "If this is a fresh deployment, '${DST_DB}' will be created automatically." + exit 0 +fi + +info "Collections in '${SRC_DB}': ${SRC_COLLECTIONS}" + +# --------------------------------------------------------------------------- +# 3. Copy all collections via \$out +# --------------------------------------------------------------------------- +info "Copying collections from '${SRC_DB}' to '${DST_DB}'..." + +mongosh_eval admin " + const src = db.getSiblingDB('${SRC_DB}'); + const cols = src.getCollectionNames(); + cols.forEach(function(name) { + src[name].aggregate([{ \\\$out: { db: '${DST_DB}', coll: name } }]); + print('Copied: ' + name); + }); +" + +# --------------------------------------------------------------------------- +# 4. Recreate indexes +# --------------------------------------------------------------------------- +info "Recreating indexes in '${DST_DB}'..." + +mongosh_eval admin " + const src = db.getSiblingDB('${SRC_DB}'); + const dst = db.getSiblingDB('${DST_DB}'); + src.getCollectionNames().forEach(function(col) { + src[col].getIndexes().forEach(function(idx) { + if (idx.name === '_id_') return; + const opts = { name: idx.name }; + if (idx.unique) opts.unique = true; + if (idx.sparse) opts.sparse = true; + if (idx.expireAfterSeconds !== undefined) opts.expireAfterSeconds = idx.expireAfterSeconds; + try { + dst[col].createIndex(idx.key, opts); + print('Index: ' + col + '.' + idx.name); + } catch(e) { + print('Skipped index ' + idx.name + ' on ' + col + ': ' + e.message); + } + }); + }); +" + +# --------------------------------------------------------------------------- +# 5. Verify document counts +# --------------------------------------------------------------------------- +info "Verifying document counts..." + +MISMATCH=0 +IFS=',' read -ra COLS <<< "$SRC_COLLECTIONS" +for col in "${COLS[@]}"; do + [ -z "$col" ] && continue + SRC_N=$(mongosh_eval "$SRC_DB" "print(db['${col}'].countDocuments())") + DST_N=$(mongosh_eval "$DST_DB" "print(db['${col}'].countDocuments())") + if [ "$SRC_N" = "$DST_N" ]; then + info " ${col}: ${SRC_N} docs OK" + else + warn " ${col}: src=${SRC_N} dst=${DST_N} MISMATCH" + MISMATCH=1 + fi +done + +[ "$MISMATCH" -eq 1 ] && die "Count mismatch — source database NOT dropped. Investigate and re-run." + +# --------------------------------------------------------------------------- +# 6. Optionally drop source database +# --------------------------------------------------------------------------- +if [ "$DROP_SRC" = "true" ]; then + info "Dropping source database '${SRC_DB}'..." + mongosh_eval admin "db.getSiblingDB('${SRC_DB}').dropDatabase(); print('Dropped.');" + info "Dropped '${SRC_DB}'." +else + warn "Source database '${SRC_DB}' kept. Set DROP_SRC=true to drop it automatically." +fi + +info "Migration complete." diff --git a/proto/keymanager/v1/keymanager.proto b/proto/vantage/v1/vantage.proto similarity index 94% rename from proto/keymanager/v1/keymanager.proto rename to proto/vantage/v1/vantage.proto index 0182edf..ca6662b 100644 --- a/proto/keymanager/v1/keymanager.proto +++ b/proto/vantage/v1/vantage.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -package keymanager.v1; +package vantage.v1; -option go_package = "github.com/mrhid6/keymanager/server/internal/grpc/pb"; +option go_package = "github.com/mrhid6/vantage/server/internal/grpc/pb"; -service KeyManager { +service Vantage { rpc Register(RegisterRequest) returns (RegisterResponse); rpc SyncKeys(SyncRequest) returns (SyncResponse); rpc UploadGeneratedKey(UploadKeyRequest) returns (UploadKeyResponse); diff --git a/server/Dockerfile b/server/Dockerfile index 3b207dc..89ad212 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -11,14 +11,14 @@ RUN go mod download COPY . . ARG VERSION=dev -RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w -X main.Version=${VERSION}" -o /keymanager-server ./cmd +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w -X main.Version=${VERSION}" -o /vantage-server ./cmd # Runtime stage FROM scratch COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -COPY --from=builder /keymanager-server /keymanager-server +COPY --from=builder /vantage-server /vantage-server EXPOSE 8080 9090 -ENTRYPOINT ["/keymanager-server"] +ENTRYPOINT ["/vantage-server"] diff --git a/server/cmd/main.go b/server/cmd/main.go index c18abf6..2468120 100644 --- a/server/cmd/main.go +++ b/server/cmd/main.go @@ -7,16 +7,16 @@ import ( "time" "github.com/gin-gonic/gin" - "github.com/mrhid6/keymanager/server/internal/api" - "github.com/mrhid6/keymanager/server/internal/auth" - "github.com/mrhid6/keymanager/server/internal/db" - grpcserver "github.com/mrhid6/keymanager/server/internal/grpc" - "github.com/mrhid6/keymanager/server/internal/services" + "github.com/mrhid6/vantage/server/internal/api" + "github.com/mrhid6/vantage/server/internal/auth" + "github.com/mrhid6/vantage/server/internal/db" + grpcserver "github.com/mrhid6/vantage/server/internal/grpc" + "github.com/mrhid6/vantage/server/internal/services" ) func main() { mongoURI := getEnv("MONGO_URI", "mongodb://localhost:27017") - dbName := getEnv("MONGO_DB", "keymanager") + dbName := getEnv("MONGO_DB", "vantage") if err := db.Connect(mongoURI, dbName); err != nil { log.Fatalf("failed to connect to MongoDB: %v", err) diff --git a/server/go.mod b/server/go.mod index 83305ff..0ab0e14 100644 --- a/server/go.mod +++ b/server/go.mod @@ -1,4 +1,4 @@ -module github.com/mrhid6/keymanager/server +module github.com/mrhid6/vantage/server go 1.26 diff --git a/server/internal/api/handlers.go b/server/internal/api/handlers.go index bc1e434..e322601 100644 --- a/server/internal/api/handlers.go +++ b/server/internal/api/handlers.go @@ -6,9 +6,9 @@ import ( "os" "github.com/gin-gonic/gin" - "github.com/mrhid6/keymanager/server/internal/auth" - "github.com/mrhid6/keymanager/server/internal/models" - "github.com/mrhid6/keymanager/server/internal/services" + "github.com/mrhid6/vantage/server/internal/auth" + "github.com/mrhid6/vantage/server/internal/models" + "github.com/mrhid6/vantage/server/internal/services" ) func RegisterRoutes(r *gin.Engine) { @@ -81,7 +81,7 @@ func newServer(c *gin.Context) { } host := os.Getenv("PUBLIC_HOST") if host == "" { - host = "https://keymanager.example.com" + host = "https://vantage.example.com" } installCmd := fmt.Sprintf( @@ -309,7 +309,7 @@ case "$ARCH" in esac # Get latest agent release tag -LATEST=$(curl -fsSL "https://${GITEA_HOST}/api/v1/repos/mrhid6/keymanager/releases?limit=10" \ +LATEST=$(curl -fsSL "https://${GITEA_HOST}/api/v1/repos/mrhid6/vantage/releases?limit=10" \ | grep -o '"tag_name":"agent/v[^"]*"' | head -1 | sed 's/"tag_name":"//;s/"//') if [ -z "$LATEST" ]; then @@ -319,27 +319,27 @@ fi VERSION="${LATEST#agent/}" LATEST_ENCODED="${LATEST/\//%%2F}" -BINARY_URL="https://${GITEA_HOST}/mrhid6/keymanager/releases/download/${LATEST_ENCODED}/keymanager-agent-linux-${ARCH}" -CHECKSUM_URL="https://${GITEA_HOST}/mrhid6/keymanager/releases/download/${LATEST_ENCODED}/checksums.txt" +BINARY_URL="https://${GITEA_HOST}/mrhid6/vantage/releases/download/${LATEST_ENCODED}/vantage-agent-linux-${ARCH}" +CHECKSUM_URL="https://${GITEA_HOST}/mrhid6/vantage/releases/download/${LATEST_ENCODED}/checksums.txt" -echo "Updating keymanager-agent to ${VERSION} (${ARCH})..." +echo "Updating vantage-agent to ${VERSION} (${ARCH})..." -curl -fsSL -o /tmp/keymanager-agent "${BINARY_URL}" +curl -fsSL -o /tmp/vantage-agent "${BINARY_URL}" curl -fsSL -o /tmp/checksums.txt "${CHECKSUM_URL}" cd /tmp -EXPECTED=$(grep "keymanager-agent-linux-${ARCH}" checksums.txt | awk '{print $1}') -ACTUAL=$(sha256sum keymanager-agent | awk '{print $1}') +EXPECTED=$(grep "vantage-agent-linux-${ARCH}" checksums.txt | awk '{print $1}') +ACTUAL=$(sha256sum vantage-agent | awk '{print $1}') if [ "$EXPECTED" != "$ACTUAL" ]; then echo "Checksum mismatch!" >&2 exit 1 fi -systemctl stop keymanager-agent || true -install -m 0755 /tmp/keymanager-agent /usr/local/bin/keymanager-agent -systemctl start keymanager-agent +systemctl stop vantage-agent || true +install -m 0755 /tmp/vantage-agent /usr/local/bin/vantage-agent +systemctl start vantage-agent -echo "keymanager-agent updated to ${VERSION} and restarted." +echo "vantage-agent updated to ${VERSION} and restarted." `, giteaHost) c.Header("Content-Type", "text/x-shellscript") @@ -356,7 +356,7 @@ func handleInstallScript(c *gin.Context) { } publicHost := os.Getenv("PUBLIC_HOST") if publicHost == "" { - publicHost = "keymanager.example.com" + publicHost = "vantage.example.com" } grpcHost := os.Getenv("GRPC_HOST") if grpcHost == "" { @@ -384,7 +384,7 @@ case "$ARCH" in esac # Get latest agent release tag -LATEST=$(curl -fsSL "https://${GITEA_HOST}/api/v1/repos/mrhid6/keymanager/releases?limit=10" \ +LATEST=$(curl -fsSL "https://${GITEA_HOST}/api/v1/repos/mrhid6/vantage/releases?limit=10" \ | grep -o '"tag_name":"agent/v[^"]*"' | head -1 | sed 's/"tag_name":"//;s/"//') if [ -z "$LATEST" ]; then @@ -394,28 +394,28 @@ fi VERSION="${LATEST#agent/}" LATEST_ENCODED="${LATEST/\//%%2F}" -BINARY_URL="https://${GITEA_HOST}/mrhid6/keymanager/releases/download/${LATEST_ENCODED}/keymanager-agent-linux-${ARCH}" -CHECKSUM_URL="https://${GITEA_HOST}/mrhid6/keymanager/releases/download/${LATEST_ENCODED}/checksums.txt" +BINARY_URL="https://${GITEA_HOST}/mrhid6/vantage/releases/download/${LATEST_ENCODED}/vantage-agent-linux-${ARCH}" +CHECKSUM_URL="https://${GITEA_HOST}/mrhid6/vantage/releases/download/${LATEST_ENCODED}/checksums.txt" -echo "Installing keymanager-agent ${VERSION} (${ARCH})..." +echo "Installing vantage-agent ${VERSION} (${ARCH})..." -curl -fsSL -o /tmp/keymanager-agent "${BINARY_URL}" +curl -fsSL -o /tmp/vantage-agent "${BINARY_URL}" curl -fsSL -o /tmp/checksums.txt "${CHECKSUM_URL}" cd /tmp -EXPECTED=$(grep "keymanager-agent-linux-${ARCH}" checksums.txt | awk '{print $1}') -ACTUAL=$(sha256sum keymanager-agent | awk '{print $1}') +EXPECTED=$(grep "vantage-agent-linux-${ARCH}" checksums.txt | awk '{print $1}') +ACTUAL=$(sha256sum vantage-agent | awk '{print $1}') if [ "$EXPECTED" != "$ACTUAL" ]; then echo "Checksum mismatch!" >&2 exit 1 fi -install -m 0755 /tmp/keymanager-agent /usr/local/bin/keymanager-agent +install -m 0755 /tmp/vantage-agent /usr/local/bin/vantage-agent -mkdir -p /etc/keymanager -chmod 0700 /etc/keymanager +mkdir -p /etc/vantage +chmod 0700 /etc/vantage -cat > /etc/keymanager/config.yaml < /etc/vantage/config.yaml < /etc/systemd/system/keymanager-agent.service < /etc/systemd/system/vantage-agent.service <

Add Server

- Generate an install command to register a new server with the KeyManager agent. + Generate an install command to register a new server with the Vantage agent.

@@ -39,7 +39,7 @@ export default function NewServerPage() {

Click the button below to generate a one-time install command. The command contains a short-lived token (valid for 1 hour) that registers your server - and installs the KeyManager agent automatically. + and installs the Vantage agent automatically.

{error && ( @@ -111,8 +111,8 @@ export default function NewServerPage() { {[ "The install script detects your CPU architecture (amd64 / arm64)", "Downloads and verifies the latest agent binary from the Gitea release", - "Writes /etc/keymanager/config.yaml with the server ID and token", - "Installs and starts the keymanager-agent systemd service", + "Writes /etc/vantage/config.yaml with the server ID and token", + "Installs and starts the vantage-agent systemd service", "The agent calls Register() to obtain a persistent auth token", "The server status changes to active on the first successful sync", ].map((step, i) => ( diff --git a/web/components/Sidebar.tsx b/web/components/Sidebar.tsx index 0353f3a..c38d20e 100644 --- a/web/components/Sidebar.tsx +++ b/web/components/Sidebar.tsx @@ -44,7 +44,7 @@ export function Sidebar() { - KeyManager + Vantage