feat: initial jump-host — SSH jump host for the theta42 stack
An SSH jump host that authenticates users against the shared LDAP directory, authorizes them from the SSO Manager's inventory graph, and bridges them to downstream hosts — auditing everything. - Username-grammar routing (uid_-_target@jump) + interactive TUI picker - Inbound LDAP auth (publickey / password with off|local|all policy) - Directory-driven access (LDAP groups x /api/discovery/resources?group=) - Per-user key injection into sshPublicKey, connects downstream as the user - Shell / exec / SFTP-subsystem bridging (WinSCP works) - Web UI + HTTP API (:3002) for audit + metrics; LDAP-admin gated - Packaged like proxy: ops/install.sh + systemd, all-in-one Docker, compose - Tests: 23 unit + 3 integration (node --test), all green Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
:root { --bg:#0f1115; --panel:#181b22; --line:#272b34; --fg:#e6e8ec; --mut:#8b93a1; --acc:#4f9cf9; --bad:#ff6b6b; --ok:#4ec9a5; }
|
||||
* { box-sizing: border-box; }
|
||||
body { margin:0; font:14px/1.5 -apple-system,Segoe UI,Roboto,sans-serif; background:var(--bg); color:var(--fg); }
|
||||
a { color:var(--acc); text-decoration:none; } a:hover { text-decoration:underline; }
|
||||
.nav { display:flex; align-items:center; gap:16px; padding:12px 20px; background:var(--panel); border-bottom:1px solid var(--line); }
|
||||
.brand { font-weight:600; } .brand small { color:var(--mut); font-weight:400; }
|
||||
.nav .spacer { flex:1; } .nav .who { color:var(--mut); }
|
||||
.wrap { max-width:1100px; margin:0 auto; padding:24px 20px; }
|
||||
h1 { font-size:20px; margin:0 0 16px; } h2 { font-size:15px; margin:24px 0 8px; }
|
||||
.tiles { display:flex; gap:16px; flex-wrap:wrap; }
|
||||
.tile { background:var(--panel); border:1px solid var(--line); border-radius:10px; padding:16px 20px; min-width:150px; }
|
||||
.tile .n { display:block; font-size:28px; font-weight:600; } .tile .l { color:var(--mut); }
|
||||
.cols { display:grid; grid-template-columns:2fr 1fr; gap:24px; }
|
||||
@media (max-width:800px){ .cols { grid-template-columns:1fr; } }
|
||||
table { width:100%; border-collapse:collapse; margin-top:8px; }
|
||||
th,td { text-align:left; padding:7px 10px; border-bottom:1px solid var(--line); }
|
||||
th { color:var(--mut); font-weight:500; font-size:12px; text-transform:uppercase; letter-spacing:.03em; }
|
||||
td.r,th.r { text-align:right; }
|
||||
tr.bad td { color:var(--bad); }
|
||||
.muted { color:var(--mut); }
|
||||
.more { font-size:12px; font-weight:400; margin-left:8px; }
|
||||
.foot { max-width:1100px; margin:0 auto; padding:16px 20px; color:var(--mut); font-size:12px; }
|
||||
.filters { display:flex; gap:8px; margin-bottom:12px; flex-wrap:wrap; }
|
||||
.filters input,.filters select,.login input { background:#0c0e12; border:1px solid var(--line); color:var(--fg); border-radius:7px; padding:7px 10px; }
|
||||
button { background:var(--acc); color:#fff; border:0; border-radius:7px; padding:8px 14px; cursor:pointer; font:inherit; }
|
||||
button.link { background:none; color:var(--acc); padding:0; }
|
||||
.inline { display:inline; } .pager { display:flex; gap:16px; align-items:center; margin-top:16px; color:var(--mut); }
|
||||
.center { display:grid; place-items:center; min-height:100vh; }
|
||||
.card.login { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:28px; width:320px; display:flex; flex-direction:column; gap:12px; }
|
||||
.card.login h1 { margin:0 0 8px; } .card.login label { display:flex; flex-direction:column; gap:4px; font-size:13px; color:var(--mut); }
|
||||
.card.login .hint { color:var(--mut); font-size:12px; margin:4px 0 0; } .err { color:var(--bad); margin:0; }
|
||||
Reference in New Issue
Block a user