Skip to main content

Security Events

The Security Events page is an append-only log of authentication, identity, credential, and policy-change events. It is the primary source of SOC 2 evidence for change management and access control and is read-only; events cannot be edited or deleted from the UI.

Access​

The page requires the View Audit Logs permission. This is granted to the Admin role by default. Find it on the Security Events tab of the Audit page (/audit/security-events), next to Change History.

What is logged​

Tagnet writes a security event in the following situations. Events are grouped by category below.

Authentication events​

Event TypeWhen it fires
UserLoginSucceededA user successfully signed in. Details include the auth scheme (cookie or jwt). Actor is the authenticated user.
UserLoginFailedA sign-in attempt failed. Details include the failure reason (bad_password, account_disabled, account_locked, or user_not_found) and the attempted email. The attempted password is never logged. See the AuthAudit policy note regarding user_not_found events.
UserLogoutA user signed out. Details include the auth scheme and, for an API revoke-all, the number of refresh tokens revoked.
UserAccountLockedA user account was locked out because the failed sign-in threshold was exceeded. Actor type is System; Identity performs the lockout automatically, not a human. Details include the user id, email, and lockout expiry timestamp.
UserAccountUnlockedA locked account was manually unlocked by an administrator from the Users page. Actor is the admin. Details include the target user id and email.

Account lifecycle events​

Event TypeWhen it fires
UserCreatedA new user account was created, either by an admin directly or when an invited user accepted their invitation. Actor is always the admin who initiated the creation; for invitation-sourced accounts, this is the inviting admin recorded on the invitation, not the new user. Details include the new user id, email, assigned roles, and source (admin or invitation).
UserDeactivatedA user account was deactivated. Inactive users cannot sign in. Actor is the admin.
UserReactivatedA previously deactivated account was reactivated. Actor is the admin.
UserInvitedAn administrator created an invitation for a new user. Details include the invitation id, target email (if specified), role, and assigned access scope ids. The plaintext invitation token is never logged.
UserInvitationAcceptedAn invitee completed the accept-invite flow and a user account was created. Actor is the new user. Details include the invitation id and the new user id.

Credential events​

Event TypeWhen it fires
UserPasswordChangedA user changed their own password using the in-app self-service change-password flow. Actor is the user.
UserPasswordResetByAdminAn administrator reset another user's password from the Users page. Actor is the admin. Details include the target user id and email. The password itself is never logged. Distinct from UserPasswordReset, which covers the Recover Account out-of-band path.
UserPasswordResetA user's password was reset from the Recover Account page in the Tagnet Admin Console. Actor type is AdminTool; the actor field contains the Windows username of the person who ran the recovery. Details include the user's email, username, and the number of active sessions revoked.
UserPasswordResetRequestedA user submitted their email through the self-service Forgot Password form and the email matched an existing active account. A reset link was dispatched by email. Actor is the resolved user. Details include the user id and email. Note: this event is only emitted when the email resolves to a real active account; anonymous misses are silently no-oped and not logged. The reset token itself is never logged.
UserPasswordResetCompletedA user successfully redeemed a self-service password reset link and set a new password. Actor is the user. Distinct from UserPasswordChanged (which requires the current password). Details include the user id and email. The new password is never logged.
UserApiKeyCreatedA new API key was created (including via regenerate, in which case the source field in Details will be regenerate). Details include the key id, name, role, key prefix, and expiry. The raw key material is never logged.
UserApiKeyUpdatedAn API key's role, access scopes, or expiry was changed via the edit flow. Details carry {old, new} blocks for each field that actually changed. Name-only edits do not emit this event; only security-relevant changes are recorded.
UserApiKeyEnabledAn API key was re-enabled (toggled from inactive to active). Actor is the admin.
UserApiKeyDisabledAn API key was disabled (toggled from active to inactive). Disabling is reversible; the key can be re-enabled later. This is distinct from UserApiKeyRevoked, which is a permanent, terminal action. Actor is the admin.
UserApiKeyRevokedAn API key was permanently revoked. Unlike disabling, revocation cannot be undone. Details include the key id, name, and revocation reason (if provided). Actor is the admin.
UserApiKeyLockedA previously-disabled (inactive, revoked, or expired) API key was presented 25 consecutive times, so Tagnet locks the key for 15 minutes to stop the holder from probing for state changes. Random brute-force guesses against unknown keys do not increment this counter and do not trigger this event. Actor type is System. Details include the key id, name, failed-attempt count, and lockout expiry timestamp.
UserApiKeyUnlockedA locked-out API key was manually unlocked by an administrator before the 15-minute window expired. Details include the key id, name, and the prior lockout-end timestamp. Mirrors UserAccountUnlocked for user accounts.

