Skip to content

Audit Events

Lumi emits security audit events as structured JSON to stdout. In BYOC deployments, the customer is responsible for log shipping, SIEM ingestion, retention, tamper protection, and access control for stored logs. Lumi is responsible for event emission and the stable schema documented here.

Transport

  • lumi-api emits audit events through the no.lumi.audit logger.
  • lumi-dashboard emits audit events through a dedicated server-side pino logger.
  • General log-level knobs must not silence audit events.
  • Audit examples below are synthetic and do not contain production identifiers.

Schema

Current schema version: lumi.audit.v1.

Required fields:

FieldDescription
audit_schemaSchema version, currently lumi.audit.v1
audit_eventStable event id from the catalog below
audit_categoryauth, admin, api_key, export, or delete
audit_operationOperation verb such as create, delete, or authorize
audit_outcomesuccess, denied, not_found, conflict, or failure
actor_typeoidc_user, api_key, anonymous, or system
resource_typeResource category for the event

Optional fields include actor_user_ref, actor_key_id, actor_is_org_admin, org_id, org_slug, team_id, team_slug, resource_id, resource_id_pseudonymized, resource_count, route_template, and request_method.

Role-gated team operations can also emit actor_role, effective_role, required_role, role_source, and authorization_policy. actor_role is the role from the selected team mapping before org-admin coercion, while effective_role is the role used for the authorization decision. authorization_policy is one of explicit_team_required, ambiguous_multi_team_read, team_editor_required, team_admin_required, secret_key_required, secret_key_minting_blocked, or secret_key_rotation_blocked.

actor_user_ref and pseudonymized resource ids use the same deterministic pseudonym in API and dashboard logs: id: plus the first 12 lowercase hexadecimal characters of SHA-256 over the UTF-8 identifier.

Privacy Rules

Audit events must not contain bearer tokens, API key values, API key hashes, session ids, encrypted cookie values, emails, display names, raw OIDC subjects, raw OIDC group ids, raw feedback text, raw answer values, raw export filter values, or raw customer-controlled surveyId values.

When an identifier is customer-controlled, the event uses a pseudonymized resource_id and sets resource_id_pseudonymized=true.

Event Catalog

EventCategoryMeaning
auth.oidc.successauthDashboard OIDC callback created a server-side session
auth.oidc.deniedauthAPI rejected an invalid bearer token
auth.oidc.failureauthAPI OIDC validation failed unexpectedly
auth.org_admin.deniedauthOrg-admin authorization rejected a caller
auth.team.deniedauthTeam authorization rejected a caller
auth.team.explicit_team_missingauthAn explicit-only route lacked ?team=, or a multi-team read was ambiguous
admin.org.updateadminOrganization metadata changed
admin.team.createadminTeam created
admin.group_mapping.createadminOIDC group mapping created
admin.group_mapping.deleteadminOIDC group mapping deleted
admin.survey_definition.deleteadminSurvey definition deleted
api_key.createapi_keyAPI key created
api_key.rotateapi_keyAPI key rotated
api_key.revokeapi_keyAPI key revoked
export.feedbackexportFeedback export generated
feedback.deletedeleteSingle feedback item deleted
survey_feedback.deletedeleteFeedback and markers for a survey deleted
marker.deletedeleteRating marker deleted
tag.deletedeleteFeedback tag deleted

Team-selection policy migration

auth.team.explicit_team_missing now represents two denied decisions. Use the stable, non-PII authorization_policy field to distinguish them:

authorization_policyMeaning
explicit_team_requiredExport, mutation, or API-key operation requires an explicit team even for a one-team caller
ambiguous_multi_team_readA normal read lacked a usable team while the caller had more than one authorized team

SIEM alerts and dashboards that previously grouped only by event id must also group by authorization_policy. Expect denied-event volume to increase when multi-team users or custom clients omit the query parameter. Neither policy contains a team slug, UUID, raw path, email, display name, or submission data.

API Key Event Read Surface

Dashboard clients can read the API key lifecycle trail for an authorized team:

http
GET /api/v1/dashboard/api-keys/events?team={teamSlug}&keyId={uuid?}&limit={1..100?}

The response is additive and reserves cursor pagination for a later release:

json
{
  "events": [
    {
      "id": "00000000-0000-0000-0000-000000000001",
      "keyId": "00000000-0000-0000-0000-000000000002",
      "keyPrefix": "lumi_pk_live",
      "keyType": "pk",
      "eventType": "created",
      "actor": {
        "type": "oidc_user",
        "userRef": "id:fcdec6df4d44",
        "keyId": null
      },
      "createdAt": "2026-06-13T12:00:00Z"
    }
  ],
  "nextBefore": null
}

Org admins can read events for all keys in the authorized team. Non-admin users can read only pk key events. If a non-admin requests an invisible sk key by id, the response returns an empty event list rather than confirming whether the key exists.

Lumi Analytics — bygget på navikt/lumi (MIT-lisens)