
The server records who asked for what, which user authenticated, and what was released to whom, as audit events. It
does so with spring-audit-support: the server publishes ordinary Spring application events,
transformers turn them into structured audit events, and the repositories that spring-audit-support sets up from the
audit.* properties store them.
This page documents the audit events of the server, how one authentication flow is followed across requests and server instances, and how to change what an event holds. How spring-audit-support works, and how its repositories are configured, is described in its own documentation.
Source links in this guide point to the main branch of the
spring-authentication-server repository.
The starters include spring-audit-support and its auto-configuration, so the server produces audit events without any code. Two things are left to the application:
The application name. spring-audit-support puts the name of the application in every audit event and refuses to
start without one. Set spring.application.name, see
The application name is required.
Where the events go. Configure one or more repositories under audit.repository. Without any, the events are
kept in a bounded in-memory repository. See Configuration and
Repositories.
spring:
application:
name: my-idp
audit:
repository:
file:
log-file: /var/log/idp/audit.log
The server has no audit settings of its own.
Personal data. The audit events hold the attributes of the users, including identity numbers. Protect the audit repositories accordingly, and use
audit.repository.exclude-eventsor a replaced transformer if an event holds more than the deployment may keep.
Without Spring Boot, the AuthnServerConfigurer publishes the events to the application
context of the HttpSecurity object, or to the publisher given with eventPublisher(...). The transformers listed
under Changing what an event holds are then registered with spring-audit-support’s
AuditApplicationListener by the application.
Every event has the common structure of spring-audit-support, see The audit event: type,
timestamp, application, correlation_id, trace_id, principal and data. The server does not assign a trace
ID.
Every authentication event has, as the first object of its data, the requester
described below. Most also have an object with the protocol-specific part of the event, holding what is needed to match
the entry to the SAML or OpenID Connect messages. Its members depend on the protocol, so the tables of those objects
are given per protocol.
Audit data: requester
| Parameter | Description | Type |
|---|---|---|
protocol |
saml or oidc. Absent when the protocol is not known, which only happens for an unrecoverable error on a path that serves both protocols, such as a resume path without an authentication in progress. |
String |
id |
The SAML entityID of the Service Provider or the OpenID Connect client_id. Absent if the request names no requester. |
String |
organization_number |
The organisation number of the requester exactly as the client registry holds it, with no conversion. A SAML Service Provider has it in whatever form its metadata gives, and an OpenID Connect client as a GLUE URI, see The client registry. Absent if the requester is not known or has none. | String |
verified |
Whether the server has established that the request comes from this requester. See below. | Boolean |
Until the requester is verified, id is only what the request claims. The requester is verified:
redirect_uri is one it has
registered, and the request object, if any, has been checked,The Authentication Request Received event is always written before any check, so its requester is never verified.
The principal of an authentication event is always the requester: the id above. When the request names no
requester, such as a SAML request without an Issuer that could be read, the principal is unknown.
The operational events have spring-audit-support’s system principal, system.
All events of one authentication flow have the same correlation_id. The server generates it when an authentication
request arrives, for both protocols. The ID of the SAML AuthnRequest is not used; it is found in the
authn_request object.
A flow usually spans several requests: the authentication request, the pages of an authentication module, the return to the resume path, and for OpenID Connect the client’s calls to the token and UserInfo endpoints. The correlation ID follows the flow like this:
| Request | Where the correlation ID comes from |
|---|---|
| Authentication request | Generated. A new request always starts a new flow, also when single sign-on is used. |
| The pages of an authentication module | The authentication in progress, kept in the session, for a request on the module’s authentication path that carries the authnId parameter. |
| The resume path | The authentication in progress, kept in the session. |
| The token endpoint | The authorization code, which is bound to the flow. |
| The UserInfo endpoint | The access token, which is bound to the flow. |
Since the correlation ID is kept with the data of the flow, the session, the authorization codes and the access tokens, it is the same whichever server instance handles a request, also when that data is kept in Redis, see Running several nodes.
A request that cannot be tied to a flow gets a correlation ID of its own, for example a token request with an unknown code, or a request on the resume path without an authentication in progress.
The correlation ID is kept by spring-audit-support’s CorrelationIDHolder while the request is processed, and is
cleared when the request ends, whatever the outcome. See Correlation ID and Trace ID.
Events from authentication modules. An event that an authentication module publishes while the flow is in progress, from its provider or from its pages on the authentication path, is audited under the correlation ID of the flow without the module doing anything. spring-audit-support picks the ID up when the event is transformed.
The events are given in the order they occur in a flow. A SAML flow produces Authentication Request Received, Authentication Request Accepted, User Authenticated and Success Response. An OpenID Connect flow produces the same events, with an Authorization Response after the user authenticated, the Success Response when the client redeems the code, and UserInfo Delivered when the client calls the UserInfo endpoint.
An error ends the flow with an Error Response or an Unrecoverable Error.
Type: authn_request_received
Description: An authentication request has arrived. No check has been made yet, so the requester is not verified. For SAML, the event is written once the message has been decoded; a message that cannot be decoded only gives an Unrecoverable Error. For OpenID Connect, the request object of a request that has one has not yet been read.
Audit data: requester, see The requester.
Audit data: authn_request, SAML
| Parameter | Description | Type |
|---|---|---|
id |
The ID of the AuthnRequest. |
String |
issuer |
The Issuer of the request. Absent if there is none. |
String |
destination |
The Destination of the request. Absent if there is none. |
String |
binding |
The binding the request was received with, the URI of the redirect or the POST binding. | String |
assertion_consumer_service_url |
The AssertionConsumerServiceURL of the request. Absent if the request gives none. |
String |
authn_context_class_refs |
The requested authentication contexts. Absent if none were requested. | List of strings |
force_authn |
The ForceAuthn attribute. |
Boolean |
is_passive |
The IsPassive attribute. |
Boolean |
relay_state |
The RelayState. Absent if there is none. |
String |
signed |
Whether the request was signed, with an XML signature or, for the redirect binding, in the query string. | Boolean |
holder_of_key |
Whether the request was received on a Holder-of-key endpoint. | Boolean |
Audit data: authn_request, OpenID Connect
| Parameter | Description | Type |
|---|---|---|
client_id |
The client_id parameter. |
String |
redirect_uri |
The redirect_uri parameter. |
String |
response_type |
The response_type parameter. |
String |
response_mode |
The response_mode parameter. |
String |
scope |
The requested scopes. | List of strings |
acr_values |
The requested authentication contexts. | List of strings |
prompt |
The prompt values. |
List of strings |
state |
The state parameter. |
String |
code_challenge_method |
The PKCE code challenge method. | String |
request_object |
Whether a request object was given, with request or request_uri. |
Boolean |
Every member except request_object is absent when the request does not have it.
Type: authn_request_accepted
Description: The request has passed all checks, the requester is verified, and the user authentication starts. Any error from here on is answered to the requester.
Audit data: requester, see The requester.
Audit data: authn_request, with the members of
Authentication Request Received, with these differences:
assertion_consumer_service_url is the assertion consumer service that the response is sent to.response_mode is the response mode that is
used, query or form_post.Type: authn_user_authenticated
Description: The user has been authenticated, or an earlier authentication from the session was reused for single sign-on. The event holds every attribute the authentication module delivered, whether or not it is released to the requester. Which attributes were released is found in the Success Response and UserInfo Delivered events.
Audit data: requester, see The requester.
Audit data: authn_request, as in Authentication Request Accepted.
Audit data: user_authentication
| Parameter | Description | Type |
|---|---|---|
authn_instant |
When the user authenticated. For single sign-on, the instant of the original authentication. | Instant |
acr |
The authentication context under which the user was authenticated, the SAML AuthnContextClassRef and the OpenID Connect acr. |
String |
authenticating_authority |
The service that authenticated the user, when the server proxies the authentication. Absent otherwise. | String |
client_ip_address |
The IP address of the client the user authenticated from. | String |
sign_message_displayed |
Whether a sign message was displayed for the user. | Boolean |
allowed_to_reuse |
Whether the authentication may be reused for single sign-on. | Boolean |
sso |
Whether an earlier authentication was reused for single sign-on. | Boolean |
sso_information.original_protocol |
The protocol of the request that the user originally authenticated for, saml or oidc. Present only when sso is true. |
String |
sso_information.original_requester |
The requester that the user originally authenticated for. Present only when sso is true. |
String |
sso_information.original_request_id |
The ID of the SAML AuthnRequest that the user originally authenticated for. Absent when sso is false, and when the original request was an OpenID Connect request. |
String |
Audit data: attributes
A list of the attributes that the authentication module delivered, by their protocol-neutral names, such as
attribute.personal-identity-number, see Attributes. Each element has:
| Parameter | Description | Type |
|---|---|---|
name |
The name of the attribute. | String |
values |
The values of the attribute, as strings. | List of strings |
Type: authn_authorization_response
Description: OpenID Connect only. The authorization code has been issued, and the authorization response holding it is sent to the client. The code itself is not recorded.
Audit data: requester, see The requester.
Audit data: authorization_response
| Parameter | Description | Type |
|---|---|---|
redirect_uri |
Where the response is sent. | String |
response_mode |
The response mode, query or form_post. |
String |
state |
The state of the request. Absent if there is none. |
String |
Type: authn_success_response
Description: For SAML, a Response holding the assertion has been built and is sent to the Service Provider. For
OpenID Connect, the client has redeemed the authorization code at the token endpoint and the ID token has been issued.
There is no separate event for the tokens. The event holds the attributes that were released, by their protocol names.
Audit data: requester, see The requester.
Audit data: response, SAML
| Parameter | Description | Type |
|---|---|---|
id |
The ID of the Response. |
String |
in_response_to |
The ID of the AuthnRequest. |
String |
destination |
The assertion consumer service the response is posted to. | String |
issued_at |
The IssueInstant of the response. |
Instant |
signed |
Whether the response is signed. | Boolean |
relay_state |
The RelayState. Absent if there is none. |
String |
assertion.id |
The ID of the assertion. | String |
assertion.signed |
Whether the assertion is signed. | Boolean |
assertion.encrypted |
Whether the assertion is encrypted in the response. | Boolean |
assertion.subject_id |
The NameID of the subject. |
String |
assertion.subject_id_format |
The format of the NameID. |
String |
assertion.authn_instant |
The AuthnInstant of the authentication statement. |
Instant |
assertion.authn_context_class_ref |
The AuthnContextClassRef of the authentication statement. |
String |
assertion.authenticating_authorities |
The AuthenticatingAuthority elements. Absent if there are none. |
List of strings |
Audit data: response, OpenID Connect
| Parameter | Description | Type |
|---|---|---|
sub |
The sub of the user for the client. |
String |
acr |
The acr of the ID token. |
String |
auth_time |
The auth_time of the ID token. |
Instant |
scope |
The scopes that the tokens were issued for. | List of strings |
redirect_uri |
The redirect URI of the authentication request. | String |
id_token_signed |
Whether the ID token is signed. Always true. |
Boolean |
id_token_encrypted |
Whether the ID token is encrypted. | Boolean |
Audit data: released_attributes
A list of the released attributes, by their protocol names: the SAML attribute names of the assertion, or the claims of
the ID token. Each element has name and values, as the attributes of
User Authenticated. The list is empty if nothing was released.
Type: authn_userinfo_delivered
Description: OpenID Connect only. A UserInfo response holding the claims has been produced and is sent to the client.
Audit data: requester, see The requester.
Audit data: response
| Parameter | Description | Type |
|---|---|---|
sub |
The sub of the user for the client. |
String |
signed |
Whether the response is a signed JWT. | Boolean |
encrypted |
Whether the response is encrypted. | Boolean |
Audit data: released_attributes, the claims of the response other than sub, as in
Success Response.
Type: authn_error_response
Description: An error is sent to the requester: a SAML error response, an OpenID Connect authorization error sent to the redirect URI, an error from the token endpoint or an error from the UserInfo endpoint. This includes a user who cancels the authentication. The event is written just before the response is sent.
Audit data: requester, see The requester.
Audit data: stage, a string telling where the error came from:
| Value | Description |
|---|---|
authn_request |
The processing of the authentication request, before the user authentication started. |
user_authentication |
The user authentication, including the return from the pages of an authentication module. |
response |
The completion of the response after the user was authenticated, such as the release of attributes. |
token |
The token endpoint. |
userinfo |
The UserInfo endpoint. |
Audit data: error, the error object of spring-audit-support, with these members:
| Parameter | Description | Type |
|---|---|---|
code |
The error code of the protocol. For SAML the subordinate status code, such as http://id.elegnamnden.se/status/1.0/cancel. For OpenID Connect the error code, such as access_denied or invalid_grant. A UserInfo request without an access token gets no error code (RFC 6750, Section 3.1), and is recorded as missing_token. |
String |
message |
The description of the error. Absent if there is none. | String |
Audit data: response, SAML
| Parameter | Description | Type |
|---|---|---|
id, in_response_to, destination, issued_at, signed, relay_state |
As in Success Response. | |
status_code |
The status code. | String |
subordinate_status_code |
The subordinate status code. | String |
status_message |
The status message. Absent if there is none. | String |
Audit data: response, OpenID Connect authorization error
| Parameter | Description | Type |
|---|---|---|
redirect_uri |
Where the error is sent. | String |
response_mode |
The response mode, query or form_post. |
String |
state |
The state of the request. Absent if there is none. |
String |
Audit data: response, OpenID Connect token and UserInfo error
| Parameter | Description | Type |
|---|---|---|
http_status |
The HTTP status of the response. | Integer |
Type: authn_unrecoverable_error
Description: An error occurred that cannot be answered to the requester, because it is not known who the requester
is or where to send a response. The error is shown to the user instead. Examples are a SAML message that cannot be
decoded, an unknown Service Provider or client, a redirect_uri that the client has not registered, and a return to
the resume path without an authentication in progress. The principal and verified follow
The principal, so an unknown requester is recorded as the requester the request names.
Audit data: requester, see The requester.
Audit data: stage, as in Error Response. Absent when the stage is not known, such as
for an error on the pages of an authentication module that do not belong to an authentication in progress.
Audit data: error
| Parameter | Description | Type |
|---|---|---|
code |
The message code of the error, such as authn-server.error.unrecoverable.session. The errors are listed in CommonUnrecoverableError, SamlUnrecoverableError and OidcUnrecoverableError. |
String |
message |
A description of what went wrong. | String |
These events are not tied to an authentication flow. Their principal is the system principal, system.
Type: authn_credential_test_error
Description: A monitored credential failed its test. Written for credentials-support’s
FailedCredentialTestEvent. What credential monitoring is, and when the events occur, is described under
Monitoring in the credentials-support documentation.
Audit data:
| Parameter | Description | Type |
|---|---|---|
credential_name |
The name of the credential. | String |
error.message |
The error reported by the test. | String |
error.exception_class |
The class of the exception from the test. Absent if there was none. | String |
Type: authn_credential_reload_success
Description: A monitored credential that failed its test has been reloaded. Written for credentials-support’s
SuccessfulCredentialReloadEvent.
Audit data:
| Parameter | Description | Type |
|---|---|---|
credential_name |
The name of the credential. | String |
Type: authn_credential_reload_error
Description: A monitored credential that failed its test could not be reloaded, and cannot be used. Written for
credentials-support’s FailedCredentialReloadEvent.
Audit data: as Credential Test Error, with the error of the reload.
Two conditions of OpenID Federation are published as spring-audit-support’s SystemAlertEvent, and audited as
System Alert events:
The trust marks of the OpenID Provider are wired to publish the alerts. A
TrustMarkStatusChecker is created by the application, which gives it the application
context with setEventPublisher(...).
Type: client_added
Description: A client appeared in the client registry: a SAML metadata source that was downloaded or read again
holds a new Service Provider, an OpenID Federation client was resolved and was not known before, or a client that the
server loads at startup was not known before the restart. There is one event per client. The type has no authn_
prefix since it is a system operation. When the event occurs, and how the server knows which clients it had before a
restart, is described under Clients added and removed.
Audit data:
| Parameter | Description | Type |
|---|---|---|
client.protocol |
saml or oidc. |
String |
client.id |
The SAML entityID or the OpenID Connect client_id. |
String |
client.organization_number |
The organisation number of the client exactly as the client registry holds it, see The requester. Absent if the client has none. | String |
client.source |
Where the client came from: the SAML metadata source, or the OpenID Connect backend, properties, configuration, repository or federation. |
String |
Type: client_removed
Description: A client disappeared from the client registry: a SAML metadata source that was downloaded or read again no longer holds a Service Provider, and no other source does, the OpenID Federation resolver reports a client that was known as not found, or a client that was known before a restart is no longer loaded. There is one event per client. A federation client whose cache entry expires and is resolved again is not removed.
Audit data:
| Parameter | Description | Type |
|---|---|---|
client |
The client as it was known, with the members of Client Added. | Object |
reason |
Why the client was removed, for example no longer held by the source 'https://md.example.com/sp.xml' or the resolver reports the client as not found. |
String |
The events are written once for the whole deployment when the nodes share their state in Redis. A deployment that does
not want them leaves them out with audit.repository.exclude-events.
Each event type has a transformer, registered as a bean by the auto-configuration:
| Type | Transformer |
|---|---|
authn_request_received |
AuthnRequestReceivedEventTransformer |
authn_request_accepted |
AuthnRequestAcceptedEventTransformer |
authn_user_authenticated |
AuthnUserAuthenticatedEventTransformer |
authn_authorization_response |
AuthnAuthorizationResponseEventTransformer |
authn_success_response |
AuthnSuccessResponseEventTransformer |
authn_userinfo_delivered |
AuthnUserInfoDeliveredEventTransformer |
authn_error_response |
AuthnErrorResponseEventTransformer |
authn_unrecoverable_error |
AuthnUnrecoverableErrorEventTransformer |
authn_credential_test_error |
CredentialTestErrorEventTransformer |
authn_credential_reload_success |
CredentialReloadSuccessEventTransformer |
authn_credential_reload_error |
CredentialReloadErrorEventTransformer |
client_added |
ClientAddedEventTransformer |
client_removed |
ClientRemovedEventTransformer |
They are found in the
se.swedenconnect.spring.authnserver.audit.transform package. A transformer is only created if the
application has not declared a bean of the same type, so an application replaces one by declaring its own bean of that
type. The usual way is to extend the transformer and override getDataFields, which returns the data of the event in
the order it is written. This one leaves the attributes out of the User Authenticated
event:
@Bean
AuthnUserAuthenticatedEventTransformer authnUserAuthenticatedEventTransformer() {
return new AuthnUserAuthenticatedEventTransformer() {
@Override
protected List<AuditValue<? extends Serializable>> getDataFields(final AuthnUserAuthenticatedEvent event) {
final List<AuditValue<? extends Serializable>> fields = super.getDataFields(event);
fields.removeIf(f -> ATTRIBUTES.equals(f.getName()));
return fields;
}
};
}
The events themselves, in the se.swedenconnect.spring.authnserver.audit.events package, carry
the requester, the protocol-specific part as a
ProtocolAuditData, and what else the event is about, so a replaced transformer can write any of
it. Document a changed event in the same way as on this page, see
Documenting Audit Events.
To leave an event type out of the audit log altogether, use audit.repository.exclude-events, see
Configuration.
Copyright © 2026, Sweden Connect. Licensed under version 2.0 of the Apache License.