Skip to main content

Audit event catalog

Each audit event records occurredAt, actor_user_id, subject_user_id, action, target_type, target_id, channel, metadata, and workspace_id (when applicable). See Audit for scopes, retention, and export.

Authentication

  • LOGIN_SUCCESS metadata: { method }
  • LOGIN_SUCCESS_2FA metadata: { method }
  • LOGIN_FAILED metadata: { email, reason }
  • LOGOUT
  • TWO_FACTOR_ENABLED
  • TWO_FACTOR_DISABLED
  • EMAIL_VERIFICATION_SENT
  • EMAIL_VERIFICATION_RESENT
  • EMAIL_VERIFICATION_FAILED
  • EMAIL_VERIFIED
  • PASSWORD_RESET_REQUESTED
  • PASSWORD_RESET_COMPLETED
  • PASSWORD_CHANGED
  • REGISTER_DUPLICATE_ATTEMPT — recorded against the existing account when someone tries to register with an email that already has one; no new account or session is created.

Workspace & RBAC

  • WORKSPACE_CREATED metadata: { name, kind }
  • WORKSPACE_RENAMED metadata: { before.name, after.name }
  • WORKSPACE_DELETED
  • MEMBER_INVITED_OR_UPDATED metadata: { role, email, workspace_name, recipient_type } (fires when the invitation record or membership is created or upserted, independently of email delivery)
  • INVITE_EMAIL_SENT metadata: { role, email, workspace_name } (fires only after the invitation email is successfully dispatched; absent if SMTP fails)
  • INVITATION_CANCELLED metadata: { email, role, workspace_name, invitation_id } (fires when a workspace admin or manager cancels a pending invitation)
  • MEMBER_ROLE_CHANGED metadata: { role }
  • MEMBER_REMOVED
  • WORKSPACE_MEMBERSHIP_ACCEPTED
  • WORKSPACE_ALERT_SETTINGS_UPDATED

Tokens

  • TOKEN_CREATED metadata: { name, type, category }
  • TOKEN_UPDATED metadata: { fields, changes }
  • TOKEN_DELETED metadata: { name, reason }; deletions performed by obsolete-token cleanup also include { location, provider } and use reason: "import_cleanup"
  • TOKENS_TRANSFERRED_FROM_FROZEN
  • TOKENS_TRANSFERRED_BETWEEN_WORKSPACES
  • TOKENS_REASSIGNED_CONTACT_GROUP

Contacts & WhatsApp

  • WORKSPACE_CONTACT_CREATED metadata: { contact_id, phone_masked }
  • WORKSPACE_CONTACT_UPDATED metadata: { contact_id, fields_updated }
  • WORKSPACE_CONTACT_DELETED metadata: { contact_id }
  • WHATSAPP_TEST_SENT
  • WHATSAPP_TEST_SENT_TEMPLATE
  • WHATSAPP_TEST_FAILED
  • WHATSAPP_TEST_FAILED_TEMPLATE
  • WHATSAPP_TEST_RATE_LIMITED
  • WHATSAPP_TEST_ERROR

Alert delivery

  • ALERT_QUEUED metadata: { daysUntil, threshold, dueDate }
  • ALERT_CHANNELS_UPDATED metadata: { alertKey, from, to }
  • ALERT_NOT_QUEUED_NO_CHANNEL metadata: { reason }
  • ALERT_SENT metadata: { days, channels }
  • ALERT_SEND_FAILED metadata: { days, error, attempts }
  • ALERT_PARTIAL_SUCCESS metadata: { channel, errors }
  • ALERT_RETRY_SCHEDULED metadata: { days, next_attempt_at, remaining_channels }
  • ALERT_BLOCKED_MAX_ATTEMPTS metadata: { days, attempts_email, attempts_webhooks, attempts_whatsapp }
  • ALERT_BLOCKED_WHATSAPP_ERROR metadata: { days }
  • ALERT_BLOCKED_PLAN_LIMIT metadata: { days, monthlyCount, limit }
  • ALERT_CHANNEL_BLOCKED_PLAN_LIMIT metadata: { channel, monthlyCount, limit }
  • CHANNEL_LIMIT_WARNING_SENT metadata: { monthlyCount, limit }
  • CHANNEL_LIMIT_REACHED_SENT metadata: { channel, monthlyCount, limit }
  • LIMIT_WARNING_SENT metadata: { monthlyCount, limit }
  • LIMIT_REMINDER_SENT metadata: { limit }
  • ALERT_MANUAL_RETRY
  • WEEKLY_DIGEST_SENT metadata: { contact_group_id, contact_group_name, tokens_count, channels, week_start_date }

