Refuse to start with the state store or .env inside the clone
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m14s

Answering "is the workspace where the agent runs, or what it works
on?" — it is what it works on, and conflating the two is dangerous
rather than merely untidy.

The agent commits its workspace with git add -A and pushes it, so
anything inside the clone reaches the project repository. A .env
placed there would publish the LiteLLM, Matrix and Gitea tokens as a
side effect of the agent working correctly: silently, once, and
probably unnoticed. Startup now refuses both that and a state store
inside the clone, and .env.example documents the intended layout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
dongarandClaude Opus 5 committed 2026-09-08 22:31:39 +00:00
1 parent 2fb25b8195
commit dfa574aeec
3 files changed
+79 -1

No files matched your search

+25 -1
View File
@@ -71,7 +71,7 @@ class AgentConfig:
raise ConfigError(
"cannot start: these are unset or empty — " + ", ".join(missing)
)
return cls(
config = cls(
state_db=Path(env["NISSE_STATE_DB"]).expanduser(),
workspace=Path(env["NISSE_WORKSPACE"]).expanduser(),
project=env["NISSE_PROJECT"],
@@ -86,6 +86,30 @@ class AgentConfig:
gitea_operators=_people(env["NISSE_GITEA_OPERATORS"]),
base_branch=env.get("NISSE_BASE_BRANCH", "main"),
)
config._refuse_secrets_inside_the_clone(env)
return config
def _refuse_secrets_inside_the_clone(self, env: Mapping[str, str]) -> None:
"""The workspace is a git clone the agent commits with ``git add -A``
and pushes. Anything inside it reaches the project repository, so a
state store or an env file placed there would publish credentials as a
side effect of the agent working correctly — silently, and once.
"""
workspace = self.workspace.expanduser().resolve()
offenders = []
for label, path in (
("NISSE_STATE_DB", self.state_db),
("NISSE_ENV", Path(env.get("NISSE_ENV", ".env"))),
):
resolved = path.expanduser().resolve()
if resolved == workspace or workspace in resolved.parents:
offenders.append(f"{label} ({resolved})")
if offenders:
raise ConfigError(
"refusing to start: these sit inside the workspace clone at "
f"{workspace} and would be committed and pushed to the project "
"repository — " + ", ".join(offenders)
)
def redacted(self) -> dict[str, str]:
"""What the agent may safely announce about how it is configured."""