Authorization events​

Event TypeWhen it fires
UserRoleAssignedA role was assigned to a user. Actor is the admin. Details include the target user id, email, and role name.
UserRoleRemovedA role was removed from a user. Actor is the admin. Details include the target user id, email, and role name.
UserAccessScopeAssignedAn access scope was assigned to a user. Actor is the admin. Details include the target user id, email, and the scope id and name.
UserAccessScopeRemovedAn access scope assignment was removed from a user. Actor is the admin. Details include the target user id, email, and the scope id and name.
AccessScopeCodeChangedAn access scope's Code was changed, including the system scope's. Because external API clients reference scopes by Code, a rename is a security-relevant configuration change: clients configured with the old Code stop resolving the scope. Actor is the admin. Details include the scope id, scope name, old Code, and new Code.
SystemScopeRecordsMovedEvery operational record left in the system scope (devices, device groups, locations, inventory, floor plans, pending mappings, commission batches) was moved to a site scope with the Move to a site action on the Access Scopes page. Actor is the admin. Details include the target scope id and name and how many records of each kind moved.

Device and credential events​

Event TypeWhen it fires
CredentialCreatedA new device credential is created.
CredentialRotatedAn existing device credential's password is changed.
CredentialViewedA device credential's plaintext password is revealed in the UI.
CredentialDecryptFailedA stored credential could not be decrypted at runtime (auto-flagged for rotation).
CredentialDeletedA device credential is deleted.
DeviceDeletedA device is deleted (alongside per-credential CredentialDeleted events). Also recorded in Change History.
ReaderFactoryResetA Zebra FX reader is reset to factory defaults from Tagnet, which also resets its admin username and password to the factory defaults. Logged at Warning. Recorded whether the reset succeeded or failed, because a failed reset may have partly reset the reader. Actor is the user who ran it. Details include the reader name, model, and IP address, plus the step that failed, or the error message when the reset stopped on an error.
ReaderDebugBundleCollectedAn administrator collected a debug bundle from a reader. Recorded whether the collection succeeded or failed. Actor is the administrator. Details include the reader name, id, and model, the status of each item collected (collected, none, not-supported, or failed, with the HTTP status code where there is one), and the error message when the collection failed. The bundle contents are never recorded.

Device activation, deactivation, and event delivery changes now appear in Change History instead of Security Events. Older DeviceActivated, DeviceDeactivated, and DeviceEventDeliveryChanged entries remain here; Tagnet no longer writes new ones.

Connection profile events​

Event TypeWhen it fires
ConnectionTokenRevealedAn administrator revealed a cached token on a connection profile's detail page for troubleshooting. Actor is the admin. Details include the profile name. The token itself is never logged.
ConnectionTokenAcquireFailedToken acquisition from a connection profile's token endpoint failed (bad credentials, unreachable endpoint, malformed response, and similar). Actor type is System. Details include the failure reason. Never includes credentials or token material.
ConnectionProfileSecretsDecryptFailedA connection profile's stored secrets could not be decrypted at runtime, most often after an encryption key rotation (auto-flagged for rotation). Logged at Critical. Actor type is System. Fires once, on the transition into the flagged state, not on every failed attempt afterward. Details include the profile name. Never includes credentials.
ConnectionProfileDeletedA connection profile was deleted. Because the profile row is removed entirely, this event is the surviving record of the deletion. Actor is the admin who deleted it. Details include the profile name and authentication mode. Never includes credentials.

Outbound delivery events​

