cg_audit_log() opens an append-only, hash-chained log; pass it to
policy_apply() (audit = log) to record every decision, allowed or
blocked, or record a decision yourself with audit_record(). Each record
says who sent what kind of data where, under which policy revision and
rule - never the text or the values. With an audit key (key or
CREDGATE_AUDIT_KEY; not the token key), identifiers are recorded as keyed
hashes, so whoever holds the key can check whether a given identifier was
involved. Card verification codes are never hashed.
Usage
cg_audit_log(path, key = NULL, actor = NULL)
audit_record(log, decision)
audit_verify(path)
audit_read(path)Arguments
- path
The log file (JSON Lines); created if missing.
- key
Audit key (64+ hex digits or raw);
NULLusesCREDGATE_AUDIT_KEYif set, otherwise identifiers are not hashed.- actor
Who makes the requests; defaults to the operating-system user.
- log
A log from
cg_audit_log().- decision
A decision from
policy_decide()orpolicy_apply().
Value
cg_audit_log(): a log. audit_record(): the record (a list),
invisibly. audit_verify(): a list with ok, records, head, and for
a broken log the failing line and the error. audit_read(): a data
frame, one row per record, with the items as a list column.
Details
audit_verify() checks that no record was edited, deleted, inserted or
reordered; keep copies of the returned head elsewhere to detect records
removed from the end. audit_read() returns the records. The same files
are written and verified by the Python package. Needs the openssl package.
Examples
policy <- cg_policy(list(
policy = "credgate-policy", version = 1L, id = "example", revision = 1L,
destinations = list(claude = list(tier = "frontier", provider = "anthropic")),
rules = list(list(id = "no-ids", action = "redact", when = list(classes = list("identity_strong")))),
default_action = "redact"
))
path <- tempfile(fileext = ".jsonl")
log <- cg_audit_log(path, actor = "analyst1")
policy_apply(policy, "PAN ABCPE1234F", "claude", audit = log)
#> Policy example (revision 1), destination claude (frontier): allowed
#> placeholder action rule
#> [PAN] redact no-ids
audit_verify(path)
#> Audit log intact: 1 record; head
#> 83578fd8da405ec0f0d0c61762910daddfb9e846b71a1f5bfd1a21b966460019
audit_read(path)[, c("seq", "actor", "destination", "allowed")]
#> seq actor destination allowed
#> 1 1 analyst1 claude TRUE