# How do I read the authentication audit?

- Link: https://www.agilicus.com/faq/read-authentication-audit/
- Published: 2026-10-15T16:47:19+00:00
- Author: Don Bowman

Authentication is the process a user, or a machine, follows to prove an identity.
Agilicus records every step of that process in the authentication audit. Each step
writes a separate record, and every record in one attempt shares the same `request_id`.
To reconstruct an attempt, collect all records with that `request_id` and read them
in time order: the earliest record starts the flow and the newest record is its 
terminal state.

## What is the typical flow for an authentication request?

There are two classes of authentication:

 * **End user**: a person signing in through a browser or an application.
 * **Service account**: a machine identity, such as a connector, that authenticates
   with an authentication document.

An end-user sign-in moves through a series of stages. Not every flow runs every 
stage: the path depends on your authentication rules and on whether the user already
holds a valid session.

### Stages

| Stage | Meaning | 
| `Authentication Request` | A step in an OpenID Connect sign-in. The authorisation request and the code exchange both appear in this stage. | 
| `Identity Provider Authentication` | The user is authenticating with an upstream identity provider. | 
| `Identity Provider Callback` | The identity provider has returned the user to Agilicus with a result. | 
| `Whoami` | Agilicus maps the upstream user to a user in your organisation, and refreshes group membership and profile details. | 
| `Policy Evaluation` | Agilicus applies your authentication rules to decide what happens next. | 
| `Token` | Agilicus issues an access token for its resources. | 
| `MFA Challenge` | Agilicus asks the user to answer a second factor. | 
| `MFA Enrollment` | A user is enrolling a second factor. | 
| `Assertion Request` | A service account authenticates with an authentication document. | 
| `Refresh` | A client exchanges a refresh token for new credentials. | 
| `Revoke` | A token or a session is being revoked. |

Older exports label these columns `stage` and `event`. The current API names them`
event_name` and `result`. Each record also carries a result, and the result of the
newest record in a `request_id` group is the terminal state of the attempt.

### Example: end-user sign-in with a second factor

| Stage | Result | 
| `Authentication Request` | `InProgress` | 
| `Policy Evaluation` | `Authenticate` | 
| `Identity Provider Authentication` | `InProgress` | 
| `Identity Provider Authentication` | `Success` | 
| `Identity Provider Callback` | `Success` | 
| `Policy Evaluation` | `DoMfa` | 
| `Policy Evaluation` | `Success` | 
| `Token` | `Create` | 
| `MFA Challenge` | `InProgress` | 
| `MFA Challenge` | `Success` | 
| `Authentication Request` | `CodeIssued` | 
| `Token` | `Create` | 
| `Authentication Request` | `Success` |

    ```wp-block-agilicus-mermaid
    %%{init: {"theme": "base", "themeVariables": {"background": "#ffffff", "primaryColor": "#e8f1fb", "primaryBorderColor": "#1f4e79", "primaryTextColor": "#111111", "lineColor": "#4a4a4a", "secondaryColor": "#f5f5f5", "fontFamily": "Inter, sans-serif"}} }%%
    sequenceDiagram
        autonumber
        participant U as User
        participant C as Client
        participant A as Agilicus
        participant I as Identity provider
        U->>C: Start sign-in
        C->>A: Authentication Request, InProgress
        A->>A: Policy Evaluation, Authenticate
        A->>I: Identity Provider Authentication, InProgress
        I-->>A: Identity Provider Callback, Success
        A->>A: Policy Evaluation, DoMfa then Success
        A->>C: MFA Challenge, InProgress
        U->>C: Answer the second factor
        C->>A: MFA Challenge, Success
        A-->>C: Authentication Request, CodeIssued
        C->>A: Exchange the code for tokens, Token Create
        A-->>C: Authentication Request, Success
    ```

### Example: end-user sign-in with a saved session

| Stage | Result | 
| `Authentication Request` | `InProgress` | 
| `Whoami` | `UpstreamUserIDUpdated` | 
| `Policy Evaluation` | `AllowLogin` | 
| `Policy Evaluation` | `Success` | 
| `Authentication Request` | `CodeIssued` | 
| `Token` | `Create` | 
| `Authentication Request` | `Success` |

    ```wp-block-agilicus-mermaid
    %%{init: {"theme": "base", "themeVariables": {"background": "#ffffff", "primaryColor": "#e8f1fb", "primaryBorderColor": "#1f4e79", "primaryTextColor": "#111111", "lineColor": "#4a4a4a", "secondaryColor": "#f5f5f5", "fontFamily": "Inter, sans-serif"}} }%%
    sequenceDiagram
        autonumber
        participant U as User
        participant C as Client
        participant A as Agilicus
        U->>C: Start sign-in
        C->>A: Authentication Request, InProgress
        A->>A: Whoami, UpstreamUserIDUpdated
        A->>A: Policy Evaluation, AllowLogin then Success
        A-->>C: Authentication Request, CodeIssued
        C->>A: Exchange the code for tokens, Token Create
        A-->>C: Authentication Request, Success
    ```

### Example: refresh

