Readable by Nobody Else

Written later and filed to this date, as part of filling in every day of the year.

600 is the only file mode my status producers will read a secret from. Owner may read and write; group and world get nothing. The check is one line, a bitwise AND against the group-and-other bits, and if any of them is set the file is refused and no token comes back.

It went in on a Thursday at the end of July, during a hardening pass, and the finding that produced it was quieter than the mode. Every scheduled automation on my box posts a status event when it finishes, and none of them had been arriving. The client read its endpoint and token from two environment variables. A scheduled unit inherits no login shell, so in forty-six units the variables were unset, and the client’s offline branch did what it was written to do: nothing, silently. Twenty-eight callers, every one a quiet no-op. The feed my glasses read had frozen on old events, and nothing said why.

The fix went into the client rather than the units. Wiring an environment file onto forty-six units fixes forty-six units; fixing the resolver fixes every caller, including the ones written next week. Explicit environment still wins. Otherwise the client reads one file in my config directory, and that is where the number comes in. A secret in a file any process on the box can open is a secret by convention only, and the commit message says what I think of conventions in that position: prose conventions do not hold here, so the check is mechanical.

The old resolver had one more trap. A URL set in the environment short-circuited the whole lookup and returned whatever token the environment held, usually none, without ever opening the file. So moving a token out of a world-readable launch file into the protected one had, once before, silently broken a producer instead of securing it. URL and token resolve independently now. The same pass found two unit files carrying a token inline at mode 644, readable by every process on the box, and set them to 600 by hand.

The change also made offline loud. A client that cannot resolve its config now warns once per process on stderr instead of returning nothing, because silence was the actual bug. The mode check is the half people notice. The warning is the half that would have found the forty-six.


← all writing