Platform
Audit logs
Authalla keeps one activity log for your whole account: every sign-in, every failed sign-in, every change your team makes to your configuration, and SCIM provisioning. Audit logs are included in every plan.
Reading the log
Open Activity in the dashboard sidebar. The log is newest first. Use Load more at the bottom to go further back, up to the end of the retention period.
Filter it by:
- Category: Sign-ins, Team or Integrations.
- Tenant and App.
- Outcome: succeeded, failed sign-ins, cancelled, or App error. Failed sign-ins lists every sign-in with a refused attempt, including one where the user got in on a later try. The others go by how the sign-in ended.
Links from Home can also narrow the log to one email address, such as the failed sign-ins for an address someone keeps trying, or to an app's App errors. They read as a sentence above the log, with a button that removes them.
The filters are part of the page's address, so you can bookmark a filtered log or send it to someone on your team. To see one user's activity, open the user and select See activity on their Sign-ins tab. That includes the changes your team made to the user, such as a suspension or signing them out everywhere.
Each row shows when it happened as relative time ("5 minutes ago"). Hover over it for the exact date and time. Hover over an event badge for a one-line explanation of the event.
What is recorded
The log has three categories.
- Sign-ins: sign-ins, failed sign-ins, sign-outs, sessions a user ended, connected apps a user revoked, users signed out everywhere, and App errors.
- Team: every change to your configuration made in the dashboard, through the Management API or by an agent over the MCP server, dashboard sign-ins and sign-outs, and impersonation.
- Integrations: users and groups created, updated and removed over SCIM.
Token refreshes aren't listed. An app renews its tokens in the background all the time, and a refresh isn't a sign-in.
A sign-in, step by step
One sign-in is one row. The row shows whether it succeeded, how the user signed in, the app, the tenant, the user, the IP address, and the browser and operating system. Open the row to see its steps:
- Sign-in: the user proved who they are, with a code, a link, a passkey or an identity provider, and a session began. A new user's first sign-in looks the same.
- Code issued: Authalla handed the app a one-time code. The app must exchange it for tokens within a few minutes.
- Tokens issued: the app exchanged its code for tokens. The user is now signed in to the app.
If a Sign-in hook ran, the row also shows one line for each call. A successful call shows the claims it added and how long it took, for example "Sign-in hook: added roles, plan · 120 ms". A failed call says how it failed and what the sign-in did next, for example "Sign-in hook: timed out, sign-in continued". Whether a failed call refuses the sign-in is a setting on the hook. See the call opens it on the hook's Calls tab, with the error, the fields your endpoint returned and the claims it added.
If the user got a code wrong and then right, both attempts are steps of the same sign-in, and the row shows it succeeded. It doesn't hide the wrong code: the badge turns amber and the row says "1 failed attempt before signing in · wrong or expired code", or with more tries, "5 failed attempts before signing in · last: wrong or expired code". Each refused attempt is a failed sign-in, counted on Home and listed under the Failed sign-ins outcome, because repeated tries are what a guessing attack, or a sign-in page that confuses people, looks like.
If the user signed in but your app then got a step wrong and never received its tokens, for example because it sent a redirect URI it hasn't registered, the row shows the App error instead: the user never reached your app. An App error after the app got its tokens, such as a code used a second time or a refresh token reused days later, is one more step of a sign-in that succeeded, and so is an App error the app recovered from within the sign-in. Such a row keeps its amber badge and names the error without being opened, for example "App error: redirect URI not registered". A sign-in Authalla refused, or the user cancelled, stays failed or cancelled whatever the app did afterwards.
The IP address and browser belong to the person signing in. The Tokens issued step is a request from your app's backend, not from the user's browser.
Sign-in methods
- PIN code and Magic link: a one-time code or link sent by email.
- Passkey: the user's device or password manager vouched for them.
- Google, GitHub, Microsoft and other social connections: the user signed in with an account they already have.
- Okta (OIDC), Microsoft Entra (OIDC), Azure AD (SAML) and other enterprise connections: the user's company identity provider vouched for them.
- Impersonation: a member of your team acted as the user. This is Team activity, not a sign-in.
Failed sign-ins
A failed sign-in is one Authalla refused. It records the reason, the tenant, the app and user when known, the email address that was typed, and the IP address. The email is kept even when no user has it, because a burst of failures for addresses that don't exist is what a password-spraying attack looks like.
Only failures during a sign-in are recorded: one that started when your app sent the user to Authalla. A request that belongs to no sign-in, such as a made-up magic link or a sign-in provider callback nobody started, can be sent by anyone as often as they like, so it isn't counted. SAML is the one exception: the identity provider posts its answer without the browser's session, so a SAML failure is recorded when the provider's signed answer names the user.
| Reason | What it means |
|---|---|
| No such user | No user in the tenant has the email address that was typed. |
| User suspended or deactivated | The user exists but may not sign in. |
| Sign-up is closed | The sign-in would have created a new user, and the tenant doesn't allow sign-ups. |
| Wrong or expired code | The emailed code was wrong or had run out. |
| Code expired | The code sent to confirm an email address ran out before it was entered. |
| Too many wrong codes | The code was entered wrong too many times, so it no longer works. |
| Link expired or already used | The magic link was old, already used, or never existed. |
| Passkey rejected | The passkey's answer didn't verify. |
| Identity provider error | The identity provider returned an error, or an answer Authalla couldn't use. |
| Cancelled at the identity provider | The user backed out at the identity provider. This is usually harmless. |
| Finished in a different browser | The sign-in came back from the identity provider to a different browser, or after the browser session had expired. |
| Connection turned off | The connection was turned off while the user was signing in. |
| Email domain not allowed | The enterprise identity provider answered for an email outside the connection's domains. |
| Sent to single sign-on | The email is on an organization's domains and its connection is on, so it can only sign in through that connection. The user was sent there instead. |
| Refused after the Sign-in hook failed | The Sign-in hook failed, and the hook is set to refuse sign-ins when it fails. |
App errors
An App error is your app getting a step of the sign-in wrong. The user did nothing wrong, so it isn't counted as a failed sign-in. It usually means a bug or a misconfiguration in the app.
| Reason | What it means |
|---|---|
| Code expired | The app exchanged its code too late. |
| Code already used | The app exchanged the same code twice. |
| Redirect URI doesn't match | The app exchanged a code with a different redirect URI from the one it signed in with. |
| PKCE check failed | The app's code verifier was missing or didn't match the code's challenge. |
| Refresh token reused | A refresh token was used again after it had been exchanged for a new one, while the new one was still live. Authalla revokes every token from that sign-in, in case the token was stolen. |
| Wrong app credentials | The app's client ID or secret was wrong. |
| Redirect URI not registered | The app asked to return to a redirect URI that isn't on its list. Activity shows the URI it sent. |
| Unknown resource | The app asked for a token for a resource server the tenant doesn't have, or one other than its code was for. |
At the token endpoint, only a request about a code or refresh token Authalla issued is recorded, under the sign-in it came from. A made-up code, a revoked refresh token, or a wrong secret on its own could come from anyone who knows your app's client ID, so those aren't recorded. A refresh token that stopped working because the user signed out everywhere or revoked the app isn't an App error either.
Adding a missing redirect URI
When an app sends a redirect URI it hasn't registered, Activity shows the URI after the reason, and offers Add redirect URI while the fix still applies: the app still exists, it doesn't accept that URI yet, and the URI is one Authalla accepts as a redirect URI (https, or http on localhost, 127.0.0.1 or [::1]). Nothing changes until you confirm. The change is saved as an ordinary edit of the app, so it shows in Activity as your team's change.
Anyone who knows your app's client ID can start a sign-in with any redirect URI, so this error can be made on purpose. When the URI's address (scheme, host and port) is new to the app, the confirmation says so. Add it only if you recognise it as your app's. A redirect URI you don't recognise is a reason to look at who is signing in, not to add it.
Other events
- Sign-out: the user signed out.
- Session ended: the user signed out of one of their browsers from inside your product, through the User API.
- Connected app revoked: the user took an app's access away from inside your product. The row names the app.
- Signed out everywhere: every browser session of the user ended and every connected app lost its access. The row says whether the user was also suspended. See Revoke access.
- Token revoked: an app told Authalla it was done with its token, and everything issued from that sign-in stopped working.
- Refresh blocked: an app tried to renew a token for a suspended or deactivated user and was refused. The row names the user's status.
- Tokens issued on a row of its own: an app got a token with its own credentials (the client credentials grant), with no user involved.
Team activity
Every change to your configuration is recorded, whether it was made in the dashboard, through the Management API with an Account API key, or by an agent over the MCP server. Each entry reads as a sentence that names who made the change: "Anna updated app Billing", "Key ci-deploy created app Docs", "Anna created user ada@example.com via MCP". A change made over MCP names the team member who connected the agent, or the Account API key it used. Names are looked up when you read the log, so a renamed app shows its new name, and a deleted record shows the name it had when it was deleted.
Changes your customer's IT admin makes in the setup portal are recorded too. The portal doesn't know who the IT admin is, so the entry names the Organization's setup link: "Setup link of Organization Globex created SAML Connection Globex Entra". A test sign-in is recorded when it starts and again when it ends, with its outcome, in the name of whoever started it: "Setup link of Organization Globex finished a test sign-in through SAML Connection Globex Entra: it passed and turned the Connection on".
Turning a connection on or off says so: "Anna turned on SAML Connection Globex Entra without a test sign-in", "Anna turned off …". When the same save changed other settings too, the entry says "updated … and turned it off", and opening it shows what else changed.
Looking at your configuration isn't recorded, and neither are failed changes.
An update also says what it changed. Open the entry to see each field with its value before and after, or, for a list such as an app's redirect URIs, the items added and removed. An update that changed nothing says so. A secret, such as a connection's client secret or the Sign-in hook's secret, shows only that it changed: its value is never stored. Creating and deleting records name the record, not its fields. Very long values are cut short, and an entry keeps at most 50 changed fields.
What changed is read with the permissions of whoever made the change: an Account API key that can change a record but not read it records the change without its fields.
Some changes are marked Sensitive:
- impersonation started
- a user signed out everywhere
- a user updated or deleted (suspending a user is an update)
- an app secret created or set to expire
- a team member invited or removed, or the account's owner changed
- an Account API key created or revoked
- the Sign-in hook, or a connection, created, changed or deleted, in the dashboard or the setup portal
- a test sign-in that turned a connection on or made its pending changes live
Treat impersonation like privileged access. Every impersonation shows who on your team started it. A change Authalla staff make in your account names Authalla support, unless they are a member of your team; then it names them like any other member.
Retention
Activity is kept for a fixed time, then deleted automatically:
| What | Kept for |
|---|---|
| Sign-ins, failed sign-ins, App errors and other sign-in events | 90 days |
| Integrations (SCIM) | 90 days |
| Sign-in hook calls | 90 days |
| Team activity | 1 year |
Expired entries are removed within the hour. The 90-day limit is also what bounds the personal data the log holds about people who aren't your users, such as an email typed by mistake and its IP address.
What audit logs are not
They record sign-ins and changes to your Authalla configuration. They aren't a general-purpose audit trail for your application. Actions your own application takes, such as a user changing something inside your product, are yours to record. Authalla only sees the sign-in.