feat: Step CA SSH certificates as a host authentication type (#1340)

* feat: Step CA SSH certificates as a host authentication type

Issue short-lived SSH user certificates from a smallstep CA through its
OIDC provisioner, over the CA's HTTP API rather than the step binary.
Everything after issuance reuses the OPKSSH plumbing: the same encrypted
per-user/host token store, WebSocket dialog and ssh2 certificate
injection, with the connect paths branching on a shared
usesIssuedCertificate() predicate. Instance-wide CA settings live in the
admin panel, with a private-host allowlist for the SSRF guard.

* fix: harden Step CA callback flow

* style: format Step CA changes
This commit is contained in:
ZacharyZcR
2026-08-25 02:56:44 +08:00
committed by GitHub
parent 0ab7cf2ab8
commit 32d77fc6d0
38 changed files with 1791 additions and 48 deletions
+4
View File
@@ -270,6 +270,8 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
stage: "chooser" | "waiting" | "authenticating" | "completed" | "error";
error?: string;
providers?: Array<{ alias: string; issuer: string }>;
/** Which issuer is asking (OPKSSH by default, "Step CA", ...). */
label?: string;
} | null>(null);
const opksshTimeoutRef = useRef<NodeJS.Timeout | null>(null);
@@ -1823,6 +1825,7 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
requestId: msg.requestId || "",
stage: "chooser",
providers: msg.providers,
label: typeof msg.label === "string" ? msg.label : undefined,
});
if (opksshTimeoutRef.current) {
clearTimeout(opksshTimeoutRef.current);
@@ -3598,6 +3601,7 @@ const TerminalInner = forwardRef<TerminalHandle, SSHTerminalProps>(
stage={opksshDialog.stage}
error={opksshDialog.error}
providers={opksshDialog.providers}
label={opksshDialog.label}
onCancel={() => {
if (webSocketRef.current) {
webSocketRef.current.send(