Event TypeWhen it fires
IntegrationDeliveryRequeuedAn administrator sent a failed or dead-lettered delivery to an external system again, from the Integration Outbox page. A bulk requeue records one event for the batch, not one per delivery, with the filter it ran against and how many moved. Details name the target host, never the stored request: no full URL, no request body, no header values. A bulk requeue also echoes the filter the administrator typed, including any URL search text, trimmed to 60 characters.
IntegrationDeliveryDeadLetteredAn administrator used Stop retrying on a delivery that was still waiting to retry, moving it to dead-lettered, so the external system will not receive it unless it is requeued later. Logged at Warning. Details include the delivery ID, the target host, and the stated reason.
IntegrationDeliveryAbandonedAn administrator abandoned a failed or dead-lettered delivery from the Integration Outbox: it will not be resent and no longer counts as needing attention. Logged at Warning. Details include the delivery ID, the target host, and the reason the administrator gave. A bulk abandon records one event for the batch, with the filter it ran against, how many moved, and the reason.

Viewing deliveries is deliberately not recorded. Both events above outlive the delivery itself: the outbox row is eventually purged by retention, and these remain.

Integration testing events​

Event TypeWhen it fires
IntegrationTestSentWithRealDataAn admin ran a test send on an integration endpoint using real inventory data rather than synthetic sample values. Logged at Warning with Outcome=Initiated, written before the request is attempted because the payload leaves the network whether or not the target accepts it. Actor is the admin who ran the test. Details include the target URL and the device and inventory item ids the payload was built from. A test run against sample data emits no event.

Alert events​

Event TypeWhen it fires
AlertAcknowledgedA user acknowledged an operational alert, claiming ownership of the problem. Actor is the acknowledging user. Details include the alert id and its alert type.
AlertResolvedAn operational alert was resolved. Fired both when a user closes an alert by hand (actor is the user) and when the underlying condition clears on its own (actor type System). Manual resolution silences an operational signal, so the record of who closed it outlives the alert. Details include the alert (or its condition identity, for automatic resolution) and its alert type.
NotificationGroupChangedA notification group was created, updated, or deleted. Group membership decides who hears about operational problems, so changes to it are security-relevant. Actor is the admin. Details include the group name, the action, and the member count, never a full list of member email addresses.
AlertRoutingRuleChangedAn alert routing rule was created, updated, enabled or disabled, or deleted. Disabling a rule silences alert delivery for everything it matched, so the record of who changed routing must outlive the rule. Actor is the admin. Details include the rule name, the action, and a summary of its alert-type selectors.

Policy and system events​

Event TypeWhen it fires
PolicyChangedA configuration policy is created, updated, enabled, or disabled. The Details field contains old/new configuration JSON.
KeyRingRotationThe data-protection key ring is rotated (initiated and completed).
ServiceAccountChangedThe Windows account the Tagnet service logs on as was changed, or its stored password was updated, from the Service Account page in the Tagnet Admin Console. Logged at Warning; Outcome is Succeeded when the service came back up under the new account and Failed otherwise (including a rollback). Actor type is AdminTool; the actor field is the Windows username of the person who ran the console. Target type is WindowsService. Details include the action (AccountChanged or PasswordUpdated), the previous and new account names, and a summary of what happened. Passwords are never logged. The same record is appended to logs\admin-console.log under the Tagnet data folder, which is where to look when the database was unreachable at the time.
LicenseImportedA license file is successfully applied. Details include customer id, customer name, expiry, and trial flag.
LicenseImportRejectedA license file is rejected during validation. Details include the error code and a description of the failure.
LicenseCapExceededA device create or reactivation attempt was blocked because it would have exceeded the active license's cap for that device type. Emitted with Outcome=Denied.
LicenseTrialExpiredThe trial license passed its expiry and the license gate transitioned to Locked.
OperationDeniedByLicenseGateAn HTTP request was denied because the license gate is Locked. Deduplicated per actor and request path within a lock session to prevent bot traffic from flooding the log.

This list grows as new privileged operations are added to Tagnet. Events that are not security-relevant (operational data edits like renaming a location) live in a separate audit log.

Account lockout and unlock flow​

When a user enters the wrong password repeatedly, ASP.NET Core Identity locks the account automatically after five failed attempts (the default threshold). Tagnet records this sequence in the audit log so you can reconstruct exactly what happened:

  1. Attempts 1–4 each fire a UserLoginFailed event with reason bad_password.
  2. On the fifth wrong attempt, two events fire in sequence: UserLoginFailed(bad_password) (the triggering attempt) and UserAccountLocked (the lockout itself). The lockout event uses actor type System because Identity performs the lock; no human is the actor.
  3. Subsequent attempts against the locked account fire UserLoginFailed with reason account_locked.
  4. When an admin unlocks the account from the Users page, a UserAccountUnlocked event fires with the admin as actor.

