5 Commits
Author SHA1 Message Date
branderson ed2a843406 Say what changed, hold alerts during expected changes, and shorten the commands
Alerts now name the kind of change and the watched area it falls under, from
a fixed list, and report lists each path as added, modified or removed.
ignore_paths keeps a change in the report without alerting on it.

dejima-guard expect opens a window that holds change and unreachable alerts,
then accepts at its end. Critical paths and containment still alert, and a
window never accepts a critical path.

accept now runs a check afterwards so the heartbeat resumes, status
summarises the guard's state, and bin/dejima-guard-docker runs any command in
the container from any directory.
2026-10-15 15:09:56 -07:00
branderson 74761e0376 Keep the push URL out of the compose file, since it is a credential
An Uptime Kuma push URL carries its token in the path, which this project
already says: it is why the URL is passed to curl through a config on stdin
rather than in argv. The compose example then put it in an environment block,
where `docker inspect` prints it and anything that can read /proc can see it -
the same exposure the token was already being kept out of.

What it grants is worth stating rather than leaving as "a URL": anyone holding
it can tell Kuma this guard is healthy, which suppresses the one signal that
reports a guard that has died. That is the channel a compromised devbox cannot
reach, and the whole reason there is a second server in this design.

It goes in the mounted config beside ntfy_token now, with a test that neither
appears in the compose environment and that the setting is still documented
where it moved to.
2026-08-29 14:04:37 -07:00
branderson 9d7d82c6d2 Rebuild the image, since nothing else will
There is no registry for this: the image is built from the Dockerfile in the
checkout. `docker compose up -d` reuses whatever image already exists, so after
a git pull it starts the old code and reports success - an update that silently
did not happen, on the program whose job is to notice things.

`--build` on both commands that need an image. `exec` does not.
2026-08-28 22:14:43 -07:00
branderson 9c71beeea2 Say which machine each setting is about, and stop defaulting to root
Two reports from setting this up, and the second is a real defect rather
than a documentation one.

DEJIMA_GUARD_HOST READ AS THE HOST THE GUARD RUNS ON. It meant the one it
watches - the wrong end of the only connection this program makes. A name
that needs a comment to be read correctly is the wrong name, so it is
devbox_host and devbox_user now, under a heading that says everything in that
group describes the machine at the other end.

AND devbox_user DEFAULTED TO ROOT, on a machine whose own runbook builds it
with no root password and expects sudo from an ordinary account. The default
was wrong for every devbox built the documented way. There is no default now:
falling back to nothing would have ssh use the local username, which in a
container is an account that does not exist over there, so it says which is
missing instead.

Every setting is documented twice over: a table in the README saying what
goes in it, and etc/config.example with the reasoning attached. The compose
example carries a comment per variable rather than a bare list, since that is
the file somebody actually edits.

Three tests worth having beyond the rename: that no setting is named so it
could mean this machine, that a missing devbox_user is refused rather than
guessed, and that the two SSH commands still match the strings
dejima-devbox-hardener's dejima-guard-shell whitelists - one contract across
two repositories, and the failure if it drifts is a collection that fails and
gets reported as the devbox being unreachable.

`bats test/` 26 passing, 3 new.
2026-08-28 16:44:12 -07:00
branderson 0994b24347 Ship the compose file as an example, so a bare up cannot start it
The setup said to copy docker-compose.yml to docker-compose.override.yml,
edit that, and then run a bare `docker compose up -d`. That is wrong twice.

`docker compose up` reads docker-compose.yml AND
docker-compose.override.yml, and merges them - so an override leaves the
example values in play rather than replacing them. And a committed
docker-compose.yml means a bare `up` in a fresh clone starts the guard
pointed at example.invalid, doing nothing useful and reporting a devbox
unreachable that was never configured.

It is docker-compose.example.yml now, copied to docker-compose.yml, which is
gitignored - the same shape as etc/config.example, and the place a host and
some URLs belong.

The example also will not start as shipped: its host is CHANGE-ME.example.
invalid and the guard refuses that. dejima's nginx example takes the same
approach for the same reason - a file that cannot become a live config by
being copied and forgotten. The refusal names the value rather than saying
the host is unreachable, because unreachable is what it would otherwise
look like.

Three tests: the placeholder is refused, the shipped example still carries
it, and no docker-compose.yml is committed. The second exists because the
first stops protecting anything the moment somebody puts a plausible
hostname in the example.

`bats test/` 23 passing.
2026-08-28 16:18:48 -07:00