> For the complete documentation index, see [llms.txt](https://docs.envector.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.envector.io/1.5.x/operations-and-management/audit.md).

# Audit

The audit service records all key-lifecycle and gRPC API events into a tamper-resistant, WORM-backed store for compliance (e.g. electronic-finance supervision requirements, FIPS 140-3). This page covers the audit pipeline and its operation. For authentication and audit scopes see [Keycloak / OIDC](/1.5.x/operations-and-management/authentication/keycloak.md); for the KMS-side audit dependency see [KMS Architecture](/1.5.x/key-management/managed-kms.md#audit-dedicated-messaging).

## Overview

Every key-lifecycle event and gRPC API call is written to an immutable audit trail. Audit logs contain **no** sensitive plaintext (no face data, passphrases, or key material).

Audited events include:

* **KMS** — key generation, unseal/decryption (on service start), seal, rotation, revocation, permission-denied, bootstrap
* **enVector system** — every gRPC API call (`action`, `resource`, `result`, `duration`, caller identity, etc.)

## Pipeline

Audit records flow through a dedicated messaging stack — Vector (log agent) and Redpanda (a lightweight Kafka-compatible queue) — into object storage as JSONL:

```
endpoint (stdout/file) → Vector → Redpanda → audit service → S3/MinIO (JSONL)
```

| Service          | Role                                      | Default port   |
| ---------------- | ----------------------------------------- | -------------- |
| `audit`          | Audit service (gRPC API + storage writer) | `50052` (gRPC) |
| `audit-logagent` | Vector log agent                          | —              |
| `audit-logmq`    | Redpanda message queue                    | —              |

The KMS runs the same audit implementation as a **separate** instance, with its own topic (`envector.kms.audit.events.v1`) and its own `envector-kms-audit` bucket, distinct from the KMS public-key storage.

## Deployment

Enable the audit overlay via the helper script or Docker Compose:

```bash
./scripts/start_envector.sh --kms --keycloak --audit --console
```

> `--audit` enables the envector audit overlay on its own. (The KMS runs a separate audit pipeline enabled by the distinct `--kms-audit` flag, which implies `--kms`.)

## Immutable storage (WORM) and retention

In production, audit logs are stored so they cannot be deleted or altered during the retention window:

* **S3 Object Lock (WORM):** use `COMPLIANCE` mode in production
* **Format:** JSONL
* **Retention:** `ENVECTOR_AUDIT_RETENTION_DAYS` (production recommendation ≈ **2190 days = 6 years**)

## Operations

### 1. Audit-dedicated token issuance

Reaching the audit API requires the `audit:read` / `audit:export` scopes (see [Client scopes](/1.5.x/operations-and-management/authentication/keycloak.md#client-scopes)):

```bash
export AUDIT_TOKEN="$("${AUTH_DIR}/get_keycloak_token.sh" \
  --port "${KEYCLOAK_HOST_PORT}" --realm "${KEYCLOAK_REALM}" \
  --scopes "openid profile email audit:read audit:export" \
  security "${KEYCLOAK_LOCAL_USER_PASSWORD}")"
```

### 2. Audit event lookup

**REST:**

```bash
curl -s -X POST "http://audit-service:58052/v2/audit/events" \
  -H "Content-Type: application/json" \
  -H "x-tenant-id: my-tenant" \
  -H "Authorization: Bearer ${AUDIT_TOKEN}" \
  -d '{
    "start_time": "2026-05-01T00:00:00Z",
    "end_time":   "2026-05-15T23:59:59Z",
    "page_size":  100
  }' | jq .
```

**gRPC** (`audit.v2.AuditService/list_events`):

```bash
export AUDIT_ADDR="127.0.0.1:${ENVECTOR_AUDIT_HOST_PORT:-50052}"

grpcurl -plaintext \
  -H "x-tenant-id: tenant-a" \
  -H "authorization: Bearer ${SECURITY_TOKEN}" \
  -d '{"header":{"id":"ops-audit-list"},"start_time":"...","end_time":"...","page_size":20}' \
  "${AUDIT_ADDR}" \
  audit.v2.AuditService/list_events \
  | jq -e '.total_count > 0'
```

### 3. Audit export

```bash
grpcurl -plaintext \
  -H "x-tenant-id: tenant-a" \
  -H "authorization: Bearer ${SECURITY_TOKEN}" \
  -d '{"header":{"id":"ops-audit-export"},"start_time":"...","end_time":"...","format":"EXPORT_FORMAT_JSON"}' \
  "${AUDIT_ADDR}" \
  audit.v2.AuditService/export_events \
  | jq -r '.data' \
  > "audit-export-$(date +%Y%m%d-%H%M%S).jsonl"
```

Expected results:

* `total_count > 0`
* The export file is non-empty
* The JSONL contains key fields such as `action`, `result`, `claimed_tenant_id`

### 4. SIEM integration

Audit logs carry no plaintext sensitive data. Forward them to your integrated security monitoring system (Splunk, ELK, etc.) via its agent for real-time collection and alerting.

## Operational considerations

* Audit data is **not** automatically forwarded to external systems — establish a regular **export → retention** procedure.
* Restrict access on export files (`chmod 600`) and codify a retention policy (retention period, disposal criteria) as operational policy.
* In test environments where authentication is disabled, the `authorization` header can be omitted.

## Troubleshooting

| Symptom                 | Action                                                                                                             |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Audit result empty      | Wait 10–30 seconds after an SDK E2E or KMS call, then query again — resolves on its own if the pipeline is healthy |
| Audit pipeline abnormal | Check `audit-logagent`, `audit-logmq`, and `audit` logs and the Redpanda disk; clean up disk or restart audit      |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.envector.io/1.5.x/operations-and-management/audit.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
