Know what's there. Know what's open. Know what moved.
A one-way Linux agent that measures three things about a running web server — what it declares, what its apps can reach, and what moved — and writes unknown at full contrast for everything it cannot settle.
- Scored against the Linux kernel: 0 false positives, 0 false negatives across the 3,130 queries it answered at high confidence — and it abstained on the other 812 rather than guessing.
-
No listening socket.
bind()=0 listen()=0 connect()=1, measured withstrace. It never opens a watched file.
-
I
what this server declares
route_coveragepartial - II what the app's own OS user can reach 17 open / 100 closed / 0 unknown
- III what moved since the last pass 8 watched / 42 excluded
- IV where code could be placed 3 deny / 12 unknown
Four readings, one pass. The hatched share is what the evidence did not settle. It is reported at full contrast, not faded out and not rounded away — and readings I, III and IV come from different runs, so they are never added together.
We measure your server. We also publish what we couldn't measure.
Four states. Two of them are answers, and two of them are not — drawn differently on purpose, because colour alone would let an unanswered question pass for a clean one at a glance.
- allow / high Settled. This principal reaches it. Solid fill.
- deny / high Settled the other way. It does not. Solid fill.
-
unknown / abstain
Asked, and deliberately not answered. Hatched, recessed, and
never faded — an abstention is not a weaker answer, it is no answer,
and it is not
safe. It is drawn off the red/green scale entirely, because it is not a severity. - no evidence source Not asked, because this release cannot ask it. A step the engine has no way to compute on any host yet. Distinct from an abstention: an abstention means the question was put and did not settle here, this means the question cannot be put at all. Shown rather than hidden.
One pass. Four readings. One OS user at a time.
Blastline does not ask what is wrong with your server. It asks four narrow questions it can answer from evidence on the disk, and it reports the share of each one it could not settle.
What this server declares
which vhosts, docroots, handlers and route mappings does this config actually resolve to?
Blastline reads the nginx and Apache configuration the way the webserver
does — following nginx include directives rather than guessing —
and builds the inventory of what is actually declared: server names, listen
directives, document roots, aliases, FastCGI and proxy targets,
try_files, deny_all, internal,
directory listing, and the handler each route maps to. Every record carries
its own provenance, so a docroot that was inherited is never
presented as one that was declared.
This axis has no headline number, and that is the honest position: the inventory ships to us as counts per category, never as your raw routes. What it does publish is the shape of its own blind spots.
reachability here is read from the listen and
internal directives; the agent runs no probe from outside, so
this is what the config says, not what the network does.
What the app's own OS user can reach
can principal P read, write or execute path X — along the whole path, not just the leaf?
This is the arithmetic the kernel runs, run deliberately. For each path and
each principal Blastline resolves the POSIX mode bits, the principal's
supplementary groups, and any POSIX ACL — including the mask::
entry, which silently narrows every named user and group entry and is the
single most common source of a wrong answer in tools that skip it.
Traversal is resolved along the whole path rather than at the leaf: for a
principal with no other route in, a file at 0644 inside a
directory at 0700 it does not own is not reachable, and saying
otherwise is a false positive. Results are reported per principal,
not per endpoint — every endpoint running as the same user shares the same
reach, so reporting it per endpoint would multiply one fact into a hundred.
What moved since the last pass
did anything appear, vanish, come back, or change how it would be handled?
Blastline does not scan your disk for changes. It watches only the slots the reach measurement already says something could be written into — a narrow, derived surface rather than a filesystem crawl — and compares it between hourly passes. On the measured host that meant 8 slots watched of 50 evaluated, the other 42 excluded because nothing could be placed there. Three consecutive runs produced zero noise.
It reports appeared, disappeared,
modified, and — the one worth knowing about —
reappeared, a file that came back after being removed. It also
reports interpreter drift: became_executable and
no_longer_executable, when the webserver's decision to run rather
than serve a location changes underneath you.
ctime untouched
is not something this measures. It runs hourly with up to five minutes of
jitter, so it is not real-time and it is not a filesystem watcher. And it will
not notify you: Blastline sends no alerts today, in any channel. You read the
result in the dashboard.
Where code could be placed
could this slot carry executable code — W write, R reach, I interpret?
The sharpest case of axis II, and the one where abstention does the most work.
Three legs have to hold at once: can this user write here,
can anything outside reach the path, and would what lands
there be interpreted as code. They combine under three-valued
Kleene logic, where unknown ∧ allow is unknown and
never allow. Nothing in the engine rounds an unresolved leg up to
a conclusion, because a conjunction with a missing term is not a weaker claim —
it is no claim.
The R leg is not signed in this release. Whether something outside can reach a given path is a question this version has no evidence source for, on any host, so it is reported as unknown rather than assumed in either direction — and that single missing leg is why the verdict below is what it is.
` strips the surrounding whitespace and glues the words together ("theexternal-reachability"), which is how this was broken once. -#}-
6
execution_confirmedSomething was seen running. no evidence source in this release -
5
execution_likelyPlaced code would be handled as code. Reached by 2 slots — and still not a verdict. -
4
externally_reachableSomething outside can reach the path. no evidence source in this release -
3
suspicious_changeThe watched surface moved. no evidence source in this release -
2
placement_path_existsThe user can write into the slot. Reached by 6 slots. -
1
insufficient_evidenceAsked, not settled. Reached by 4 slots. -
0
no_pathNo placement path for this principal. Settled for 3 slots.
Scored against the kernel
No heuristics, no scoring model, no machine learning — the decision procedure is small enough to audit, and it was checked against the only authority that cannot be argued with: the running Linux kernel on a real multi-user server, asked the same questions as the same principals.
Three independent axes, because the oracle you verify against decides which class of error you are able to see. A single axis returning zero is a comfortable result, not a settled one.
And every answer lands in one of three tiers — allow/high,
deny/high, unknown/abstain. There is no fourth tier
and no numeric score to hide behind. If the evidence does not settle the
question, the answer is an abstention with a stated reason.
What Blastline does not claim
Not a disclaimer page and not fine print. These limits are the reason the numbers above can be trusted, so they are on the same page, at the same size, and none of them is behind a toggle.
We do not detect web shells
Blastline reports whether a slot could carry executable
code. It does not scan for one, fingerprint one, or claim one is
present. Reaching execution_likely means the placement
path exists — it is a rung on an evidence ladder, not a verdict, and
the engine keeps the two separate by design.
We do not prove external reachability
The R leg is unsigned in this release, and one class of case cannot be ruled out by this measurement even where it is. The product states it in its own output rather than in a footnote:
NOT PROVEN: (1) execution ("placement path exists" is not "it
ran"); (2) the sealed rung does not change — this is not
a ladder step; (3) the one mirror-proxy class this measurement cannot
rule out: a byte-identical, mtime-preserved mirror copy served behind
a proxy — in that case outside traffic may never reach the object on
this disk at all.
We do not model root, the kernel, or privilege escalation
The threat model starts after the attacker can run code as the web application's user. Kernel exploits, EDR evasion, rootkits and local privilege escalation are out of scope. Blastline never assumes root and never reports on it. It measures one thing precisely rather than nine things approximately.
We tell you a credential is reachable, not what it unlocks
"This app can read that secret file" is measured. "That credential is an admin on your database" is a different question, requiring the credential to be used. It is off by default and lives behind an explicit opt-in, because access and power are not the same claim.
We cannot execute code on your agent — but we could blind it
The agent takes no commands. It parses exactly two things, both
replies to requests it made itself: a schema-gated acknowledgement
whose only decision-carrying bit is accepted, and a
cryptographically signed rule bundle that can only adjust a threshold
it already knows how to compute.
The honest boundary: a validly signed bundle could leave
rules in place that can no longer fire. Countermeasures are a
scope-regression gate, a staleness threshold, and a
signature_health indicator in the dashboard — so a quiet
agent looks quiet, not clean. This page previously would have said
"the agent receives nothing"; that sentence was retired when it was
measured and found to be too strong.
We abstain on ground we cannot stand on
The supported target is ext4 and XFS on a VPS. Blastline reads standard
nginx and Apache configuration, including the configuration cPanel, Plesk
and CloudPanel generate — but those panel adapters have not been verified
against a live install, so we do not claim verified panel support. On an
exotic filesystem, or where an identity will not resolve, Blastline
returns unknown. Container-native layouts need a separate
adapter and are not covered yet.
We do not send you alerts
Blastline has no notification channel at all today — no email, no webhook, no Slack. The agent pushes hourly and you read the result in the dashboard. The certificate and header monitoring elsewhere on this site does alert; the two products are not wired together yet, and we would rather say so than let the word "monitoring" imply it.
We do not find the way in
Blastline never looks for the vulnerability that gets an attacker onto your server. If you need boundary testing, that is what the SSL and header scanners on this site are for — different question, different tool, and Blastline sits alongside kernel-level and endpoint tooling rather than replacing any of it.
What leaves your server
The complete list, in both directions.
Never leaves the host
Not configurable, not opt-out, not negotiable.
- File contents. Not transmitted — and on the watched surface, not even read: change detection compares
statmetadata, so the file is never opened. - Secret values. The agent can report that a secret file is reachable without ever holding what is in it.
- Raw logs. Parsed on the host; the parse result travels, the log does not.
- Your route definitions. The endpoint inventory leaves as counts per category. The routes themselves stay on the host.
Does leave the host
Over outbound TLS, on a connection the agent opens itself.
- Raw file paths. The full path, e.g.
/var/www/shop/.env. - OS user names. The principal a finding belongs to, e.g.
shop-fpm. - Metadata and verdicts. Modes, ownership, the decision and its stated reason. Plus an alias you choose for the server — the agent rejects the real hostname.
Install in five steps
One package, no third-party dependencies, any distribution with glibc 2.17 or newer. The exact commands, with your own activation key filled in, are on the setup page after you sign in.
Download the package
Debian, Ubuntu and RHEL. Published with a SHA-256 you can check before installing.
curl -fsSLO https://myssl.info/downloads/myssl-agent_0.1.0_all.deb
Generate an activation key
Generated once and shown once, in the dashboard. It proves the agent's identity when it pushes from your server — it is not the REST API key from Settings, and the two are not interchangeable.
Install it
The two --force-conf* flags keep your
agent.toml across upgrades; without them dpkg stops to
ask an interactive question on every single one.
sudo dpkg --force-confdef --force-confold -i myssl-agent_0.1.0_all.deb
Pick the site and name the server
You make this choice on your own server, not here — the agent has to know what to scan before it has ever spoken to us. List what it found, then let it write the config block for you and delete the directories you do not want measured.
sudo myssl-agent sites
sudo myssl-agent sites --toml
The block sets included_roots in
/etc/myssl-agent/agent.toml. Without it the agent scans
every site on the server, exceeds the free plan and is rejected. The
alias is a label you choose; if it matches the machine's
real hostname the agent refuses it and uses a safe per-install default
instead.
Start it
The dashboard fills in on its own once the agent sends its first observation.
sudo /usr/lib/myssl-agent/configure-egress
sudo systemctl start myssl-agent
Frequently asked questions
What does Blastline actually measure?
Three things about a running Linux web server, in one read-only pass. What the server declares: the vhosts, docroots, handlers and route mappings nginx or Apache actually resolve to. What each application can reach: for the OS user an app runs as, Blastline resolves POSIX mode bits, supplementary groups and POSIX ACLs including the ACL mask, along the whole path rather than just the leaf, and reports allow, deny or unknown. And what moved: on a deliberately narrow watched surface it compares file metadata between hourly passes and reports whether something appeared, disappeared, came back, or changed how it would be handled. Results are scoped to the principal, not to a single endpoint, because every endpoint running as the same user shares the same reach.
Is this a vulnerability scanner? Does it find webshells?
No, to both. Blastline assumes the compromise has already happened and measures the consequences; it does not look for the flaw that got the attacker in. And it does not detect web shells. It measures whether a slot could carry one — whether the user can write there and whether what lands there would be handled as code. Reaching the execution_likely rung means the placement path exists, not that anything was seen running. The third leg, whether something outside can reach the path, is not signed in this release and is reported as unknown rather than assumed either way.
Do my file contents or secret values leave my server?
No. File contents, secret values and raw logs stay on the host and are never transmitted. Blastline never opens a watched file at all: change detection compares stat metadata, not bytes. Raw file paths and the OS user names they belong to are sent, because without them an operator cannot tell which of three .env files to fix. That trade is deliberate and it has a cost: if the portal were breached, an attacker would see your directory map and which files are open. We would rather state that than hide it. Raw route definitions from your webserver config are not sent; only counts per category are.
Does the agent open a port or take commands from you?
It opens no port and binds no socket. Measured with strace: bind()=0, listen()=0, connect()=1 — outbound TLS only, so there is no listening socket for anything to connect to. It parses exactly two things, both replies to requests it made itself: a schema-gated acknowledgement whose only decision-carrying bit is accepted, and a cryptographically signed rule bundle that can adjust a threshold the agent already knows how to compute. A bundle cannot make it read a new file or take a new action.
So the server cannot do anything to my agent at all?
That would be an overstatement, so we will not make it. We cannot execute code on your agent, but a validly signed bundle could blind it — leaving rules in place that can no longer fire. The countermeasures are a scope-regression gate, a staleness threshold, and a signature_health indicator surfaced in the dashboard so a quiet agent looks quiet rather than clean. This is a stated boundary of the product, not a gap we discovered late.
What does unknown mean? Is unknown the same as safe?
No, and the difference is the point of the product. Every answer carries a confidence tier: allow/high, deny/high, or unknown/abstain. When the evidence does not settle a question — an exotic filesystem, an unresolvable identity, a leg this release does not sign — Blastline abstains rather than guessing. An unknown is an unanswered question, and it is drawn differently from a settled one everywhere in the interface, hatched rather than filled, so it cannot be misread as a clean result.
How do you know the answers are right?
They are scored against the Linux kernel itself on a real multi-user server. Across 3,942 queries — 146 paths by 9 principals by 3 access intents — the engine answered 3,130 at high confidence and agreed with the kernel on 3,130 of 3,130: no false positives, no false negatives. It abstained on the remainder rather than guessing. Two further oracles were run over the same corpus: object identity, meaning was it reasoning about the right object, returned 0 mismatches, and reason locality returned 0 unfounded reasons across 2,020 denials.
How often does it run, and will it alert me?
It runs hourly with up to five minutes of jitter, on a systemd timer. It is not real-time and it does not watch the filesystem continuously. Blastline sends you no notifications today — there is no alerting, no email and no webhook for it; you read the results in the dashboard. The MySSL certificate and header monitoring on the rest of this site does have alerting, but that is a separate product and the two are not wired together yet. A Linux server with glibc 2.17 or newer plus root to install the package is all it needs, and the free plan covers one site per server.
Build the map before you need it
Install the agent on one server, point it at one site, and read the inventory. Worth most if you host more than one site on a box, or if you have ever had to answer "how bad was it?" after an incident — and worth nothing at all if you wanted a tool that grades everything and explains none of it.
Requires a free MySSL account and root on the server you install it on. One site per server on the free plan. File contents and secret values never leave the host; raw file paths and OS user names do.