The start-menu entry ran `hound` with Terminal=true — the CLI, which
printed help and exited. No GUI binary had ever been built or packaged.
Four separate faults were stacked behind that report:
1. build-deb.sh now builds and ships hound-gui, and writes a .desktop
entry only when that binary exists. A launcher for software that is
not there is worse than no launcher.
2. Tray icons were loaded from a relative "icons/" path, which resolves
only from the build tree. Installed to /usr/bin the setup hook failed
and Tauri panicked before a window appeared. They are include_bytes!
now — four ~1 KB PNGs that can no longer be missing.
3. The front-end never ran at all. app.js opened with a bare module
specifier ("@tauri-apps/api/core") and there is no bundler, so the
webview could not resolve it and the script silently failed to parse.
The window rendered its static HTML forever, which looks exactly like
a daemon that never answered. withGlobalTauri + window.__TAURI__.
4. build-deb.sh ran the Tauri build as `>/dev/null 2>&1 || true`, so a
config error scrolled past unseen and the package shipped the
PREVIOUS binary. Two fixes appeared to do nothing. That step is no
longer silenced or tolerant of failure, and the build fails outright
on a bare import in gui/dist/*.js.
Guards, because each of these failed quietly: index.html flips to an
interface-error message if app.js never sets a boot flag within 5s. An
antivirus showing "Protected - your system looks healthy" while its own
front-end is dead is the worst failure mode there is.
Then the window came up and could not reach the daemon: the socket was
0700 root:root. Widening it needed more than a chmod, because
quarantine.restore writes files back out as root — handing that to a
desktop group would hand out root. So the daemon now checks SO_PEERCRED
per method (crates/houndd/src/peer.rs):
- group `hound`: status, settings.get, events, quarantine.list,
rootkit.scan, persistence.scan
- scan/supply.sweep: only paths the caller could read itself, decided
by forking a child, dropping to the peer's uid, gid and
supplementary groups, and asking access(2) — which honours ACLs and
mount options, unlike anything reconstructed from mode bits
- everything that writes: root, or the uid the daemon runs as
Unclassified methods fall into Admin, so a new mutating method fails
closed rather than becoming public by omission. The end-to-end socket
test caught that "root only" broke every developer run; the owner
clause collapses to "root" under the packaged root daemon and is
verified to do so.
CAP_SETUID/CAP_SETGID join the gate capability set for the readability
check. There was a test asserting CAP_SETUID must never be retained —
it is updated with the reasoning rather than deleted. The daemon
already holds CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH, so becoming
another user widens nothing that matters. The unit gains Group=hound so
the socket can be chgrp'd without CAP_CHOWN; it stays uid 0.
Also: the footer claimed "engine: ClamAV via Unix socket". It reports
what the daemon actually loaded, which has been yara-x since the engine
was replaced. Every error path in the front-end goes through explain(),
so a privilege refusal reads as "run it from a terminal: sudo hound …"
rather than "daemon error -32000".
358 tests pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
852 lines
54 KiB
HTML
852 lines
54 KiB
HTML
<!doctype html>
|
|
<html lang="en" data-theme="auto">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Hound — endpoint and supply-chain security for Linux</title>
|
|
<meta name="description" content="Hound blocks a binary before it runs and reads your lockfiles against 235,577 packages that exist only to be malware. Open source agent, Linux-native, built for people who ship software.">
|
|
<link rel="canonical" href="https://houndav.com/">
|
|
<link rel="icon" href="/icons/app-32.png" type="image/png">
|
|
<link rel="apple-touch-icon" href="/icons/app-256.png">
|
|
<meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large">
|
|
<meta name="author" content="Hound">
|
|
<meta name="theme-color" content="#5A58D6">
|
|
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://houndav.com/">
|
|
<meta property="og:site_name" content="Hound">
|
|
<meta property="og:title" content="Hound — endpoint and supply-chain security for Linux">
|
|
<meta property="og:description" content="Blocks a malicious binary before it runs, in 2 ms, and reads your lockfiles against 235,577 packages that exist only to be malware. Open-source agent. Ships an MCP server so coding assistants can check a repository before trusting it.">
|
|
<meta property="og:image" content="https://houndav.com/icons/app-512.png">
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:title" content="Hound — endpoint and supply-chain security for Linux">
|
|
<meta name="twitter:description" content="97% of npm's security records are malware, not bugs. Hound knows 235,577 of them by name.">
|
|
<meta name="twitter:image" content="https://houndav.com/icons/app-512.png">
|
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=IBM+Plex+Sans:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap">
|
|
<style>
|
|
/* ── tokens ──────────────────────────────────────────────────────────
|
|
Light is the bare :root, dark is layered over it twice — once for the
|
|
un-stamped "follow the system" state, once for an explicit choice —
|
|
so all three of auto/light/dark resolve as a complete set. */
|
|
:root {
|
|
--bg: #F7F7FB;
|
|
--raised: #FFFFFF;
|
|
--panel: #FFFFFF;
|
|
--line: #E2E2EC;
|
|
--line-hi: #C9C9DA;
|
|
--fg: #14141C;
|
|
--dim: #55556B;
|
|
--faint: #8A8AA0;
|
|
--brand: #5A58C8;
|
|
--brand-dim: #7B79D8;
|
|
--on-brand: #FFFFFF;
|
|
/* Buttons get their own background rather than reusing --brand. White
|
|
on the dark theme's #9896E0 is 2.70:1, which fails AA outright; this
|
|
is 5.52:1 and lets the label stay white in both themes, which is
|
|
what makes the control read as the same object when you switch. */
|
|
--btn-bg: #5A58C8;
|
|
--btn-bg-hi: #4B49B4;
|
|
--ok: #147A3D;
|
|
--warn: #9A6100;
|
|
--bad: #C22222;
|
|
--code-bg: #F0F0F7;
|
|
--shadow: 0 1px 2px rgb(20 20 28 / .06), 0 8px 24px rgb(20 20 28 / .05);
|
|
--term-bg: #0B0E14;
|
|
--term-fg: #E8ECF4;
|
|
--term-dim: #8B96AB;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
:root:not([data-theme="light"]) {
|
|
--bg: #0B0E14;
|
|
--raised: #12161F;
|
|
--panel: #161B26;
|
|
--line: #232B3A;
|
|
--line-hi: #32405A;
|
|
--fg: #E8ECF4;
|
|
--dim: #8B96AB;
|
|
--faint: #5A6478;
|
|
--brand: #9896E0;
|
|
--brand-dim: #7B79C8;
|
|
--on-brand: #0B0E14;
|
|
--btn-bg: #5A58D6;
|
|
--btn-bg-hi: #6B69E4;
|
|
--ok: #22C55E;
|
|
--warn: #F59E0B;
|
|
--bad: #EF4444;
|
|
--code-bg: #0F131C;
|
|
--shadow: 0 8px 30px rgb(0 0 0 / .45);
|
|
--term-bg: #080B10;
|
|
}
|
|
}
|
|
:root[data-theme="dark"] {
|
|
--bg: #0B0E14;
|
|
--raised: #12161F;
|
|
--panel: #161B26;
|
|
--line: #232B3A;
|
|
--line-hi: #32405A;
|
|
--fg: #E8ECF4;
|
|
--dim: #8B96AB;
|
|
--faint: #5A6478;
|
|
--brand: #9896E0;
|
|
--brand-dim: #7B79C8;
|
|
--on-brand: #0B0E14;
|
|
--btn-bg: #5A58D6;
|
|
--btn-bg-hi: #6B69E4;
|
|
--ok: #22C55E;
|
|
--warn: #F59E0B;
|
|
--bad: #EF4444;
|
|
--code-bg: #0F131C;
|
|
--shadow: 0 8px 30px rgb(0 0 0 / .45);
|
|
--term-bg: #080B10;
|
|
}
|
|
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
html { scroll-behavior: smooth; }
|
|
@media (prefers-reduced-motion: reduce) {
|
|
html { scroll-behavior: auto; }
|
|
* { animation: none !important; transition: none !important; }
|
|
}
|
|
|
|
body {
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
font: 16px/1.65 "IBM Plex Sans", system-ui, -apple-system, sans-serif;
|
|
-webkit-font-smoothing: antialiased;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 24px; }
|
|
|
|
/* Grid and flex children default to min-width:auto, so anything holding
|
|
a long unbreakable string — a terminal block, a curl command — refuses
|
|
to shrink below that string and pushes the whole PAGE sideways instead
|
|
of scrolling inside its own box. This is the single most common cause
|
|
of a layout that is fine on a desktop and broken on a phone. */
|
|
.hero > *, .grid2 > *, .grid3 > *, .tiers > *, .install > *, .stats > * { min-width: 0; }
|
|
.mono { font-family: "JetBrains Mono", ui-monospace, monospace; }
|
|
|
|
a { color: var(--brand); text-decoration: none; }
|
|
a:hover { text-decoration: underline; }
|
|
a:focus-visible, button:focus-visible {
|
|
outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 6px;
|
|
}
|
|
|
|
h1, h2, h3 { font-family: "Space Grotesk", system-ui, sans-serif; letter-spacing: -.02em; text-wrap: balance; }
|
|
p { text-wrap: pretty; }
|
|
|
|
/* ── header ───────────────────────────────────────────────────────── */
|
|
header {
|
|
position: sticky; top: 0; z-index: 20;
|
|
/* Opaque first. A sticky header that falls back to transparent puts
|
|
scrolling content underneath the navigation, which is worse than
|
|
having no blur. color-mix and backdrop-filter are the enhancement. */
|
|
background: var(--bg);
|
|
border-bottom: 1px solid var(--line);
|
|
}
|
|
@supports (backdrop-filter: blur(1px)) and (background: color-mix(in srgb, red 50%, transparent)) {
|
|
header {
|
|
background: color-mix(in srgb, var(--bg) 88%, transparent);
|
|
backdrop-filter: blur(12px);
|
|
}
|
|
}
|
|
.bar { display: flex; align-items: center; gap: 16px; height: 62px; }
|
|
.logo { display: flex; align-items: center; gap: 10px; color: var(--fg); }
|
|
.logo:hover { text-decoration: none; }
|
|
.logo svg { width: 30px; height: 30px; flex: 0 0 auto; }
|
|
.logo b { font: 700 18px/1 "Space Grotesk", system-ui, sans-serif; }
|
|
nav.links { margin-left: auto; display: flex; gap: 22px; align-items: center; }
|
|
nav.links a { color: var(--dim); font-size: 14.5px; font-weight: 500; }
|
|
nav.links a:hover { color: var(--fg); text-decoration: none; }
|
|
|
|
/* Hamburger. Hiding links on a phone was not enough — the theme switch
|
|
and the call to action still competed for a 360px bar and pushed it
|
|
sideways. Below the breakpoint the bar holds the mark and one button,
|
|
and everything else moves into a panel. */
|
|
.menu-btn {
|
|
display: none; appearance: none; border: 1px solid var(--line-hi);
|
|
background: var(--raised); color: var(--fg); cursor: pointer;
|
|
border-radius: 9px; padding: 9px; line-height: 0; margin-left: auto;
|
|
}
|
|
.menu-btn svg { width: 20px; height: 20px; }
|
|
.menu-btn .close { display: none; }
|
|
.menu-btn[aria-expanded="true"] .open { display: none; }
|
|
.menu-btn[aria-expanded="true"] .close { display: block; }
|
|
|
|
/* No display:contents here. An ID beats a class, so it would override
|
|
nav.links's own flex layout and margin-left:auto and quietly unstick
|
|
the desktop navigation from the right-hand side. The panel styles
|
|
belong inside the breakpoint and nowhere else. */
|
|
|
|
@media (max-width: 760px) {
|
|
.menu-btn { display: inline-flex; }
|
|
#menu {
|
|
display: none;
|
|
position: absolute; left: 0; right: 0; top: 100%;
|
|
background: var(--bg); border-bottom: 1px solid var(--line);
|
|
padding: 8px 24px 20px;
|
|
flex-direction: column; align-items: stretch; gap: 4px;
|
|
box-shadow: var(--shadow);
|
|
}
|
|
#menu.open { display: flex; }
|
|
#menu a:not(.btn) {
|
|
padding: 13px 4px; border-bottom: 1px solid var(--line);
|
|
font-size: 16px; color: var(--fg);
|
|
}
|
|
#menu .theme { align-self: flex-start; margin: 14px 0 4px; }
|
|
#menu .btn { justify-content: center; padding: 13px 17px; }
|
|
header { position: sticky; }
|
|
.bar { position: relative; }
|
|
}
|
|
|
|
/* theme switch */
|
|
.theme {
|
|
display: inline-flex; border: 1px solid var(--line-hi); border-radius: 999px;
|
|
padding: 2px; background: var(--raised); gap: 1px;
|
|
}
|
|
.theme button {
|
|
appearance: none; border: 0; background: transparent; cursor: pointer;
|
|
color: var(--faint); padding: 5px 8px; border-radius: 999px; line-height: 0;
|
|
}
|
|
.theme button svg { width: 15px; height: 15px; }
|
|
.theme button[aria-pressed="true"] { background: var(--btn-bg); color: #FFFFFF; }
|
|
|
|
.btn {
|
|
display: inline-flex; align-items: center; gap: 8px;
|
|
background: var(--btn-bg); color: #FFFFFF;
|
|
font: 600 14.5px/1 "IBM Plex Sans", system-ui, sans-serif;
|
|
padding: 11px 17px; border-radius: 9px; border: 1px solid transparent;
|
|
transition: background .15s;
|
|
}
|
|
.btn:hover { background: var(--btn-bg-hi); color: #FFFFFF; text-decoration: none; }
|
|
.btn.ghost { background: transparent; color: var(--fg); border-color: var(--line-hi); }
|
|
.btn.ghost:hover { background: var(--raised); }
|
|
|
|
/* ── hero ─────────────────────────────────────────────────────────── */
|
|
.hero { padding: 84px 0 56px; display: grid; grid-template-columns: 1.05fr .95fr; gap: 56px; align-items: center; }
|
|
@media (max-width: 900px) { .hero { grid-template-columns: 1fr; gap: 36px; padding: 52px 0 36px; } }
|
|
.eyebrow {
|
|
font-family: "JetBrains Mono", ui-monospace, monospace;
|
|
font-size: 12px; letter-spacing: 1.3px; text-transform: uppercase;
|
|
color: var(--brand); margin-bottom: 18px;
|
|
}
|
|
.hero h1 { font-size: clamp(34px, 5.2vw, 54px); line-height: 1.05; font-weight: 700; }
|
|
.hero .lede { color: var(--dim); font-size: 18px; margin: 20px 0 30px; max-width: 52ch; }
|
|
.cta { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
|
|
.cta .note { color: var(--faint); font-size: 13.5px; }
|
|
|
|
/* terminal */
|
|
.term {
|
|
background: var(--term-bg); border: 1px solid var(--line); border-radius: 13px;
|
|
box-shadow: var(--shadow); overflow: hidden; min-width: 0; max-width: 100%;
|
|
}
|
|
.term-bar {
|
|
display: flex; align-items: center; gap: 9px; padding: 10px 14px;
|
|
border-bottom: 1px solid rgb(255 255 255 / .07);
|
|
font: 500 11.5px/1 "JetBrains Mono", monospace; color: var(--term-dim);
|
|
}
|
|
.term-bar i { width: 9px; height: 9px; border-radius: 50%; background: #32405A; display: inline-block; }
|
|
.term pre {
|
|
margin: 0; padding: 16px 18px 20px; overflow-x: auto; max-width: 100%;
|
|
font: 12.5px/1.75 "JetBrains Mono", ui-monospace, monospace;
|
|
color: var(--term-fg);
|
|
}
|
|
.term .p { color: #9896E0; }
|
|
.term .d { color: #5A6478; }
|
|
.term .g { color: #22C55E; }
|
|
.term .r { color: #EF4444; }
|
|
.term .y { color: #F59E0B; }
|
|
|
|
/* ── stat band ────────────────────────────────────────────────────── */
|
|
.band { border-block: 1px solid var(--line); background: var(--raised); }
|
|
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); }
|
|
@media (max-width: 820px) { .stats { grid-template-columns: repeat(2, 1fr); } }
|
|
.stat { background: var(--raised); padding: 26px 22px; }
|
|
.stat b { display: block; font: 700 clamp(24px, 3.6vw, 34px)/1 "Space Grotesk", system-ui, sans-serif; font-variant-numeric: tabular-nums; }
|
|
.stat span { display: block; margin-top: 7px; font-size: 13px; color: var(--dim); }
|
|
|
|
/* ── sections ─────────────────────────────────────────────────────── */
|
|
section { padding: 76px 0; }
|
|
@media (max-width: 720px) { section { padding: 52px 0; } }
|
|
.kicker {
|
|
font-family: "JetBrains Mono", ui-monospace, monospace;
|
|
font-size: 11.5px; letter-spacing: 1.2px; text-transform: uppercase;
|
|
color: var(--faint); margin-bottom: 12px;
|
|
}
|
|
section h2 { font-size: clamp(26px, 3.6vw, 36px); font-weight: 700; }
|
|
section .sub { color: var(--dim); margin-top: 14px; max-width: 62ch; font-size: 17px; }
|
|
|
|
.grid2 { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 18px; margin-top: 40px; }
|
|
.grid3 { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 18px; margin-top: 40px; }
|
|
@media (max-width: 880px) { .grid2, .grid3 { grid-template-columns: 1fr; } }
|
|
|
|
.card {
|
|
background: var(--panel); border: 1px solid var(--line);
|
|
border-radius: 13px; padding: 24px;
|
|
}
|
|
.card h3 { font-size: 18px; font-weight: 600; margin-bottom: 9px; }
|
|
.card p { color: var(--dim); font-size: 14.5px; }
|
|
.card .tag {
|
|
display: inline-block; font-family: "JetBrains Mono", monospace;
|
|
font-size: 10.5px; letter-spacing: .7px; text-transform: uppercase;
|
|
color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, transparent);
|
|
padding: 3px 8px; border-radius: 999px; margin-bottom: 12px;
|
|
}
|
|
|
|
code, .inline {
|
|
font-family: "JetBrains Mono", ui-monospace, monospace; font-size: .88em;
|
|
background: var(--code-bg); border: 1px solid var(--line);
|
|
padding: 1px 6px; border-radius: 5px; color: var(--fg);
|
|
}
|
|
|
|
/* ── pricing ──────────────────────────────────────────────────────── */
|
|
.tiers { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 20px; margin-top: 44px; align-items: stretch; }
|
|
@media (max-width: 880px) { .tiers { grid-template-columns: 1fr; } }
|
|
.tier {
|
|
position: relative; background: var(--panel); border: 1px solid var(--line);
|
|
border-radius: 16px; padding: 28px 26px 26px;
|
|
display: flex; flex-direction: column;
|
|
}
|
|
/* The featured tier is marked by a rule along its top edge rather than a
|
|
different fill — the card stays the same object, it is just the one
|
|
being pointed at. */
|
|
.tier.feature { border-color: var(--btn-bg); box-shadow: var(--shadow); }
|
|
.tier.feature::before {
|
|
content: ""; position: absolute; inset: -1px -1px auto -1px; height: 4px;
|
|
background: var(--btn-bg); border-radius: 16px 16px 0 0;
|
|
}
|
|
.badge {
|
|
position: absolute; top: -11px; right: 22px;
|
|
background: var(--btn-bg); color: #FFFFFF;
|
|
font: 600 10.5px/1 "JetBrains Mono", monospace; letter-spacing: .8px;
|
|
text-transform: uppercase; padding: 6px 10px; border-radius: 999px;
|
|
}
|
|
.tier h3 { font-size: 13px; font-weight: 600; color: var(--dim); letter-spacing: 1px; text-transform: uppercase; }
|
|
.price {
|
|
margin: 16px 0 2px; font: 700 38px/1 "Space Grotesk", system-ui, sans-serif;
|
|
font-variant-numeric: tabular-nums; letter-spacing: -.03em;
|
|
}
|
|
.price small { font-size: 15px; font-weight: 500; color: var(--dim); letter-spacing: 0; }
|
|
.tier .who { color: var(--faint); font-size: 13.5px; margin-top: 8px; min-height: 42px; }
|
|
.tier hr { border: 0; border-top: 1px solid var(--line); margin: 22px 0 20px; }
|
|
.tier ul { list-style: none; margin: 0 0 26px; display: flex; flex-direction: column; gap: 12px; flex: 1 1 auto; }
|
|
/* Two columns, therefore exactly two children: the tick and ONE box
|
|
holding all the text. A bare text node sitting beside a <strong>
|
|
becomes its own anonymous grid item, lands in the 20px icon column,
|
|
and wraps one word per line. */
|
|
.tier li { display: grid; grid-template-columns: 20px minmax(0, 1fr); gap: 10px; font-size: 14.5px; color: var(--dim); line-height: 1.55; align-items: start; }
|
|
.tier li > span { min-width: 0; }
|
|
.tier li svg { width: 15px; height: 15px; margin-top: 4px; color: var(--ok); }
|
|
.tier li strong { color: var(--fg); font-weight: 600; }
|
|
.tier .btn { width: 100%; justify-content: center; padding: 13px 17px; }
|
|
.tier .fine { margin-top: 12px; font-size: 12px; color: var(--faint); text-align: center; }
|
|
|
|
/* ── install ──────────────────────────────────────────────────────── */
|
|
.install { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 36px; }
|
|
@media (max-width: 880px) { .install { grid-template-columns: 1fr; } }
|
|
.copy {
|
|
display: flex; align-items: center; gap: 12px;
|
|
background: var(--code-bg); border: 1px solid var(--line);
|
|
border-radius: 10px; padding: 13px 15px;
|
|
min-width: 0;
|
|
}
|
|
/* Only the command scrolls. The button sits outside that box so it can
|
|
never be scrolled out of reach — which is what happens when the whole
|
|
row is the scroll container. */
|
|
.copy .cmd { overflow-x: auto; min-width: 0; flex: 1 1 auto; }
|
|
.copy code {
|
|
background: none; border: 0; padding: 0; font-size: 13px;
|
|
white-space: nowrap; display: block;
|
|
}
|
|
.copy button {
|
|
appearance: none; border: 1px solid var(--line-hi);
|
|
background: var(--raised); color: var(--dim); cursor: pointer;
|
|
padding: 8px; border-radius: 7px; flex: 0 0 auto; line-height: 0;
|
|
transition: color .15s, border-color .15s;
|
|
}
|
|
.copy button svg { width: 16px; height: 16px; }
|
|
.copy button:hover { color: var(--fg); border-color: var(--fg); }
|
|
.copy button .ico-done { display: none; }
|
|
.copy button.done { color: var(--ok); border-color: var(--ok); }
|
|
.copy button.done .ico-copy { display: none; }
|
|
.copy button.done .ico-done { display: block; }
|
|
|
|
/* On a phone, wrapping beats sideways scrolling: the whole command is
|
|
visible at once, and the Copy button is the thing they will use
|
|
anyway. break-all because a URL has no useful break points. */
|
|
@media (max-width: 720px) {
|
|
.copy { align-items: flex-start; flex-direction: column; gap: 10px; }
|
|
.copy .cmd { overflow-x: visible; width: 100%; }
|
|
.copy code { white-space: pre-wrap; word-break: break-all; line-height: 1.7; }
|
|
.copy button { align-self: flex-end; }
|
|
}
|
|
|
|
/* ── faq ──────────────────────────────────────────────────────────── */
|
|
.faq { margin-top: 36px; border-top: 1px solid var(--line); }
|
|
.faq details { border-bottom: 1px solid var(--line); }
|
|
.faq summary {
|
|
cursor: pointer; list-style: none; padding: 18px 34px 18px 0; position: relative;
|
|
font: 600 17px/1.4 "Space Grotesk", system-ui, sans-serif; color: var(--fg);
|
|
}
|
|
.faq summary::-webkit-details-marker { display: none; }
|
|
.faq summary::after {
|
|
content: ""; position: absolute; right: 6px; top: 26px;
|
|
width: 9px; height: 9px; border-right: 2px solid var(--faint);
|
|
border-bottom: 2px solid var(--faint); transform: rotate(45deg);
|
|
transition: transform .2s;
|
|
}
|
|
.faq details[open] summary::after { transform: rotate(-135deg); top: 30px; }
|
|
.faq p { color: var(--dim); padding: 0 0 20px; max-width: 74ch; font-size: 15.5px; }
|
|
|
|
/* ── footer ───────────────────────────────────────────────────────── */
|
|
footer { border-top: 1px solid var(--line); padding: 40px 0 56px; color: var(--faint); font-size: 13.5px; }
|
|
.foot { display: flex; gap: 28px; flex-wrap: wrap; align-items: center; }
|
|
.foot a { color: var(--dim); }
|
|
.foot .right { margin-left: auto; }
|
|
@media (max-width: 640px) { .foot .right { margin-left: 0; } }
|
|
</style>
|
|
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "SoftwareApplication", "name": "Hound", "alternateName": "Hound Antivirus", "applicationCategory": "SecurityApplication", "applicationSubCategory": "Antivirus, supply-chain security, endpoint protection", "operatingSystem": "Linux (Ubuntu, Debian, Linux Mint)", "url": "https://houndav.com/", "downloadUrl": "https://dl.houndav.com/", "softwareVersion": "0.1.0", "license": "https://www.apache.org/licenses/LICENSE-2.0", "isAccessibleForFree": true, "description": "Endpoint and supply-chain security for Linux. Refuses a malicious binary at execve in 2 ms using fanotify, and checks lockfiles against 235,577 known-malicious packages from the OSSF malicious-packages feed. Detects typosquats, hallucinated package names, install scripts that run code during npm install, pickle-based model files that execute on load, prompt injection in AI assistant instruction files, over-privileged MCP servers, rootkits and persistence changes. Ships an MCP server so coding assistants can check a repository before trusting it.", "featureList": ["Execution gate: refuses a malicious binary at execve before it runs", "Supply-chain scanning of package-lock.json, yarn.lock, Cargo.lock, poetry.lock, requirements.txt, go.sum, Gemfile.lock and composer.lock", "235,577 known-malicious package indicators across npm, PyPI, RubyGems, crates.io, Go and Packagist", "Typosquat and slopsquat detection for AI-hallucinated package names", "Install-script analysis for postinstall hooks that pipe remote scripts to a shell", "Pickle opcode analysis for .pt, .ckpt and .pkl model files that execute code on load", "Prompt-injection detection in CLAUDE.md, AGENTS.md, .cursorrules and copilot-instructions", "MCP server audit for unpinned servers and servers handed credentials", "Rootkit detection by kernel-versus-/proc comparison and package ownership", "Persistence ledger over systemd units, cron, autostart, shell profiles and authorized_keys", "MCP server with four read-only tools for coding assistants"], "offers": [{"@type": "Offer", "name": "Free", "price": "0", "priceCurrency": "USD", "description": "On-demand scanning, real-time file protection, quarantine, MCP server. No account."}, {"@type": "Offer", "name": "Pro", "price": "89.95", "priceCurrency": "USD", "description": "Execution gate, full supply-chain feed, Hound Linux threat pack, signed automatic definitions. Billed annually.", "priceSpecification": {"@type": "UnitPriceSpecification", "price": "89.95", "priceCurrency": "USD", "billingDuration": 1, "billingIncrement": 1, "unitCode": "ANN"}}, {"@type": "Offer", "name": "Fleet", "price": "249.95", "priceCurrency": "USD", "description": "Everything in Pro on up to 10 seats, plus central console, policy push and compliance reports. $15 per additional seat. Billed monthly."}], "publisher": {"@type": "Organization", "name": "Hound", "url": "https://houndav.com/"}}</script>
|
|
<script type="application/ld+json">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "Is Hound an antivirus?", "acceptedAnswer": {"@type": "Answer", "text": "Partly, and the interesting part is not. Hound does scan files and quarantine malware, but traditional antivirus databases are overwhelmingly Windows malware, which is close to irrelevant on a Linux developer machine. What actually compromises those machines is a dependency, a model file or a repository, so most of Hound is supply-chain and agent-era detection rather than file signatures."}}, {"@type": "Question", "name": "How is Hound different from ClamAV?", "acceptedAnswer": {"@type": "Answer", "text": "ClamAV's corpus is mostly Windows malware, useful if you are a file server passing infections along to Windows clients. Hound is Linux-native: it refuses a malicious binary at execve rather than reporting it afterwards, and its 235,577 indicators are packages that exist only to be malware, drawn from the OSSF malicious-packages feed. Hound can use clamd alongside it for the Windows-carrier case, but does not require it."}}, {"@type": "Question", "name": "Does Hound slow my machine down?", "acceptedAnswer": {"@type": "Answer", "text": "The execution gate adds about 0.8 milliseconds to a program starting, and sustains over 4,000 executions per second. On a server running 21 containers, 16 Node processes and a web server, arming it did not move request latency or load average. A verdict cache means a program you have already run is answered from memory without re-reading it."}}, {"@type": "Question", "name": "What happens if Hound crashes while it is blocking programs?", "acceptedAnswer": {"@type": "Answer", "text": "Nothing. The gate fails open: a watchdog releases any execution that has not been answered within 500 milliseconds, and if the daemon dies outright the kernel releases everything pending when its descriptor closes. A bug in an antivirus must never be able to freeze a machine, so that path is tested rather than assumed."}}, {"@type": "Question", "name": "Is Hound open source?", "acceptedAnswer": {"@type": "Answer", "text": "The agent is Apache-2.0 and the source is public. You are being asked to run a root daemon that can block execution, so you should be able to read it. Definitions are signed with a key whose public half is compiled into the binary, so anyone can verify that the definitions they received are the ones that were published. What is paid for is the threat feed, the console and support."}}, {"@type": "Question", "name": "Can my coding assistant use Hound?", "acceptedAnswer": {"@type": "Answer", "text": "Yes. Hound ships an MCP server with four read-only tools, so Claude, Cursor, VS Code or anything else that speaks MCP can check a project before installing its dependencies, check a single package or model file, and audit the MCP servers it is already trusting. There is deliberately no tool that can delete or quarantine anything: an assistant that can be persuaded by the repository it is reading must not be able to make your antivirus destroy files."}}, {"@type": "Question", "name": "What does Hound detect that other scanners do not?", "acceptedAnswer": {"@type": "Answer", "text": "Packages whose install script pipes a remote script into a shell before you have used any of their code. Package names an AI invented that somebody then registered. Model files whose pickle stream calls os.system when loaded. Instructions in CLAUDE.md or .cursorrules aimed at your assistant rather than at you. MCP servers downloaded fresh from the internet on every launch and handed an API token. Setuid binaries no installed package claims."}}, {"@type": "Question", "name": "Does Hound phone home?", "acceptedAnswer": {"@type": "Answer", "text": "No telemetry by default, and it can run fully offline with definitions imported from a file, which is how it works in air-gapped and regulated environments. The only network request it makes is fetching signed definition packs, and you can point that at your own mirror."}}, {"@type": "Question", "name": "Which Linux distributions does Hound support?", "acceptedAnswer": {"@type": "Answer", "text": "Ubuntu, Debian and Linux Mint have packages today. An AppImage runs anywhere without installing, though it cannot provide the execution gate, which needs privileges an uninstalled bundle does not have. RPM and Arch packaging exists but is not yet built and published."}}]}</script>
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<div class="wrap bar">
|
|
<a class="logo" href="/">
|
|
<svg viewBox="0 0 28 28" aria-hidden="true"><rect width="28" height="28" rx="6.3" fill="var(--brand)"/><g transform="translate(3.2,3.2) scale(0.771)" fill="var(--on-brand)" fill-rule="nonzero"><path d="M3.80069371,23.1130888 C4.43848107,23.5650959 5.14832497,23.919844 5.9089202,24.1573863 L4.47060635,26.3139954 C4.11309659,26.8500464 3.3887224,26.9947828 2.85267132,26.637273 C2.35490959,26.3052997 2.19455701,25.6569993 2.46043143,25.1368862 L2.52939365,25.019338 L3.80069371,23.1130888 Z M14.5833333,1.16666667 C16.7811895,1.16666667 18.6893658,2.52489596 19.4646473,4.47968116 L19.5335,4.66666667 L24.3833333,4.66666667 C25.0448446,4.66666667 25.5894608,5.16717524 25.6591362,5.81016498 L25.6666667,5.94999885 L25.6666667,11.375 C25.6666667,14.0328704 23.5754085,16.2023012 20.9485691,16.3276156 L20.7083333,16.3333333 L18.7961667,16.3321667 L18.8104203,16.3635263 C19.2754933,17.3735749 19.6443042,18.3167095 19.9164818,19.1943797 L20.0445161,19.627766 C20.7657518,22.2003082 19.7286621,25.1941618 17.5638169,26.637392 C17.0277001,26.9948032 16.3033525,26.8499337 15.9459413,26.3138169 C15.5885301,25.7777001 15.7333996,25.0533525 16.2695164,24.6959413 C17.5764793,23.8246327 18.2515149,21.8759509 17.7978097,20.2576506 C17.4455369,19.0011449 16.8372737,17.5384042 15.9713012,15.8761384 C15.8759396,15.6930882 15.8261459,15.4897339 15.8261459,15.2833333 C15.8261459,14.6231337 16.3245332,14.0799436 16.9690039,14.0080605 L17.1092123,14 L20.7083333,14 C22.0976747,14 23.2349191,12.9206448 23.3272774,11.5547236 L23.3333333,11.375 L23.3333333,6.99883333 L17.6136472,7.00006824 L17.4704091,5.99857195 C17.2758266,4.63808519 16.1483073,3.59829995 14.780321,3.50658494 L14.5833333,3.5 L12.7831667,3.5 L12.5783017,3.50389564 C8.27042644,3.63569563 4.8164366,7.09906173 4.67140846,11.3859455 L4.66666667,11.6666667 L4.66631609,16.8880679 L4.67097109,17.092305 C4.76225687,18.9495018 6.29888585,20.4166667 8.16666667,20.4166667 C10.0996633,20.4166667 11.6666667,18.8496633 11.6666667,16.9166667 C11.6666667,16.1268183 11.523797,15.416107 11.2062777,14.4675176 L10.7570788,13.2056109 C10.1975498,11.6462738 9.90930052,10.544355 9.77521466,9.11410583 C9.71507223,8.47258663 10.1863712,7.90377749 10.8278904,7.84363507 C11.4694096,7.78349264 12.0382188,8.25479164 12.0983612,8.89631084 C12.1996371,9.97658728 12.4067419,10.8376191 12.8110905,12.0132787 L13.3678001,13.5759215 L13.4189446,13.7268763 C13.8098537,14.8947176 14,15.8406089 14,16.9166667 C14,20.1383277 11.3883277,22.75 8.16666667,22.75 C5.13975753,22.75 2.63542176,20.439154 2.35770657,17.4371488 L2.3393951,17.1781792 L2.33333333,16.9166667 L2.33333333,11.6666667 C2.33333333,6.09263102 6.68344803,1.51408374 12.2162292,1.1851268 L12.4308333,1.17483333 L12.4315796,1.16666667 L14.5833333,1.16666667 Z M16.1504743,6.81070338 L16.4543586,8.53411695 C16.5662457,9.1686603 16.1425491,9.77376175 15.5080058,9.88564887 C14.8734624,9.99753598 14.268361,9.57383938 14.1564739,8.93929603 L13.8525895,7.21588246 C13.7407024,6.58133911 14.164399,5.97623765 14.7989424,5.86435054 C15.4334857,5.75246343 16.0385872,6.17616002 16.1504743,6.81070338 Z"></path></g></svg>
|
|
<b>Hound</b>
|
|
</a>
|
|
<button class="menu-btn" id="menu-btn" aria-expanded="false" aria-controls="menu" aria-label="Menu">
|
|
<svg class="open" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
|
|
<svg class="close" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M18 6 6 18M6 6l12 12"/></svg>
|
|
</button>
|
|
<nav class="links" id="menu">
|
|
<a href="#what">What it catches</a>
|
|
<a href="#agents">For agents</a>
|
|
<a href="#pricing">Pricing</a>
|
|
<a href="#faq">FAQ</a>
|
|
<div class="theme" role="group" aria-label="Colour theme">
|
|
<button data-set="light" aria-pressed="false" title="Light">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
|
|
</button>
|
|
<button data-set="auto" aria-pressed="true" title="Follow system">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="13" rx="2"/><path d="M8 21h8M12 17v4"/></svg>
|
|
</button>
|
|
<button data-set="dark" aria-pressed="false" title="Dark">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/></svg>
|
|
</button>
|
|
</div>
|
|
<a class="btn" href="#install">Install</a>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
<main>
|
|
<div class="wrap">
|
|
<div class="hero">
|
|
<div>
|
|
<div class="eyebrow">Linux · open source agent</div>
|
|
<h1>Your antivirus has never heard of the things that actually reach your machine.</h1>
|
|
<p class="lede">
|
|
Hound blocks a binary before it runs, and reads your lockfiles against
|
|
<strong>235,577 packages that exist only to be malware</strong>. Built for people who
|
|
ship software, on the machines they ship it from.
|
|
</p>
|
|
<div class="cta">
|
|
<a class="btn" href="#install">Install on Linux</a>
|
|
<a class="btn ghost" href="#what">See what it catches</a>
|
|
<span class="note">Free tier, no account.</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="term" aria-label="Example terminal output">
|
|
<div class="term-bar"><i></i><i></i><i></i> joe@thinkpad — hound</div>
|
|
<pre><span class="p">$</span> hound supply-chain ~/src/dashboard
|
|
|
|
<span class="r">✘ 2 critical</span>, 1 warning across 1,284 packages
|
|
|
|
<span class="r">CRITICAL</span> @vue/cli-plugin-babe1@1.0.2
|
|
<span class="d">node_modules/@vue/cli-plugin-babe1/package.json</span>
|
|
Its "postinstall" step runs automatically when the
|
|
package is installed — before you have used any of
|
|
its code — and it downloads a script from the
|
|
internet and runs it immediately.
|
|
<span class="p">→</span> Do not install this package. If it is already
|
|
installed, rotate any credentials it could read.
|
|
|
|
<span class="r">CRITICAL</span> mcp-github-tools@0.3.1
|
|
<span class="d">~/.config/mcp/servers.json</span>
|
|
Handed GITHUB_TOKEN, and its code is downloaded
|
|
fresh from the internet on every launch.
|
|
|
|
<span class="y">WARNING</span> CLAUDE.md
|
|
<span class="d">vendor/awesome-agents/CLAUDE.md</span>
|
|
Contains instructions aimed at your assistant
|
|
rather than at you.
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="band">
|
|
<div class="wrap">
|
|
<div class="stats">
|
|
<div class="stat"><b>97%</b><span>of npm's security records are malware, not bugs</span></div>
|
|
<div class="stat"><b>235,577</b><span>malicious packages Hound knows by name</span></div>
|
|
<div class="stat"><b>2 ms</b><span>to refuse a malicious binary at <span class="mono">execve</span></span></div>
|
|
<div class="stat"><b>0.8 ms</b><span>added to a normal program starting</span></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<section id="what">
|
|
<div class="wrap">
|
|
<div class="kicker">What it catches</div>
|
|
<h2>The Linux desktop threat is not a Windows virus.</h2>
|
|
<p class="sub">
|
|
Traditional antivirus databases are overwhelmingly Windows malware — useful if you are a
|
|
file server passing infections along, irrelevant to the laptop you write code on. What
|
|
actually reaches a developer machine is a dependency, a model file, or a repository.
|
|
</p>
|
|
|
|
<div class="grid3">
|
|
<div class="card">
|
|
<span class="tag">Supply chain</span>
|
|
<h3>Dependencies that are malware</h3>
|
|
<p>Typosquats, and the newer problem: names an AI invented that somebody then registered. Hound reads your lockfiles — so it catches what <em>will</em> be installed, before the payload runs during installation.</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag">Execution</span>
|
|
<h3>Refused before it runs</h3>
|
|
<p>Real-time protection that denies <span class="mono">execve</span> rather than reporting it afterwards. Built on fanotify, with a watchdog that fails open — a bug in Hound must never be able to freeze your machine.</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag">Model files</span>
|
|
<h3>Weights that are programs</h3>
|
|
<p>A pickle-based <span class="mono">.pt</span> or <span class="mono">.ckpt</span> executes code the moment it loads. Downloading weights is a code-execution decision, and Hound reads the opcodes before you find out the hard way.</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag">Persistence</span>
|
|
<h3>What changed since last time</h3>
|
|
<p>Half of a Linux compromise is a line added to a startup file, not a file on disk. Hound keeps a hashed ledger of systemd units, cron, autostart, shell profiles and authorized_keys, and reports what moved.</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag">Install scripts</span>
|
|
<h3>Code that runs on <span class="mono">npm install</span></h3>
|
|
<p>A <span class="mono">postinstall</span> hook that pipes a remote script into a shell, decodes something scrambled and runs it, or reaches for your SSH keys. It executes before you have used a line of the package.</p>
|
|
</div>
|
|
<div class="card">
|
|
<span class="tag">Rootkits</span>
|
|
<h3>Questions with factual answers</h3>
|
|
<p>A process the kernel has but <span class="mono">/proc</span> does not list. A setuid binary no installed package claims. Not guesswork against a list of names that only holds on one distribution.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="agents" class="band">
|
|
<div class="wrap">
|
|
<div class="kicker">For people who code with agents</div>
|
|
<h2>Your assistant can ask Hound first.</h2>
|
|
<p class="sub">
|
|
Hound ships an MCP server. Point Claude, Cursor, VS Code or anything else that speaks MCP
|
|
at it, and your assistant can check a repository before it installs its dependencies or
|
|
starts working in it.
|
|
</p>
|
|
|
|
<div class="grid2">
|
|
<div class="term" aria-label="MCP configuration">
|
|
<div class="term-bar"><i></i><i></i><i></i> ~/.config/mcp/servers.json</div>
|
|
<pre>{
|
|
<span class="p">"mcpServers"</span>: {
|
|
<span class="p">"hound"</span>: {
|
|
<span class="p">"command"</span>: <span class="g">"/usr/bin/hound-mcp"</span>
|
|
}
|
|
}
|
|
}
|
|
|
|
<span class="d">// No npx — nothing fetched at launch.</span>
|
|
<span class="d">// No env — no secret handed over.</span>
|
|
<span class="d">// No path — no directory granted.</span>
|
|
<span class="d">//</span>
|
|
<span class="d">// Hound flags all three in other</span>
|
|
<span class="d">// people's configs. Ours passes its</span>
|
|
<span class="d">// own audit.</span>
|
|
</pre>
|
|
</div>
|
|
<div style="display:flex; flex-direction:column; gap:18px;">
|
|
<div class="card">
|
|
<h3>Four read-only tools</h3>
|
|
<p><span class="mono">check_project</span>, <span class="mono">check_package</span>, <span class="mono">check_file</span>, <span class="mono">check_mcp_config</span>. There is no quarantine tool and never will be — an assistant that can be persuaded by the repository it is reading must not be able to make your antivirus delete things.</p>
|
|
</div>
|
|
<div class="card">
|
|
<h3>It audits the tools you already trust</h3>
|
|
<p>Every MCP server in your config runs with your permissions and gets called without asking you. Hound tells you which ones download their code fresh on every launch, and which ones you handed a token.</p>
|
|
</div>
|
|
<div class="card">
|
|
<h3>Written to be read twice</h3>
|
|
<p>Once by the model, once by you. No rule identifiers, no jargon, and a clean result says what it did <em>not</em> check — because "nothing wrong" that reads as a blanket endorsement is worse than no answer.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="pricing">
|
|
<div class="wrap">
|
|
<div class="kicker">Pricing</div>
|
|
<h2>The scanner is free. The blocking and the intelligence are not.</h2>
|
|
<p class="sub">
|
|
A free tier that cannot protect anything is a bad first impression, so real-time file
|
|
protection is in the free build. The line is drawn at refusing execution, and at the
|
|
threat feed.
|
|
</p>
|
|
|
|
<div class="tiers">
|
|
<div class="tier">
|
|
<h3>Free</h3>
|
|
<div class="price">$0</div>
|
|
<p class="who">Everyone. No account, no telemetry, no expiry.</p>
|
|
<hr>
|
|
<ul>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>On-demand scanning, CLI and desktop app</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Real-time file protection</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Quarantine vault with one-click restore</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>MCP server for your coding assistant</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Rootkit and persistence checks</span></li>
|
|
</ul>
|
|
<a class="btn ghost" href="#install">Install</a>
|
|
<p class="fine">Apache-2.0. Yours to read and to fork.</p>
|
|
</div>
|
|
|
|
<div class="tier feature">
|
|
<span class="badge">Most popular</span>
|
|
<h3>Pro</h3>
|
|
<div class="price">$89.95 <small>/ year</small></div>
|
|
<p class="who">One machine, for someone who builds software on it.</p>
|
|
<hr>
|
|
<ul>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Everything in Free</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span><strong>Execution gate</strong> — a malicious binary is refused before it runs, in 2 ms</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span><strong>Supply-chain scanner</strong> against all 235,577 indicators</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span><strong>Hound Linux threat pack</strong> — miners, backdoors, rootkits, webshells</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Signed definitions, updated automatically</span></li>
|
|
</ul>
|
|
<a class="btn" href="#install">Get Pro</a>
|
|
<p class="fine">Annual only. Billed once, cancel any time.</p>
|
|
</div>
|
|
|
|
<div class="tier">
|
|
<h3>Fleet</h3>
|
|
<div class="price">$249.95 <small>/ month</small></div>
|
|
<p class="who">Up to 10 seats, then $15 each. Annual at ten months' price.</p>
|
|
<hr>
|
|
<ul>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Everything in Pro, on every machine</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Central console, enrolment and policy push</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span><strong>Compliance reports</strong> an auditor accepts</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Air-gapped definition mirrors</span></li>
|
|
<li><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg><span>Priority support and a named contact</span></li>
|
|
</ul>
|
|
<a class="btn ghost" href="mailto:sales@houndav.com?subject=Hound%20Fleet">Talk to us</a>
|
|
<p class="fine">Over 20 seats? We will quote you.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="install" class="band">
|
|
<div class="wrap">
|
|
<div class="kicker">Install</div>
|
|
<h2>One command, then it is running.</h2>
|
|
<p class="sub">
|
|
Ubuntu, Debian and Linux Mint today. The execution gate ships switched <strong>off</strong> —
|
|
it needs root and covers your whole filesystem, so turning it on is your decision rather
|
|
than the installer's.
|
|
</p>
|
|
|
|
<div class="install">
|
|
<div>
|
|
<p style="color:var(--dim); font-size:14px; margin-bottom:10px;"><strong style="color:var(--fg)">Debian, Ubuntu, Mint</strong></p>
|
|
<div class="copy">
|
|
<div class="cmd"><code id="c1">curl -fsSL https://dl.houndav.com/deb/hound_latest_amd64.deb -o hound.deb && sudo apt install ./hound.deb</code></div>
|
|
<button data-copy="c1" aria-label="Copy command" title="Copy command">
|
|
<svg class="ico-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
|
<svg class="ico-done" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<p style="color:var(--dim); font-size:14px; margin-bottom:10px;"><strong style="color:var(--fg)">Try it without installing</strong></p>
|
|
<div class="copy">
|
|
<div class="cmd"><code id="c2">curl -fsSL https://dl.houndav.com/appimage/Hound-latest-x86_64.AppImage -o hound && chmod +x hound && ./hound status</code></div>
|
|
<button data-copy="c2" aria-label="Copy command" title="Copy command">
|
|
<svg class="ico-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
|
<svg class="ico-done" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<p style="color:var(--faint); font-size:13.5px; margin-top:22px;">
|
|
The AppImage runs as your user and leaves nothing behind. It cannot do the execution gate —
|
|
that needs privileges an uninstalled bundle does not have — and it will tell you so rather
|
|
than failing quietly.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="faq">
|
|
<div class="wrap">
|
|
<div class="kicker">Questions</div>
|
|
<h2>What people ask before installing it.</h2>
|
|
<div class="faq">
|
|
<details>
|
|
<summary>Is Hound an antivirus?</summary>
|
|
<p>Partly, and the interesting part is not. Hound does scan files and quarantine malware, but traditional antivirus databases are overwhelmingly Windows malware, which is close to irrelevant on a Linux developer machine. What actually compromises those machines is a dependency, a model file or a repository, so most of Hound is supply-chain and agent-era detection rather than file signatures.</p>
|
|
</details>
|
|
<details>
|
|
<summary>How is Hound different from ClamAV?</summary>
|
|
<p>ClamAV's corpus is mostly Windows malware, useful if you are a file server passing infections along to Windows clients. Hound is Linux-native: it refuses a malicious binary at execve rather than reporting it afterwards, and its 235,577 indicators are packages that exist only to be malware, drawn from the OSSF malicious-packages feed. Hound can use clamd alongside it for the Windows-carrier case, but does not require it.</p>
|
|
</details>
|
|
<details>
|
|
<summary>Does Hound slow my machine down?</summary>
|
|
<p>The execution gate adds about 0.8 milliseconds to a program starting, and sustains over 4,000 executions per second. On a server running 21 containers, 16 Node processes and a web server, arming it did not move request latency or load average. A verdict cache means a program you have already run is answered from memory without re-reading it.</p>
|
|
</details>
|
|
<details>
|
|
<summary>What happens if Hound crashes while it is blocking programs?</summary>
|
|
<p>Nothing. The gate fails open: a watchdog releases any execution that has not been answered within 500 milliseconds, and if the daemon dies outright the kernel releases everything pending when its descriptor closes. A bug in an antivirus must never be able to freeze a machine, so that path is tested rather than assumed.</p>
|
|
</details>
|
|
<details>
|
|
<summary>Is Hound open source?</summary>
|
|
<p>The agent is Apache-2.0 and the source is public. You are being asked to run a root daemon that can block execution, so you should be able to read it. Definitions are signed with a key whose public half is compiled into the binary, so anyone can verify that the definitions they received are the ones that were published. What is paid for is the threat feed, the console and support.</p>
|
|
</details>
|
|
<details>
|
|
<summary>Can my coding assistant use Hound?</summary>
|
|
<p>Yes. Hound ships an MCP server with four read-only tools, so Claude, Cursor, VS Code or anything else that speaks MCP can check a project before installing its dependencies, check a single package or model file, and audit the MCP servers it is already trusting. There is deliberately no tool that can delete or quarantine anything: an assistant that can be persuaded by the repository it is reading must not be able to make your antivirus destroy files.</p>
|
|
</details>
|
|
<details>
|
|
<summary>What does Hound detect that other scanners do not?</summary>
|
|
<p>Packages whose install script pipes a remote script into a shell before you have used any of their code. Package names an AI invented that somebody then registered. Model files whose pickle stream calls os.system when loaded. Instructions in CLAUDE.md or .cursorrules aimed at your assistant rather than at you. MCP servers downloaded fresh from the internet on every launch and handed an API token. Setuid binaries no installed package claims.</p>
|
|
</details>
|
|
<details>
|
|
<summary>Does Hound phone home?</summary>
|
|
<p>No telemetry by default, and it can run fully offline with definitions imported from a file, which is how it works in air-gapped and regulated environments. The only network request it makes is fetching signed definition packs, and you can point that at your own mirror.</p>
|
|
</details>
|
|
<details>
|
|
<summary>Which Linux distributions does Hound support?</summary>
|
|
<p>Ubuntu, Debian and Linux Mint have packages today. An AppImage runs anywhere without installing, though it cannot provide the execution gate, which needs privileges an uninstalled bundle does not have. RPM and Arch packaging exists but is not yet built and published.</p>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<div class="wrap">
|
|
<div class="kicker">Open source</div>
|
|
<h2>You are installing a root daemon that can block execution.</h2>
|
|
<p class="sub">
|
|
So you should be able to read it. The agent is Apache-2.0 and the definitions are signed
|
|
with a key whose public half is compiled into the binary — anyone can verify that what
|
|
they received is what we published. What you pay for is the threat feed, the console and
|
|
support, not permission to look.
|
|
</p>
|
|
<div class="cta" style="margin-top:26px;">
|
|
<a class="btn ghost" href="https://git.joelovestech.com/Hound/Antivirus">Read the source</a>
|
|
<a class="btn ghost" href="https://defs.houndav.com/index.json">See the definitions index</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<footer>
|
|
<div class="wrap foot">
|
|
<span>© 2026 Hound</span>
|
|
<a href="https://git.joelovestech.com/Hound/Antivirus">Source</a>
|
|
<a href="mailto:support@houndav.com">Support</a>
|
|
<a href="https://dl.houndav.com/">Downloads</a>
|
|
<span class="right mono" style="font-size:12px;">Definitions 2026.08.21 · 235,577 indicators</span>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
(function () {
|
|
var root = document.documentElement;
|
|
var buttons = Array.prototype.slice.call(document.querySelectorAll('.theme button'));
|
|
|
|
function apply(mode) {
|
|
if (mode === 'auto') { root.removeAttribute('data-theme'); }
|
|
else { root.setAttribute('data-theme', mode); }
|
|
buttons.forEach(function (b) {
|
|
b.setAttribute('aria-pressed', String(b.dataset.set === mode));
|
|
});
|
|
}
|
|
|
|
var saved = 'auto';
|
|
try { saved = localStorage.getItem('hound-theme') || 'auto'; } catch (e) { /* private mode */ }
|
|
apply(saved);
|
|
|
|
buttons.forEach(function (b) {
|
|
b.addEventListener('click', function () {
|
|
var mode = b.dataset.set;
|
|
apply(mode);
|
|
try { localStorage.setItem('hound-theme', mode); } catch (e) { /* ignore */ }
|
|
});
|
|
});
|
|
|
|
// Hamburger
|
|
var menuBtn = document.getElementById('menu-btn');
|
|
var menu = document.getElementById('menu');
|
|
function setMenu(open) {
|
|
menu.classList.toggle('open', open);
|
|
menuBtn.setAttribute('aria-expanded', String(open));
|
|
}
|
|
if (menuBtn && menu) {
|
|
menuBtn.addEventListener('click', function () {
|
|
setMenu(menuBtn.getAttribute('aria-expanded') !== 'true');
|
|
});
|
|
// Any navigation closes it, or the panel stays over the thing you
|
|
// just asked to see.
|
|
menu.addEventListener('click', function (e) {
|
|
if (e.target.closest('a')) setMenu(false);
|
|
});
|
|
document.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape') setMenu(false);
|
|
});
|
|
// Rotating to landscape must not leave a phone panel stranded over a
|
|
// desktop layout.
|
|
window.addEventListener('resize', function () {
|
|
if (window.innerWidth > 760) setMenu(false);
|
|
});
|
|
}
|
|
|
|
document.querySelectorAll('[data-copy]').forEach(function (btn) {
|
|
btn.addEventListener('click', function () {
|
|
var el = document.getElementById(btn.dataset.copy);
|
|
if (!el) return;
|
|
var done = function () {
|
|
btn.classList.add('done');
|
|
btn.setAttribute('aria-label', 'Copied');
|
|
setTimeout(function () {
|
|
btn.classList.remove('done');
|
|
btn.setAttribute('aria-label', 'Copy command');
|
|
}, 1600);
|
|
};
|
|
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
navigator.clipboard.writeText(el.textContent).then(done, function () {});
|
|
} else {
|
|
var r = document.createRange();
|
|
r.selectNodeContents(el);
|
|
var s = window.getSelection();
|
|
s.removeAllRanges(); s.addRange(r);
|
|
try { document.execCommand('copy'); done(); } catch (e) {}
|
|
s.removeAllRanges();
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|