Phase 08 · Audit & security evidence

Audit and security evidence

A local, append-only, hash-chained record of what happened — with a vocabulary precise enough that a policy denial can never be mistaken for an operating-system denial.

Permanent ruleSecurity evidence must say exactly what happened, not what BitShout wishes had happened.

Phase 8 creates no authority. It records decisions, and it does so in a form that can be verified later by someone who does not trust the process that wrote it.

Distinctions preserved everywhere

These are maintained in the schema, in queries, in interface labels, in exports, and in the tests — so they cannot erode one layer at a time:

Observed fact             ≠ policy decision
Policy denied             ≠ operating-system denied
Authorization approved    ≠ action executed
Broker-mediated success   ≠ reusable credential release
Evidence present          ≠ authority granted
Missing or corrupt
  evidence                ≠ permission granted

The vocabulary

Term Meaning
observed A trusted component observed a fact or request. Not a policy or enforcement claim.
policyEvaluated A deterministic policy decision was made. May be paired with notEnforced.
authorized A trusted authorization or grant lifecycle event occurred. Not proof the action ran.
notEnforced There is a policy result but no OS or broker enforcement result.
enforcedAllow A trusted runtime or broker boundary actually allowed the operation.
enforcedDeny A trusted runtime or broker boundary actually denied the operation.
enforcementUnavailable Enforcement could not be proven available. Stays visible.
notApplicable Health, system or marker evidence rather than an access attempt.

The interface labels runtime denial as OS Denied and policy-only denial as Policy Denied. Those two strings are not interchangeable anywhere in the product.

What a record carries

Each SecurityEvidenceRecord holds the schema version, evidence ID, generation and monotonic sequence, timestamp, event type, category and severity, the trusted source component identity, containment session and subject IDs where known, process identity and process-instance evidence where known, the operation, resource and destination, the policy domain and outcome with its reason code and policy version, and the authorization request ID, grant ID, grant type and grant generation where known.

That is a lot of fields, and the reason is that a record which omits any of them cannot answer the question people actually ask afterwards: which thing, doing what, under whose authority, and did it work.

Append-only, per generation

Evidence is append-only within a generation. Clearing history and applying retention do not rewrite records; they open a new generation and write explicit marker records. The past is not edited to look tidier, it is closed and annotated.

Records are hash-chained, with the chain anchored in the macOS Keychain. Altering a record breaks verification for that record and for everything chained after it — and BitShout reports the break rather than silently re-anchoring, which would turn a tamper-evident store into a store that quietly forgives tampering.

Privacy

An audit trail must not become a second privacy problem. Redaction runs before records are written, not before they are displayed. Storage is local by default. Export requires an explicit action, produces a redacted and versioned artifact, and there is no automatic upload path to disable because there is no automatic upload path.

Enterprise evidence collection and remote attestation are deliberately out of scope for the initial roadmap.