person-setup-machine

How do I read the authentication audit?

How do I read the authentication audit?


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

StageMeaning
Authentication RequestA step in an OpenID Connect sign-in. The authorisation request and the code exchange both appear in this stage.
Identity Provider AuthenticationThe user is authenticating with an upstream identity provider.
Identity Provider CallbackThe identity provider has returned the user to Agilicus with a result.
WhoamiAgilicus maps the upstream user to a user in your organisation, and refreshes group membership and profile details.
Policy EvaluationAgilicus applies your authentication rules to decide what happens next.
TokenAgilicus issues an access token for its resources.
MFA ChallengeAgilicus asks the user to answer a second factor.
MFA EnrollmentA user is enrolling a second factor.
Assertion RequestA service account authenticates with an authentication document.
RefreshA client exchanges a refresh token for new credentials.
RevokeA 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

StageResult
Authentication RequestInProgress
Policy EvaluationAuthenticate
Identity Provider AuthenticationInProgress
Identity Provider AuthenticationSuccess
Identity Provider CallbackSuccess
Policy EvaluationDoMfa
Policy EvaluationSuccess
TokenCreate
MFA ChallengeInProgress
MFA ChallengeSuccess
Authentication RequestCodeIssued
TokenCreate
Authentication RequestSuccess
%%{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

StageResult
Authentication RequestInProgress
WhoamiUpstreamUserIDUpdated
Policy EvaluationAllowLogin
Policy EvaluationSuccess
Authentication RequestCodeIssued
TokenCreate
Authentication RequestSuccess
%%{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

StageResult
RefreshInProgress
Policy EvaluationAllowLogin
Policy EvaluationSuccess
RefreshSuccess
%%{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

StageResult
Assertion RequestInProgress
Assertion RequestSuccess
%%{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:

%%{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.

ResultMeaning
AllowLoginContinue the sign-in without a second factor.
DontMfaDeprecated. Continue the sign-in without a second factor. Newer rules return AllowLogin.
DoMfaChallenge the user for a second factor.
AuthenticateSend the user to an upstream identity provider to authenticate.
DenyLoginDo 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