Audience: Operators and CI/CD pipelines wiring
forgelm verify-auditinto release gates. Mirror: verify_audit-tr.md
The verify-audit subcommand validates the SHA-256 hash chain of a ForgeLM audit_log.jsonl produced under EU AI Act Article 12 record-keeping. When the operator's FORGELM_AUDIT_SECRET is set in the environment, per-line HMAC tags are also verified. The CLI is a thin dispatcher around the library entry point forgelm.compliance.verify_audit_log (returning forgelm.compliance.VerifyResult).
forgelm verify-audit [--hmac-secret-env VAR] [--require-hmac]
[-q] [--log-level {DEBUG,INFO,WARNING,ERROR}]
log_path
log_path (positional, required) — path to audit_log.jsonl. The genesis manifest sidecar (<log_path>.manifest.json) is auto-detected and cross-checked when present.
| Flag | Default | Description |
|---|---|---|
--hmac-secret-env VAR |
FORGELM_AUDIT_SECRET |
Name of the environment variable that holds the HMAC secret used at log-write time. When the variable is set, per-line _hmac tags are validated; when unset, only the SHA-256 chain is checked. |
--require-hmac |
False |
Strict mode. Exit 1 if the configured env var is unset (a pre-flight option error — the verifier never ran). Exit 6 if any line lacks an _hmac field (the log was read and failed strict-mode verification — a chain-integrity failure). Use this in regulated CI pipelines where every entry must be HMAC-authenticated. |
-q, --quiet |
off | Suppress INFO logs. |
--log-level {DEBUG,INFO,WARNING,ERROR} |
INFO |
Set logging verbosity. |
-h, --help |
— | Show argparse help and exit. |
| Code | Meaning |
|---|---|
0 |
EXIT_SUCCESS — the SHA-256 chain (and HMAC tags, when verified) is intact end-to-end. |
1 |
EXIT_CONFIG_ERROR — nothing could be compared: --require-hmac set with the configured env var unset, the log path does not exist / is a directory / is unreadable for a caller-input reason, or the log exists but holds zero entries and no genesis manifest pins what it should have held. There is no integrity verdict. |
2 |
EXIT_TRAINING_ERROR — the log exists but could not be read (permission denied, mid-read I/O failure). Retryable. |
6 |
EXIT_INTEGRITY_FAILURE — the log was read and the chain does not verify: chain break, HMAC mismatch, genesis-manifest mismatch, an undecodable line, non-UTF-8 bytes inside the log, or (under --require-hmac) a line missing its _hmac field. This is the tampering signal, and it is the reason the code exists — previously a broken hash chain and a mistyped path both exited 1, so a CI pipeline could not tell a security event from an operator typo. |
The codes are emitted by the dispatcher at _run_verify_audit_cmd (forgelm/cli/subcommands/_verify_audit.py), which probes the file first (_probe_log_readable) so a read failure routes to 1 or 2 before the verifier runs — every valid=False the library entry point returns after that probe succeeds is therefore a genuine integrity verdict (6). forgelm.compliance.verify_audit_log itself never raises for chain-level failures; it always returns a VerifyResult(valid=False, reason=...), and only raises OSError for a file that becomes unreadable mid-verification.
forgelm verify-audit is a read-only verifier and emits no entries to audit_log.jsonl. It only inspects the chain. The events that appear inside the log being verified are catalogued in audit_event_catalog.md (see the Common envelope row for the _hmac, prev_hash, and run_id fields the verifier walks).
$ forgelm verify-audit checkpoints/run/compliance/audit_log.jsonl
OK: 87 entries verified$ export FORGELM_AUDIT_SECRET="$(cat /run/secrets/audit-secret)"
$ forgelm verify-audit checkpoints/run/compliance/audit_log.jsonl
OK: 87 entries verified (HMAC validated)$ FORGELM_AUDIT_SECRET="$(cat /run/secrets/audit-secret)" \
forgelm verify-audit --require-hmac \
checkpoints/run/compliance/audit_log.jsonl
OK: 87 entries verified (HMAC validated)
$ echo $?
0If the secret env var is unset under --require-hmac, the command exits 1:
$ forgelm verify-audit --require-hmac checkpoints/run/compliance/audit_log.jsonl
ERROR: --require-hmac specified but $FORGELM_AUDIT_SECRET is unset.
$ echo $?
1For multi-tenant environments where each tenant carries its own secret variable:
$ TENANT_ACME_AUDIT_KEY="$(cat /run/secrets/acme-audit)" \
forgelm verify-audit --hmac-secret-env TENANT_ACME_AUDIT_KEY \
artifacts/acme/audit_log.jsonl
OK: 412 entries verified (HMAC validated)$ forgelm verify-audit checkpoints/run/compliance/audit_log.jsonl
FAIL at line 53: prev_hash mismatch — chain break suggests entry was inserted, removed, or reordered
$ echo $?
6A log file that exists but holds zero entries never verifies. Which code you get depends on whether a genesis manifest survives to say what the log should have contained.
No manifest — exit 1. Nothing exists to compare zero entries against, so the verifier cannot distinguish a deleted log from a mistyped path:
$ forgelm verify-audit checkpoints/run/compliance/audit_log.jsonl
FAIL: audit log at 'checkpoints/run/compliance/audit_log.jsonl' exists but contains 0 entries,
and there is no genesis manifest at
'checkpoints/run/compliance/audit_log.jsonl.manifest.json' to say what it should contain —
nothing could be verified. …
$ echo $?
1Manifest pins a first entry — exit 6. The manifest is a baseline, so a comparison ran and failed; this is the truncate-to-empty signal:
$ forgelm verify-audit checkpoints/run/compliance/audit_log.jsonl
FAIL at line 1: genesis manifest pins a first entry (first_entry_sha256='…', run_id='…')
but the audit log is empty — log truncated to zero entries
$ echo $?
6A manifest that is present but corrupt, or missing its pinned fields, also exits 6 — corrupting the sidecar must not be a quieter way to disarm the truncation guard than deleting it.
An empty log is never a legitimate fresh-run state. AuditLogger creates its output directory but not the log file; the file and its manifest are both written by the first event. A never-used log is therefore absent (exit 1, audit log not found), not empty — so an empty one is a truncation, a rotation that moved the body away, a stray touch, or a wrong path.
audit_event_catalog.md— events that appear inside the log this command verifies.verify_annex_iv_subcommand.md— companion verifier for the Annex IV technical-documentation artifact.verify_gguf_subcommand.md— companion verifier for exported GGUF model files.- Audit Log usermanual page — operator-facing primer on the log itself.
forgelm.compliance.verify_audit_log— the library entry point integrators call directly without going through the CLI.