""" Append-only audit log for local-identity. All CLI commands and OIDC server events write one entry per operation to ~/.local-identity/audit.log (mode 600). Format (TSV): ISO-timestamp command username outcome Example: 2026-03-02T00:00:00Z init alice ok 2026-03-02T00:01:00Z serve/auth alice auth_request 2026-03-02T00:01:01Z serve/token alice token_issued Failures (e.g. file permission errors) are silently swallowed — the audit log must never interrupt the primary operation. """ import datetime import os from pathlib import Path from .store import _store_dir def _audit_log_path() -> Path: return _store_dir() / "audit.log" def log_event(command: str, username: str | None, outcome: str) -> None: """Append one audit entry. Silent on any I/O failure.""" timestamp = datetime.datetime.now(datetime.timezone.utc).strftime( "%Y-%m-%dT%H:%M:%SZ" ) entry = f"{timestamp}\t{command}\t{username or '-'}\t{outcome}\n" path = _audit_log_path() try: is_new = not path.exists() with open(path, "a", encoding="utf-8") as fh: fh.write(entry) if is_new: os.chmod(path, 0o600) except OSError: pass