Support Vault auth for monitors (#1004)

This commit is contained in:
ZacharyZcR
2026-07-10 08:01:57 +08:00
committed by GitHub
parent 579c5c675c
commit 017be33974
4 changed files with 62 additions and 1 deletions
+11
View File
@@ -104,6 +104,7 @@ interface SSHHostWithCredentials {
rdpPort?: number; rdpPort?: number;
vncPort?: number; vncPort?: number;
telnetPort?: number; telnetPort?: number;
vaultProfile?: { id?: number | null } | null;
} }
type StatusEntry = { type StatusEntry = {
@@ -1128,6 +1129,8 @@ async function buildSshConfig(
// no credentials needed // no credentials needed
} else if (host.authType === "opkssh") { } else if (host.authType === "opkssh") {
// cert auth setup happens in createSshFactory (needs client instance) // cert auth setup happens in createSshFactory (needs client instance)
} else if (host.authType === "vault") {
// cert auth setup happens in createSshFactory (needs client instance)
} else if (host.authType === "credential") { } else if (host.authType === "credential") {
if (host.password) { if (host.password) {
base.password = host.password; base.password = host.password;
@@ -1186,6 +1189,10 @@ function createSshFactory(host: SSHHostWithCredentials): () => Promise<Client> {
} }
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js"); const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
await setupOPKSSHCertAuth(config, client, token, host.username); await setupOPKSSHCertAuth(config, client, token, host.username);
} else if (host.authType === "vault") {
const { setupVaultSshSignerAuth } =
await import("./vault-ssh-connect.js");
await setupVaultSshSignerAuth(config, client, host);
} }
const proxyConfig: SOCKS5Config | null = const proxyConfig: SOCKS5Config | null =
@@ -2070,6 +2077,10 @@ app.post("/metrics/start/:id", validateHostId, async (req, res) => {
} }
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js"); const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
await setupOPKSSHCertAuth(config, client, token, host.username); await setupOPKSSHCertAuth(config, client, token, host.username);
} else if (host.authType === "vault") {
const { setupVaultSshSignerAuth } =
await import("./vault-ssh-connect.js");
await setupVaultSshSignerAuth(config, client, host);
} }
const connectionPromise = new Promise<{ const connectionPromise = new Promise<{
+8
View File
@@ -95,6 +95,8 @@ async function buildSshConfig(host: SSHHost): Promise<ConnectConfig> {
} }
} else if (host.authType === "none") { } else if (host.authType === "none") {
// no credentials needed // no credentials needed
} else if (host.authType === "vault") {
// cert auth setup happens in connectToHost (needs client instance)
} else if (host.authType === "agent") { } else if (host.authType === "agent") {
const result = await applyAgentAuth( const result = await applyAgentAuth(
base as Record<string, unknown>, base as Record<string, unknown>,
@@ -118,6 +120,12 @@ export function connectToHost(host: SSHHost): () => Promise<Client> {
const config = await buildSshConfig(host); const config = await buildSshConfig(host);
const client = new Client(); const client = new Client();
if (host.authType === "vault") {
const { setupVaultSshSignerAuth } =
await import("./vault-ssh-connect.js");
await setupVaultSshSignerAuth(config, client, host);
}
const proxyConfig: SOCKS5Config | null = const proxyConfig: SOCKS5Config | null =
host.useSocks5 && host.useSocks5 &&
(host.socks5Host || (host.socks5Host ||
+39
View File
@@ -0,0 +1,39 @@
import type { Client, ConnectConfig } from "ssh2";
type VaultAuthHost = {
id: number;
username: string;
userId?: string | null;
vaultProfile?: { id?: number | null } | null;
};
export async function setupVaultSshSignerAuth(
config: ConnectConfig,
client: Client,
host: VaultAuthHost,
): Promise<void> {
if (!host.userId) {
throw new Error("Vault SSH signer authentication requires a user session");
}
const vaultProfileId = host.vaultProfile?.id;
if (!vaultProfileId) {
throw new Error("Host has no Vault signer profile configured");
}
const { getVaultCert } = await import("./vault-signer-auth.js");
const cert = await getVaultCert(host.userId, vaultProfileId);
if (!cert) {
throw new Error(
"Vault SSH signer authentication required. Please open a Terminal connection first.",
);
}
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
await setupOPKSSHCertAuth(
config,
client,
{ privateKey: cert.privateKey, sshCert: cert.sshCert },
host.username,
);
}
+4 -1
View File
@@ -109,7 +109,8 @@ export interface Host {
| "none" | "none"
| "opkssh" | "opkssh"
| "tailscale" | "tailscale"
| "agent"; | "agent"
| "vault";
useWarpgate?: boolean; useWarpgate?: boolean;
password?: string; password?: string;
key?: string; key?: string;
@@ -123,6 +124,8 @@ export interface Host {
autostartKeyPassword?: string; autostartKeyPassword?: string;
credentialId?: number; credentialId?: number;
vaultProfileId?: number | null;
vaultProfile?: { id?: number | null };
overrideCredentialUsername?: boolean; overrideCredentialUsername?: boolean;
userId?: string; userId?: string;
enableTerminal: boolean; enableTerminal: boolean;