Billing & plan

  • PLAN_CHANGED metadata: { plan, previous_plan, from_plan, to_plan, source, source_label }. Recorded on every plan transition (upgrade, downgrade, or Stripe-driven change). Upgrading away from Free automatically unfreezes workspaces you administer, but that side effect is not recorded as a separate audit event; check to_plan on this event instead.
  • PLAN_DOWNGRADED metadata: { disabled, frozen_workspaces, plan, previous_plan }. Recorded when a Stripe subscription cancellation or non-renewal takes effect; frozen_workspaces is the count of workspaces frozen by the downgrade.
  • ALERTS_REQUEUED_AFTER_PLAN_CHANGE
  • ALERTS_BULK_REQUEUED

User settings & integrations

  • ALERT_PREFS_UPDATED metadata: { fields_updated }
  • ACCOUNT_DELETION_FEEDBACK metadata: { reason }
  • INTEGRATION_SCAN metadata: { provider, region, success, tokens_found }
  • INTEGRATION_DETECT_REGIONS metadata: { provider, regions_found }
  • TOKEN_IMPORTED metadata: { source, name, type }
  • TOKENS_IMPORTED metadata: { source, count, method }

Endpoint monitoring

  • DOMAIN_MONITOR_CREATED metadata: { url, ssl_detected }
  • DOMAIN_MONITOR_UPDATED metadata: { url, fields_updated }
  • DOMAIN_MONITOR_DELETED metadata: { url }
  • DOMAIN_MONITOR_HEALTH_CHECK metadata: { url, status, response_ms }

CertOps

  • CERTOPS_CERTIFICATE_REGISTERED / CERTOPS_CERTIFICATE_IMPORTED metadata: { source, count, certificate_ids, fingerprints_sha256 }. source is "api" for CertOps API registrations (event name CERTOPS_CERTIFICATE_REGISTERED) or "import" for dashboard PEM imports (event name CERTOPS_CERTIFICATE_IMPORTED).
  • CERTOPS_CERTIFICATE_RETIRED metadata: { managedCertificateId, tokenId, status, reason, fingerprintSha256 }.
  • CERTOPS_JOB_CREATED_MANUAL metadata: { operation, subjectType, subjectId, source }. Emitted when a workspace manager creates an executor job manually from the dashboard or POST .../certops/jobs. source is always "api".
  • CERTOPS_EXECUTOR_EVENT_ACCEPTED metadata: { apiTokenId, executorEventId, eventType, jobId, logId, status, evidenceIds }. Emitted for every accepted job lifecycle event posted by a CertOps executor (agent) using a machine API token.
  • CERTOPS_EVIDENCE_ACCEPTED metadata: same fields as CERTOPS_EXECUTOR_EVENT_ACCEPTED. Emitted alongside it whenever the accepted event carried one or more evidence items.
  • CERTOPS_EVIDENCE_REJECTED metadata: { apiTokenId, jobId, eventId, eventType, rejectionCode, routeFamily }. Emitted when submitted evidence fails validation or is too large, or when it contains private key material (rejectionCode: PRIVATE_KEY_MATERIAL_REJECTED).
  • CERTOPS_KEY_MATERIAL_REJECTED — emitted whenever a request is rejected because it contained private key material; TokenTimer never accepts or stores private keys. Two call sites, two metadata shapes: dashboard/API requests via middleware use { code: "PRIVATE_KEY_MATERIAL_REJECTED", method, path, body_type }; CertOps executor events (machine token) use { code: "PRIVATE_KEY_MATERIAL_REJECTED", method, routeFamily, apiTokenId }.
  • CERTOPS_GENERIC_SECRET_REDACTION_APPLIED metadata: { ...executor event fields, redactionApplied: true, redactionCount, redactedFields }. Emitted when an executor event's free-text fields (for example command output) matched a generic secret pattern and were redacted before storage.

Agents and the execution plane

These events cover the native TokenTimer agent (as opposed to the external executor path above).

  • CERTOPS_AGENT_BOOTSTRAP_TOKEN_CREATED metadata: { bootstrap_token_id, token_prefix, name, status, expires_at }. Emitted when an admin mints a single-use ttboot_ token to enroll an agent. The token value itself is never in the audit trail, only its prefix.
  • CERTOPS_AGENT_BOOTSTRAP_TOKEN_REVOKED metadata: { bootstrap_token_id, token_prefix, name, status, revoked_at }. A successful enrollment consumes the token rather than revoking it, so a used token produces no separate event; look for the agent's own registration instead.
  • CERTOPS_AGENT_RETIRED metadata: { agentId, force, reason, leasedJobs }, plus { cancelledJobIds, orphanedJobIds } when the retirement fenced in-flight work. A forced retirement (force: true) is the case worth reviewing: orphanedJobIds lists jobs whose real-world effect is unknown because the agent was removed mid-execution, the state described in Reconciling interrupted jobs.
  • CERTOPS_KEY_MATERIAL_REJECTED also fires on the agent routes, with { code: "PRIVATE_KEY_MATERIAL_REJECTED", method, routeFamily: "agent-protocol", agentId } and targetType: "certops_agent". An agent should never send key material, so this event on an agent route means either a misbuilt custom client or a tampered agent. It is written with no actor user, since the caller is a machine.

