Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ chown toolstack:toolstack /etc/toolstack/sps.crt /etc/toolstack/sps-ca.crt

Adjust account and install root to match the installer. Bootstrap creates only TLS
material/config, not a vault. Vault lives in `/var/lib/toolstack/sps.vault.json`,
audit in `/var/log/toolstack/sps.audit`; `/etc` remains read-only in the services.
audit in `/var/lib/toolstack/audit/sps.audit` (not under `/var/log`: SPS refuses group-writable ancestors and Ubuntu keeps `/var/log` group-writable; existing installs should point `SP_AUDIT_LOG` there); `/etc` remains read-only in the services.
Provision `sps init-vault` and `sps vault-set` as the service user with the venv,
explicit `--config /etc/toolstack/sps.env`, and the same passphrase as the SPS
runtime file. Keep SPS **stopped during all direct provisioning**. Never put real
Expand Down
2 changes: 1 addition & 1 deletion deploy/bootstrap-sps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def main():
p = argparse.ArgumentParser(description=__doc__)
p.add_argument('--config', default='/etc/toolstack/sps.env')
p.add_argument('--state-dir', default='/var/lib/toolstack')
p.add_argument('--log-dir', default='/var/log/toolstack')
p.add_argument('--log-dir', default='/var/lib/toolstack/audit')
args = p.parse_args()
os.umask(0o077)
config = Path(args.config).resolve()
Expand Down
4 changes: 3 additions & 1 deletion deploy/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ sudo -u "$SERVICE_USER" sh -c "cd '$REPO_ROOT' && '$VENV_PIP' install --quiet '.
# so set-password + the SPS audit logger land right instead of crashing on first write)
install -d -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 700 /var/lib/toolstack
install -d -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 700 /var/log/toolstack
# SPS refuses group-writable ancestors; Ubuntu keeps /var/log 0775, so audit lives under the state dir.
install -d -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 700 /var/lib/toolstack/audit
install -d -o root -g "$SERVICE_GROUP" -m 750 /etc/toolstack

# 5. Admin password (the panel fails closed without one)
Expand Down Expand Up @@ -100,7 +102,7 @@ Toolstack admin is installed. SPS still requires config/vault provisioning if ne
Status: systemctl status toolstack-admin toolstack-sps
Logs: journalctl -u toolstack-admin -f
journalctl -u toolstack-sps -f
tail -f /var/log/toolstack/sps.audit (SPS secret-access audit log)
tail -f /var/lib/toolstack/audit/sps.audit (SPS secret-access audit log)

Provision an agent (its bearer token prints once):
sudo -u $SERVICE_USER env XDG_CONFIG_HOME=/var/lib XDG_STATE_HOME=/var/lib \\
Expand Down
2 changes: 1 addition & 1 deletion deploy/sps.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SP_TLS_CERT = "/etc/toolstack/sps.crt"
SP_TLS_KEY = "/etc/toolstack/sps.key"
SP_TLS_CA = "/etc/toolstack/sps-ca.crt"
#SP_SECRET =
SP_AUDIT_LOG = "/var/log/toolstack/sps.audit"
SP_AUDIT_LOG = "/var/lib/toolstack/audit/sps.audit"

# Choose exactly one plugin.
SP_PLUGIN = "localfile"
Expand Down
2 changes: 1 addition & 1 deletion docs/sps.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ See [matrix](runtime-matrix.md) for unsupported Docker/Seatbelt/native-helper pa

Use [deployment bootstrap](../deploy/README.md): `/etc/toolstack/sps.env` is private
TOML, not a shell/systemd env file. The deployment wrapper passes `sps init`
`--state-dir /var/lib/toolstack --audit-log /var/log/toolstack/sps.audit`.
`--state-dir /var/lib/toolstack --audit-log /var/lib/toolstack/audit/sps.audit`.
Choose dedicated private immediate parents for vault, audit and boot identity;
unsafe existing paths are refused, never repaired by blind chmod. New nested
parents are 0700, vault/audit/lock 0600, nonsecret boot identity 0644 under its
Expand Down
6 changes: 3 additions & 3 deletions sps/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def init_runtime_paths(config: str | Path, *, state_dir: str | Path | None = Non
state = Path(state_dir) if state_dir is not None else (
Path("/var/lib/toolstack") if production else config.parent)
audit_path = Path(audit_log) if audit_log is not None else (
Path("/var/log/toolstack/sps.audit") if production else config.parent / "sps-audit.jsonl")
Path("/var/lib/toolstack/audit/sps.audit") if production else config.parent / "sps-audit.jsonl")
return state / "sps.vault.json", audit_path


Expand Down Expand Up @@ -113,7 +113,7 @@ def _cmd_serve(args) -> None:
warn_certificate_expiry(cfg.sp_tls_cert)
plugin = plugin_loader.load_plugin(cfg)
plugin.connect()
audit_log_path = cfg.sp_audit_log or "/var/log/toolstack/sps.audit"
audit_log_path = cfg.sp_audit_log or "/var/lib/toolstack/audit/sps.audit"
audit_log = audit.AuditLogger(audit_log_path)
boot_id = secrets.token_hex(16)
ctx = AppContext(
Expand Down Expand Up @@ -301,7 +301,7 @@ def main() -> None:
p_init = sub.add_parser("init", help="write a starter sps.env (cert + key + CA)")
p_init.add_argument("--config", default="/etc/toolstack/sps.env")
p_init.add_argument("--state-dir", help="directory for sps.vault.json (default: /var/lib/toolstack for production config, otherwise beside config)")
p_init.add_argument("--audit-log", help="audit log file (default: /var/log/toolstack/sps.audit for production config, otherwise beside config)")
p_init.add_argument("--audit-log", help="audit log file (default: /var/lib/toolstack/audit/sps.audit for production config, otherwise beside config)")
p_init.set_defaults(func=_cmd_init)
p_iv = sub.add_parser("init-vault", help="create the localfile vault file (separate from init)")
p_iv.add_argument("--config", default="/etc/toolstack/sps.env")
Expand Down
4 changes: 2 additions & 2 deletions sps/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Bootstrap(unittest.TestCase):
def test_production_and_temporary_path_selection_is_pure(self):
# No filesystem operations: production paths must never be created here.
self.assertEqual(init_runtime_paths("/etc/toolstack/sps.env"), (
Path("/var/lib/toolstack/sps.vault.json"), Path("/var/log/toolstack/sps.audit")))
Path("/var/lib/toolstack/sps.vault.json"), Path("/var/lib/toolstack/audit/sps.audit")))
self.assertEqual(init_runtime_paths("/temporary/config/sps.env"), (
Path("/temporary/config/sps.vault.json"), Path("/temporary/config/sps-audit.jsonl")))
self.assertEqual(init_runtime_paths("local.env"), (
Expand All @@ -24,7 +24,7 @@ def test_production_and_temporary_path_selection_is_pure(self):
self.assertEqual(init_runtime_paths(config, state_dir="/explicit/state", audit_log="/explicit/log/audit"), (
Path("/explicit/state/sps.vault.json"), Path("/explicit/log/audit")))
self.assertEqual(init_runtime_paths("/etc/toolstack/sps.env", state_dir="/explicit/state")[1],
Path("/var/log/toolstack/sps.audit"))
Path("/var/lib/toolstack/audit/sps.audit"))
self.assertEqual(init_runtime_paths("/temporary/config/sps.env", audit_log="/explicit/audit")[0],
Path("/temporary/config/sps.vault.json"))

Expand Down
Loading