Natural lockout expiry (the account unlocks automatically after the lockout window passes) does not emit a UserAccountUnlocked event; only admin-initiated unlocks do.

AuthAudit policy​

The Security > AuthAudit policy controls whether UserLoginFailed events with reason user_not_found are written to the audit log. This reason fires when someone attempts to sign in with an email address that does not exist in the system.

  • Enabled (default): All failed sign-in reasons are logged, including user_not_found. This gives you complete visibility into credential-stuffing and reconnaissance attempts.
  • Disabled: user_not_found events are suppressed. The other failure reasons (bad_password, account_disabled, account_locked) always fire regardless of this setting because they involve a known user account.

When to disable: On internet-exposed hosted deployments, bot traffic can generate thousands of user_not_found events per day using attacker-controlled email strings. If this noise obscures legitimate audit signals, disable the policy. On on-premises deployments with a controlled login surface, leave it enabled; the user_not_found events are useful signal.

Configure this policy on the Policies page under the Security category. See Policies for details on enabling and disabling policies.

What is not yet logged​

The following event types are planned but not yet implemented:

  • MFA events: Tagnet does not yet have multi-factor authentication. MFA-related events will be added under the Enterprise Sign-In feature.
  • Refresh token lifecycle events: Deferred until a session-management UI exists.
  • User hard-delete events: Tagnet only supports deactivation today; hard delete is not available.
  • Operational data audit: Changes to inventory items, locations, and other non-security configuration not yet covered by Change History are planned for that log over time.
  • Connection profile create and edit events: Creating or editing a connection profile is not yet logged as a security event (the profile row itself records who created and last updated it); deletions, token reveals, acquisition failures, and secret decrypt failures are captured today.

Filtering and pagination​

Use the filter bar to narrow results by:

  • Performed by: pick a specific user to see only events that user performed
  • Event: select one or more event types from the dropdown
  • Severity (Info, Warning, Critical)
  • Outcome (Initiated, Succeeded, Failed, Denied)
  • Search: free-text search across the event, the entity, its id, and who performed it, using the names as the page shows them ("login failed", "API key", a user's name or email) or the stored values ("system", an API key id, etc.)
  • Date: from and to, in your local time

Active filters appear as chips above the grid; close a chip to clear that filter, or click Clear All to reset. Use the Refresh button in the page header to reload the grid and re-check the empty state without losing your current filter selections.

Event detail​

Click any row to open the event's own page at a stable, shareable URL. If a linked event id no longer resolves, for example because retention has since removed it, the page shows a friendly "not found, may have been removed by retention" message rather than an error. The page shows:

  • When it happened (in your local time) and the event
  • The entity and its id (e.g., Policy / Retention/TagRead, User / user@example.com)
  • Outcome and severity
  • Who performed it, and the actor type
  • IP address and correlation id (when present)
  • The full Details JSON, pretty-printed

Retention​

Security events are kept for 365 days by default, from when the event happened, and are then deleted by the Retention background job. Before this policy existed, nothing ever purged security events; the log grew forever. On an install that already had security events when this policy first arrived, the window seeds at the maximum, 3650 days, so the upgrade does not delete any pre-existing history; an administrator can shorten it afterward. A fresh install seeds at the 365-day default.

The window is configured on the Retention / Audit policy; see Audit retention. Shortening the window permanently deletes older events on the next retention run, so lower it deliberately, not by accident. If a linked event id no longer resolves because retention has since removed it, its page shows a friendly "not found, may have been removed by retention" message rather than an error.

SOC 2 use​

For most audit reviews you will filter by event type and date range, then export findings out-of-band (e.g., screenshot or copy/paste from the event's detail page, or share its URL directly with an auditor). The store is append-only, so an auditor's question "show me every policy change last quarter" or "show me every failed login for this user" is answered directly without trusting that the log was not tampered with.

A future release will add structured export. If your compliance obligation requires keeping security events longer than the default, raise the Security event retention (days) setting on the Retention / Audit policy; see Audit retention.