| Stage | Result | 
| `Refresh` | `InProgress` | 
| `Policy Evaluation` | `AllowLogin` | 
| `Policy Evaluation` | `Success` | 
| `Refresh` | `Success` |

    ```wp-block-agilicus-mermaid
    %%{init: {"theme": "base", "themeVariables": {"background": "#ffffff", "primaryColor": "#e8f1fb", "primaryBorderColor": "#1f4e79", "primaryTextColor": "#111111", "lineColor": "#4a4a4a", "secondaryColor": "#f5f5f5", "fontFamily": "Inter, sans-serif"}} }%%
    sequenceDiagram
        autonumber
        participant C as Client
        participant A as Agilicus
        C->>A: Refresh, InProgress
        A->>A: Policy Evaluation, AllowLogin then Success
        A-->>C: Refresh, Success
        Note over A,C: A failed refresh writes Refresh, Failure instead.
    ```

### Example: service account

| Stage | Result | 
| `Assertion Request` | `InProgress` | 
| `Assertion Request` | `Success` |

    ```wp-block-agilicus-mermaid
    %%{init: {"theme": "base", "themeVariables": {"background": "#ffffff", "primaryColor": "#e8f1fb", "primaryBorderColor": "#1f4e79", "primaryTextColor": "#111111", "lineColor": "#4a4a4a", "secondaryColor": "#f5f5f5", "fontFamily": "Inter, sans-serif"}} }%%
    sequenceDiagram
        autonumber
        participant K as Connector
        participant A as Agilicus
        K->>A: Assertion Request, InProgress
        A->>A: Validate the authentication document
        A-->>K: Assertion Request, Success
    ```

## How is a request classified as success or failure?

The service does not write a single record that announces the outcome of a flow.
It writes the first record as `InProgress`, and then appends a record for each step.
To classify an attempt, group the records by `request_id` and read the newest one:

    ```wp-block-agilicus-mermaid
    %%{init: {"theme": "base", "themeVariables": {"background": "#ffffff", "primaryColor": "#e8f1fb", "primaryBorderColor": "#1f4e79", "primaryTextColor": "#111111", "lineColor": "#4a4a4a", "secondaryColor": "#f5f5f5", "fontFamily": "Inter, sans-serif"}} }%%
    flowchart TD
        A["Collect the records for one request_id"] --> B["Sort them by time"]
        B --> C{"Result of the newest record"}
        C -->|"Authentication Request, Success"| D["Signed in"]
        C -->|"Refresh, Success"| E["Refresh completed"]
        C -->|"Assertion Request, Success"| F["Service account authenticated"]
        C -->|"InProgress"| G["Still running, or abandoned by the client"]
        C -->|"Failure, Denied, Timeout, SessionExpired"| H["Not signed in"]
    ```

 * `Authentication Request` with `Success`: the user is signed in.
 * `Refresh` with `Success`: the refresh completed.
 * `Assertion Request` with `Success`: the service account is authenticated.

A newest result of `InProgress` means the flow has not finished. A newest result
of `Failure`, `Denied`, `Timeout` or `SessionExpired` means it stopped without signing
the user in.

Some flows stop without a terminal record, because the client never calls the next
endpoint. This happens when a user closes the browser, when a network connection
drops, or when a web crawler follows the authorisation link. The service does not
write a synthetic failure for these abandoned flows, so treat a dangling flow as
an unsuccessful attempt.

The web interface applies the same rule. It groups the records by `request_id`, 
sorts each group from oldest to newest, takes the result of the newest record as
the outcome, and lists the groups newest first. You can reproduce that logic in 
a spreadsheet or a script when you review an export.

## Why does a flow end at CodeIssued without a Success?

`CodeIssued` means that Agilicus returned an authorisation code to the client and
is waiting for the client to exchange it for tokens. That exchange is what later
writes the `Authentication Request` with `Success` record. If the `Success` record
is missing, the client did not complete the exchange. Common causes are a closed
browser tab, a dropped network connection, and a web crawler that followed the authorisation
link and then stopped.

It is not a sign that a valid token already exists. A flow that reuses an existing
session takes a different path, and it still ends with `Authentication Request` 
and `Success`.

## What do the Policy Evaluation results mean?

Policy Evaluation is where your authentication rules decide what happens next. The
first `Policy Evaluation` record carries the decision, and a following `Policy Evaluation`
record with `Success` confirms that Agilicus stored the decision.

| Result | Meaning | 
| `AllowLogin` | Continue the sign-in without a second factor. | 
| `DontMfa` | Deprecated. Continue the sign-in without a second factor. Newer rules return `AllowLogin`. | 
| `DoMfa` | Challenge the user for a second factor. | 
| `Authenticate` | Send the user to an upstream identity provider to authenticate. | 
| `DenyLogin` | Do not allow the user to continue. Agilicus terminates the sign-in. |

Three further results can appear on the Policy Evaluation stage:

 * `Success`: the decision was evaluated and stored.
 * `Failure`: Agilicus could not evaluate the policy and aborted the sign-in. Report
   this to support if you see it.
 * `Denied`: written after a `DenyLogin` decision, when the sign-in is terminated.

## See also

 * [Authentication Audit](https://www.agilicus.com/anyx-guide/authentication-audit/)
 * [Authentication audit (admin interface)](https://www.agilicus.com/anyx-guide/agilicus-anyx-administrative-web-interface/organisation/authentication-audit/)
 * [Audit and diagnostics](https://www.agilicus.com/anyx-guide/agilicus-anyx-administrative-web-interface/concepts/audit-and-diagnostics/)
 * [Authentication rules](https://www.agilicus.com/anyx-guide/authentication-rules/)
 * [Diagnostic logs](https://www.agilicus.com/faq/diagnostic-logs/)
 * [API reference: authentication audits](https://www.agilicus.com/api/#get-/v1/auth_audits)
