Skip to contents

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); NULL uses CREDGATE_AUDIT_KEY if 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() or policy_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