+
{ca.active_certs}
Active certs
@@ -157,10 +157,7 @@ AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
{ca.default_cert_validity_hours}h
Default validity
-
-
{ca.next_serial_number ?? "—"}
-
Next serial
-
+
)}
diff --git a/src/pages/user/CLIGuidePage.tsx b/src/pages/user/CLIGuidePage.tsx
new file mode 100644
index 0000000..b7f3f75
--- /dev/null
+++ b/src/pages/user/CLIGuidePage.tsx
@@ -0,0 +1,202 @@
+import { useState } from "react";
+import { Terminal, Copy, CheckCircle, ChevronDown, ChevronRight } from "lucide-react";
+import { useToast } from "@/hooks/use-toast";
+import {
+ Collapsible,
+ CollapsibleContent,
+ CollapsibleTrigger,
+} from "@/components/ui/collapsible";
+
+const SIGN_URL = "https://api.secuird.tech";
+
+// ── Code block with copy button ────────────────────────────────────────────────
+function CodeBlock({ code }: { code: string }) {
+ const [copied, setCopied] = useState(false);
+ const { toast } = useToast();
+
+ const handleCopy = async () => {
+ try {
+ await navigator.clipboard.writeText(code);
+ setCopied(true);
+ toast({ title: "Copied!" });
+ setTimeout(() => setCopied(false), 2000);
+ } catch {
+ toast({ variant: "destructive", title: "Copy failed" });
+ }
+ };
+
+ return (
+
+
+ {copied
+ ?
+ : }
+
+
+ {code}
+
+
+ );
+}
+
+// ── Numbered step ──────────────────────────────────────────────────────────────
+function Step({ n, title, children }: { n: number; title: string; children: React.ReactNode }) {
+ return (
+
+ );
+}
+
+// ── Collapsible FAQ item ───────────────────────────────────────────────────────
+function FaqItem({ q, children }: { q: string; children: React.ReactNode }) {
+ const [open, setOpen] = useState(false);
+ return (
+
+
+ {open
+ ?
+ : }
+ {q}
+
+
+ {children}
+
+
+ );
+}
+
+// ── Main page ──────────────────────────────────────────────────────────────────
+export default function CLIGuidePage() {
+ return (
+
+ {/* Header */}
+
+
+
+
Secuird CLI
+
+
+ Sign your SSH key from the command line. Browser login happens once — token is cached.
+
+
+
+
+
+ {/* Setup steps */}
+
+
Setup
+
+
+
+
+
+
+
+ Creates an isolated virtualenv so nothing pollutes your system Python.
+
+ Install dependencies
+
+ Create the secuird command
+ ~/.local/bin/secuird << 'EOF'\n#!/usr/bin/env bash\nexec ~/.secuird/venv/bin/python ~/.secuird/secuird-cli.py "$@"\nEOF\n\nchmod +x ~/.local/bin/secuird\n\necho 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc\nsource ~/.bashrc`} />
+
+
+
+ ~/.secuird/.env`} />
+
+
+
+
+ Your browser will open for login. Token is cached after first login.
+
+
+
+
+ Certificate saved to /tmp/ssh-cert. Re-run when it expires.
+
+
+
+
+
+
+
+
+
+ {/* Commands reference */}
+
+
Commands
+
+ {[
+ ["--request-cert", "-r", "Request / renew a signed SSH certificate"],
+ ["--add-key -k
", "-a", "Upload & verify an SSH public key"],
+ ["--list-keys", "", "List your registered SSH keys"],
+ ["--remove-key [id]", "", "Remove a key (interactive if no ID)"],
+ ["--check-cert", "-c", "Exit 0 if cert valid, 1 if expired/missing"],
+ ["--force", "-f", "Force renewal even if cert is still valid"],
+ ["--clear-cache", "", "Delete cached auth token"],
+ ].map(([flag, short, desc]) => (
+
+ {flag}
+ {short
+ ? {short}
+ : }
+ {desc}
+
+ ))}
+
+
+
+
+
+ {/* FAQ */}
+
+
FAQ
+
+
+ No — the token is cached at ~/.secuird/token_cache.json and reused until it expires.
+
+
+ The CLI listens on port 8250 locally. Make sure nothing else is using that port and complete the login before closing the tab.
+
+
+ Run secuird --add-key -k ~/.ssh/id_ed25519.pub then check with secuird --list-keys.
+
+
+ > ~/.bashrc && source ~/.bashrc`} />
+
+
+ You can use a cron job to automatically renew your certificate before it expires. Run secuird --request-cert interactively at least once first so a cached token exists.
+
+
+
+
+ {/* Footer */}
+
+
+ View source on GitHub
+
+ {" · "}
+
+ Manage SSH keys in the UI
+
+
+
+
+
+ );
+}
diff --git a/src/pages/user/SSHKeysPage.tsx b/src/pages/user/SSHKeysPage.tsx
index e8ff568..b924449 100644
--- a/src/pages/user/SSHKeysPage.tsx
+++ b/src/pages/user/SSHKeysPage.tsx
@@ -824,9 +824,6 @@ TrustedUserCAKeys /etc/ssh/trusted_user_ca`}
className="font-mono text-xs pr-10"
rows={6}
/>
-
- /tmp/challenge.txt\nssh-keygen -Y sign \\\n -f ~/.ssh/id_ed25519 \\\n -n file \\\n /tmp/challenge.txt\ncat /tmp/challenge.txt.sig | base64 -w0`} />
-