Skip to content

smaug has no logs, and that is a decision — record it as a residual #255

Closed

Description

@Gerrrt

ADR-0016
decided that the NAS on CasaBonita (40) is scraped, never pushed — metrics
come out over 99→40:9100, and nothing on that segment initiates anywhere. Loki
has no pull. Metrics survive that reversal; logs do not.

So the NAS will be the one host in the estate whose compromise is invisible.
Prometheus will show it alive, loaded and busy, and nothing will show what it
did. Jellyfin is a large codebase with a network-facing indexer, sitting on the
segment whose stated assumption is that everything on it is already
compromised — which is exactly the host you would want logs from.

Important

The trigger has fired. This issue said "Nothing to do until the hardware
lands" and "record it as a residual when it lands". It landed:
smaug — the host this issue filed as zion, renamed by
ADR-0038
— has held 10.0.40.30 since 2026-09-16, runs TrueNAS
(ADR-0040),
and its four inbound passes are created and verified in position. It runs no
Alloy agent and ships no logs, exactly as decided. The three boxes below are
now writable
, and none of them waits on the ZFS pool, which is why this
moved to Wave 0. #102 is closed; the build is
#413.

Why the obvious fix is worse than the gap

A 40→99:3100 rule would collect the logs. It would also:

  • Be the first upward path in the estate — the property ADR-0008 claims to
    keep ("nothing untrusted ever initiates upward") and ADR-0016 went out of its
    way to preserve. All four passes that exist today reach in, and
    CasaBonita's Reaches column is unchanged for exactly this reason.
  • Let anything that reaches the NAS write to the log store the rest of the
    estate is judged by
    . Loki's ingest is unauthenticated by design
    (ADR-0012,
    #182), so this does not just
    move logs — it hands a low-trust host the ability to inject and delete them.
  • Make a sentence in SECURITY.md false. The residual row for the ingest ports
    currently reads "Firewall default-deny is the whole control: only Hicks (50)
    and Winterfell (99) can reach the host at all, and never an untrusted
    segment
    ." That last clause survives ADR-0016 only because the direction was
    reversed. This rule would retire it.

Trading a blind spot on one host for a write path into every host's logs is the
wrong way round, which is why ADR-0016 chose the blind spot. But it chose it —
it is not an oversight, and it should not be discovered later as one.

What this issue is for

Not to close the gap. To record it where residuals are recorded:

  • A row in SECURITY.md's Known exposure table, in the same
    "Accepted residual, not a fix in progress" form as the ingest-port and
    unencrypted-disk rows.
  • A line in docs/security.md, near the tripwire paragraph — the tripwire
    is the control that still watches this segment, and it is worth saying
    that it is the only one. That paragraph moved on 2026-09-16 when the
    rules were created and the prose had to stop saying CasaBonita has "no
    path to anything else"; this line belongs beside the wording that
    replaced it.
  • Decide whether TerminalSegmentReachedInternalNetwork is enough on its
    own for this host, or whether the absence of logs deserves something of
    its own. Note the trap: a rule that alerts on "no logs from smaug"
    cannot exist, because there were never any logs to stop arriving. This is
    the SuricataStopped reasoning in security.rules.yaml:241-250 again —
    absence of a signal is indistinguishable from absence of the service —
    and it is why the answer here is probably "the tripwire, and honesty in
    the docs", not a new alert.

One thing to state while writing it, because it is newly true. smaug runs
no Alloy, so it has no logs and no SMART collection and no patch state — every
one of those rides the push this host does not make. The blind spot is wider
than the logs this issue was filed about, and the rest of it is its own issue
rather than a fourth box here.

Found writing ADR-0016 for #95.

Activity

  1. added
    documentationImprovements or additions to documentation
    securityA credential, an exposure, or a control that is weaker than recorded
    on Sep 4, 2026
  2. Gerrrt commented on Sep 8, 2026

    @Gerrrt
    OwnerAuthor

    Nothing to add to SECURITY.md yet — every row in that table is an observed
    finding about a host that exists, and zion is still not bought
    (network.md says so; ADR-0016's three rules are written down and not
    created). But the third checkbox is answerable now, and answering it removes
    the only thinking left in this issue.

    Is TerminalSegmentReachedInternalNetwork enough on its own?

    It is a positional check, not a compromise detector, and it should be
    described as the former.
    Three facts from the repository:

    • It fires on zion initiating toward 30, 50 or 99, which ADR-0016 says
      will never happen. Return traffic for a session Winterfell opened is carried
      by state and never consults the ruleset, so a scrape works and the rule stays
      silent — as designed.
    • It sees the firewall's view. Anything zion does inside VLAN 40 — to the
      televisions, on the same broadcast domain — never reaches morpheus, and
      ADR-0016 already says the TVs need no rule for exactly that reason.
    • It is a Loki rule over filterlog, so it watches the segmentation around
      the NAS, not the NAS.

    So it is the control that watches the segment, and it is the only one. The
    absence-of-logs alert this issue warns about cannot exist, for the reason the
    file records — not at security.rules.yaml:241-250, which is KernelOomKill,
    but in the block headed NO LOG-BASED "SuricataStopped" RULE, DELIBERATELY
    (now around line 560): absence of a signal is indistinguishable from absence
    of the service, and there was never a signal here. The answer is the
    tripwire and honesty in the docs.
    No new alert.

    Ready to paste on the day

    SECURITY.md, known-exposure table, after the Loki size-ceiling row:

    | The NAS ships no logs | **Accepted residual, not a fix in progress.** `zion` on CasaBonita (40) is scraped and never pushes — ADR-0016 reversed the direction so nothing on a terminal segment initiates upward. Metrics survive that; logs do not, because Loki has no pull and its ingest is unauthenticated (the row above), so a `40 → 99:3100` rule would hand a low-trust host the ability to inject into and delete from the log store the rest of the estate is judged by. Prometheus will show `zion` alive and busy; nothing will show what it did. The tripwire on `igc0.40` is the one control that still watches that segment, and it watches the boundary, not the host. |
    

    docs/security.md, after the tripwire paragraph:

    One host will be behind those tripwires with nothing else watching it. `zion`
    on CasaBonita is scraped and never pushes (ADR-0016), so it has metrics and no
    logs — the one host in the estate whose compromise is invisible from here. The
    tripwire on `igc0.40` is the only control on that segment, and it watches the
    boundary, not the host; an alert on "no logs from `zion`" cannot exist, because
    there were never any to stop. Recorded in `SECURITY.md` as an accepted residual.
    

    Both are drafts against the design; check them against the box when it exists
    — in particular that the address is 10.0.40.30 and that the 99 → 40:9100
    pass is the only rule that names it.

    Still blocked on #102's hardware; nothing else to do here until then.

    🤖 Generated with Claude Code

  3. added this to the Wave 3 — NAS milestone on Sep 11, 2026
  4. added
    seq/2Step 2 within its milestone; same number = can run in parallel
    seq/1Step 1 within its milestone; same number = can run in parallel
    and removed
    seq/2Step 2 within its milestone; same number = can run in parallel
    on Sep 11, 2026
  5. changed the title [-]The NAS will have no logs, and that is a decision — record it as a residual when it lands[/-] [+]smaug has no logs, and that is a decision — record it as a residual[/+] on Sep 17, 2026
  6. Gerrrt commented on Sep 17, 2026

    @Gerrrt
    OwnerAuthor

    The trigger has fired, and this moved to Wave 0. smaug exists, is
    addressed, runs no Alloy and ships no logs — exactly as ADR-0016 decided. The
    three residual rows can be written now; none of them waits on the pool. See
    the build comment on #413.

    The blind spot turned out to be wider than the logs this issue was filed about:
    SMART and patch state ride the same push, and this host makes none. That is
    #483 rather than a fourth
    checkbox here, but the residual rows should describe the whole of the gap and
    not just its logging half.

  7. added a commit that references this issue on Sep 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationsecurityA credential, an exposure, or a control that is weaker than recordedseq/1Step 1 within its milestone; same number = can run in parallel

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions