feat(local-identity): Stage 4 — security hardening (NK-WP-0002-T04)
Permission enforcement on startup: enforce_permissions() checks store dir
(700), user files (600), signing key, TLS key, audit.log, revoked.json.
CLI and run_server() call it before any sensitive operation.
New modules:
security.py check_store(), enforce_permissions(), print_security_check()
audit.py log_event() — append-only TSV audit log (mode 600)
revoke.py revoke(jti), is_revoked(jti) — revocation list (mode 600)
New CLI commands:
security-check Print per-check pass/warn/fail report; exit 1 on failure
revoke-token <jti|jwt> Add JTI to revocation list; accepts raw JTI or full JWT
Serve integration:
Audit log written for auth request, token issuance, and userinfo calls
Revocation checked at /userinfo; revoked tokens return 401
Docs: security model section in LocalIdentity.md — threat model,
assumptions, non-guarantees, SELinux/AppArmor guidance, revocation usage.
138 tests passing (34 new for Stage 4).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 08:06:56 +01:00
|
|
|
"""
|
|
|
|
|
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:
|
2026-03-02 08:25:21 +01:00
|
|
|
is_new = not path.exists()
|
feat(local-identity): Stage 4 — security hardening (NK-WP-0002-T04)
Permission enforcement on startup: enforce_permissions() checks store dir
(700), user files (600), signing key, TLS key, audit.log, revoked.json.
CLI and run_server() call it before any sensitive operation.
New modules:
security.py check_store(), enforce_permissions(), print_security_check()
audit.py log_event() — append-only TSV audit log (mode 600)
revoke.py revoke(jti), is_revoked(jti) — revocation list (mode 600)
New CLI commands:
security-check Print per-check pass/warn/fail report; exit 1 on failure
revoke-token <jti|jwt> Add JTI to revocation list; accepts raw JTI or full JWT
Serve integration:
Audit log written for auth request, token issuance, and userinfo calls
Revocation checked at /userinfo; revoked tokens return 401
Docs: security model section in LocalIdentity.md — threat model,
assumptions, non-guarantees, SELinux/AppArmor guidance, revocation usage.
138 tests passing (34 new for Stage 4).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 08:06:56 +01:00
|
|
|
with open(path, "a", encoding="utf-8") as fh:
|
|
|
|
|
fh.write(entry)
|
2026-03-02 08:25:21 +01:00
|
|
|
if is_new:
|
|
|
|
|
os.chmod(path, 0o600)
|
feat(local-identity): Stage 4 — security hardening (NK-WP-0002-T04)
Permission enforcement on startup: enforce_permissions() checks store dir
(700), user files (600), signing key, TLS key, audit.log, revoked.json.
CLI and run_server() call it before any sensitive operation.
New modules:
security.py check_store(), enforce_permissions(), print_security_check()
audit.py log_event() — append-only TSV audit log (mode 600)
revoke.py revoke(jti), is_revoked(jti) — revocation list (mode 600)
New CLI commands:
security-check Print per-check pass/warn/fail report; exit 1 on failure
revoke-token <jti|jwt> Add JTI to revocation list; accepts raw JTI or full JWT
Serve integration:
Audit log written for auth request, token issuance, and userinfo calls
Revocation checked at /userinfo; revoked tokens return 401
Docs: security model section in LocalIdentity.md — threat model,
assumptions, non-guarantees, SELinux/AppArmor guidance, revocation usage.
138 tests passing (34 new for Stage 4).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 08:06:56 +01:00
|
|
|
except OSError:
|
|
|
|
|
pass
|