---
name: audit-and-compliance
description: Configure and verify audit logging for tibi website projects. Covers server-level audit config, collection audit actions, audit.return filtering, TTL/retention, source semantics, and what later agents must check before relying on audit trails.
---

# audit-and-compliance

## When to use this skill

Use this skill when:

- a project needs auditable create/update/delete activity
- operators or stakeholders need a trace of who changed content and how
- hooks, jobs, or actions mutate important collections and that history matters
- sensitive data could land in audit snapshots and must be filtered safely

## Goal

Give later agents a concrete workflow for deciding, configuring, and validating audit logging on this stack.

Audit is not just “turn it on”. A usable audit setup must answer:

- what is logged
- how long it is kept
- who can read it
- which sensitive fields must be stripped
- how hook/job/action side effects appear in the audit trail

## Source of truth

Use these sources when implementing or reviewing audit behavior:

- `tibi-server/docs/10-audit.md`
- `tibi-server/docs/06-hooks.md`
- `tibi-server/docs/11-jobs.md`
- `tibi-server/docs/19-actions.md`
- active server/project config

## Core audit model

Audit requires an explicit server-level decision:

```yaml
audit:
    enabled: true
    defaultTTL: "720h"
    defaultLimit: 50
    maxLimit: 10000
```

At collection level, audit is controlled separately:

```yaml
name: content
audit:
    enabled: true
    actions:
        - create
        - update
        - delete
```

Default audited collection actions are `create`, `update`, and `delete`.

Important:

- `get` can also be audited when needed
- system actions such as `login`, `reload`, and `shutdown` are controlled by server-level audit enablement
- bulk API mutations are still audited even though the internal action naming differs (`bulkCreate`, `bulkUpdate`, `bulkDelete`)

## Source semantics matter

Audit entries are not all equal. The `source.type` tells you where the mutation came from:

- `controller` — direct API CRUD request
- `hook` — database mutation performed from a hook
- `job` — database mutation performed from a scheduled job
- `system` — internal system operation

For website projects this matters because content can change through:

- direct editor CRUD
- action-triggered persistence
- hook-side side effects
- cleanup or synchronization jobs

If a project relies on audit trails for governance or debugging, later agents must understand these source types instead of assuming every change came from an editor UI save.

## Authentication context in audit entries

Audit also records how a request was authenticated.

Relevant fields include:

- `authMethod`
- `tokenLabel`
- `tokenPrefix`
- `userId`
- `username`
- `ip`

Practical implication:

- use labeled admin tokens for operator workflows so audit output stays readable
- do not treat all token-based writes as anonymous noise

## Snapshot exposure and `audit.return`

Audit snapshots can contain more than a normal API read would expose.

That means fields that are stripped by normal read hooks can still appear in audit snapshots unless you filter them explicitly.

Use `audit.return` hooks when a collection may contain:

- passwords
- API keys
- internal secrets
- sensitive operator-only notes

Example shape:

```yaml
hooks:
    audit:
        return:
            type: javascript
            file: hooks/users/audit_return.js
```

Use this hook to delete or suppress sensitive `snapshot` and `changes` data before the audit response is returned.

## Retention and limits

Audit is an operator/compliance concern, not just a developer concern.

Decide deliberately:

- whether audit is enabled at all
- how long audit logs should be retained (`defaultTTL`)
- what read limits make sense (`defaultLimit`, `maxLimit`)
- whether the target environment expects short-term diagnostics or longer retention

Do not enable audit and leave retention undefined by habit.

## Recommended patterns for website projects

### Content governance

Recommended shape:

- audit enabled for collections whose changes affect public output or editorial accountability
- clear retention decision with operations
- readable token labels for automation or deploy-related writes

### Hook-heavy workflows

Recommended shape:

- understand which hook-side writes will appear as `source.type: "hook"`
- do not assume audit trails point only to controller actions
- document important side effects when hooks fan out into multiple writes

### Jobs and automation

Recommended shape:

- know that job-side DB mutations appear as `source.type: "job"`
- if job behavior matters operationally, make that visible in the job design and ops notes

### Sensitive collections

Recommended shape:

- explicit `audit.return` filtering
- do not expose raw snapshots just because admins technically can read the endpoint

## Anti-patterns

- enabling audit without deciding retention
- treating audit as equivalent to normal collection reads
- forgetting that hooks and jobs create their own audit source types
- relying on unlabeled tokens for important automated writes
- storing sensitive data in snapshots without `audit.return` filtering

## Verification checklist

After audit-related changes, verify all of these:

1. server-level audit settings are deliberate
2. collection-level audited actions match the actual governance need
3. a representative write produces the expected audit entry
4. hook/job/action side effects produce understandable source metadata
5. sensitive fields are filtered from audit output where required
6. read visibility and retention expectations are documented

## What an LLM should inspect first

When asked to design or review audit behavior on this starter, inspect in this order:

1. `tibi-server/docs/10-audit.md`
2. active server audit config
3. collection-level `audit:` sections
4. any hook/job/action workflow that mutates important collections
5. whether `audit.return` filtering is needed

This prevents “audit enabled” setups that are technically on but operationally weak.
