Problem/Motivation

log() writes an unsigned row rather than dropping the entry when the configured signing key will not resolve. That is the right policy for ordinary auditing: an unsigned record is better than a missing one.

Evidence-required consumers invert that policy. If a governed mutation must not proceed without a signed precommit, an unsigned row is a failed guarantee. Those consumers can only check the key, append, and re-check. That narrows but cannot close the race in which the key vanishes during the append and returns after. They also have to replay the chain's key resolution themselves, which drifts if the chain's resolution changes.

Proposed resolution

Add two methods on AuditChainLoggerInterface:

  • logKeyed($channel, $operation, $metadata = []) — appends only when the row will be HMAC-signed with the currently configured key. If no key resolves, throw AuditChainSigningUnavailableException and write nothing. Key resolution is re-checked inside the chain lock so a vanishing key cannot produce an unkeyed row on this path.
  • signingStatus() — returns {keyed, key_id} from the chain's own key resolution, for cheap precondition checks and status reporting.

Ordinary log() is unchanged.

Remaining tasks

  • Land the interface methods and kernel tests on 1.x. Done in 1.x-dev.
  • Ship in 1.6.0.

User interface changes

None.

API changes

Additive methods on AuditChainLoggerInterface. Existing log() callers are unaffected.

Data model changes

None.

Comments

jmcerda created an issue. See original summary.

jmcerda’s picture

Version: 1.x-dev » 1.6.0
Status: Active » Fixed

Shipped in 1.6.0.

https://www.drupal.org/project/audit_chain/releases/1.6.0

The project page now documents logKeyed() and signingStatus() under Evidence-required consumers.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.