Approval gates

  • CERTOPS_JOB_APPROVAL_GRANTED metadata: { jobId, status, payloadHash, canonicalIntentHash }. The two hashes are what the approval is bound to: if the job payload is edited afterwards the hashes no longer match and the approval is invalidated, rather than silently covering the new intent. The actor is the approver, who cannot be the requester.
  • CERTOPS_JOB_APPROVAL_REJECTED metadata: { jobId, status }.

See Approval gates for the rules these events record.

Kill switch

  • CERTOPS_WORKSPACE_PAUSED / CERTOPS_WORKSPACE_RESUMED metadata: { workspaceId, previousCertOpsPaused, certOpsPaused, certOpsEnabled, certOpsActive, reason }. reason is operator-supplied free text. Pausing blocks new jobs and dispatch, but deciding a pending approval still works, so an approval event may legitimately appear while a workspace is paused.

Kubernetes controller

  • CERTOPS_CONTROLLER_OBSERVATION_ACCEPTED metadata: { apiTokenId, clusterId, managedCertificateId, observationId, resourceRecreated, targetId, certificateInstanceId }. Emitted for each accepted cert-manager observation. resourceRecreated is true when the cluster resource was deleted and recreated under the same identity, a legitimate but notable cluster-side change.
  • CERTOPS_CONTROLLER_PROVISION_INTENT_CREATED metadata: { clusterId, jobId, managedCertificateId, targetId }. Emitted when a provisioning intent is authorized, before the controller mutates anything in the cluster. Provisioning is re-authorized before every mutation, so this records intent, not completion.
  • CERTOPS_GENERIC_SECRET_REDACTION_APPLIED is also emitted against targetType: "certops_controller_observation" when an observation's free-text fields were redacted.
Signing-key rotation is not tenant-visible

The signing key belongs to the deployment rather than to any workspace, so these events carry no workspace and do not appear in workspace or personal audit views. On TokenTimer Cloud, rotation is a platform operation performed by TokenTimer.

  • CERTOPS_SIGNING_KEY_ROTATION_STARTED metadata: { signing_key_id, supersedes_signing_key_id, source }.
  • CERTOPS_SIGNING_KEY_ROTATION_COMPLETED metadata: { retired_signing_key_id, active_signing_key_id, forced, force_reason, active_agents, ack_count, source }. A forced: true completion retired the old key before every agent acknowledged the new one, and force_reason records the operator's stated justification.
Known gap

CertOps machine API token creation and revocation (POST .../certops/tokens and POST .../certops/tokens/:tokenId/revoke) do not write CERTOPS_API_TOKEN_CREATED / CERTOPS_API_TOKEN_REVOKED audit events on TokenTimer Cloud, though TokenTimer Self-hosted does record both. This is a tracked gap, not intended behavior. Until it is closed, reconstruct machine-token history from the CertOps API tokens panel, which shows each token's prefix, scopes, status, and creation and revocation timestamps. Revoking a token that was also being monitored as an SSL token still records a TOKEN_DELETED event for that side effect.

Agent bootstrap tokens are recorded separately, via CERTOPS_AGENT_BOOTSTRAP_TOKEN_CREATED and _REVOKED above.

Domain Checker

Emitted when a workspace member discovers publicly known subdomains for a root domain using passive discovery (subfinder), or imports selected hostnames into the workspace as SSL tokens. Lookup is rate limited per workspace and user. On TokenTimer Cloud, the Domain Checker is available on Pro and Team plans (API error PLAN_FEATURE_REQUIRED otherwise); TokenTimer Self-hosted has no subscription gate and uses the domain.manage permission instead.

  • DOMAIN_CHECKER_LOOKUP metadata: { domain, source, results, partial, tools_succeeded, tools_failed, truncated }. source is subfinder. partial is true when only some discovery tools completed. tools_failed lists tool names that timed out or errored.
  • DOMAIN_CHECKER_IMPORT metadata: { domain, source, submitted, imported, skipped, skipped_duplicate, skipped_invalid, skipped_unreachable, skipped_other_invalid, create_monitors, monitors_created, monitors_existing }. When create_monitors is true the event also includes { monitor_check_interval, monitor_health_check_enabled, monitor_alert_after_failures, monitor_contact_group_id }. submitted is the number of certificates selected, imported counts newly created SSL tokens, skipped_unreachable counts DNS failures, skipped_other_invalid is invalid skips excluding DNS cases, and skipped_duplicate / skipped_invalid are aggregate skip counts.