Audit#
This chapter describes audit logging in Curity Identity Server. Audit logging is an always-on feature, facilitated through Apache Log4j 2.
Audit messages are logged at the INFO level to the audit-events logger.
An audit message is formatted as a Syslog (RFC 5424) Structured Data Message,
where the structured data parameters of the message are populated by the audit data parameters of the event.
Most individual parameters can be accessed through the Map Conversion Pattern provided by the Log4j Pattern Layout; e.g. %K{key}.
The id, type and message parameters are exceptions and must be accessed through the structured_data_id, structured_data_type and structured_data_message Conversion Patterns, respectively.
Configuration#
Audit logging is configured through the Log4j configuration file located at ${IDSVR_HOME}/etc/log4j2.xml.
For in-depth details on how to configure Log4j, please consult the Apache Log4j 2 Manual.
The audit log configuration consists of a logger and two appenders.
Logger#
The default audit logger configuration as it appears in ${IDSVR_HOME}/etc/log4j2.xml:
<AsyncLogger name="audit-events" level="INFO" additivity="false">
<AppenderRef ref="audit-log"/>
<AppenderRef ref="audit-db"/>
</AsyncLogger>
The default audit logger configuration has the following properties:
- Messages logged to
audit-eventsare collected. - The logger is asynchronous; for performance, as many audit events occur on a request thread.
- The logger is not additive; to prevent the root logger from also collecting audit messages.
- The
audit-logandaudit-dbappenders are utilized to persist the messages.
File Appender#
The default audit to file appender configuration as it appears in ${IDSVR_HOME}/etc/log4j2.xml:
<RollingFile name="audit-log" fileName="${env:IDSVR_HOME}/var/log/audit.log"
filePattern="${env:IDSVR_HOME}/var/log/audit.log.%i.gz">
<Policies>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<Rfc5424Layout appName="Curity" facility="AUDIT" newLine="true" includeMDC="false" />
</RollingFile>
The default audit to file appender configuration has the following properties:
- Audit messages are appended to the file
${IDSVR_HOME}/var/log/audit.log. - The log file rolls when it reaches
10MBin size. Rolled files are stored as${IDSVR_HOME}/var/log/audit.log.<index>.gz; where<index>is an integer counter. - Audit messages are formatted as Syslog (RFC 5424) compliant structured data messages.
Database Appender#
The default audit to database appender configuration as it appears in ${IDSVR_HOME}/etc/log4j2.xml:
<JDBC name="audit-db" tableName="audit">
<ConnectionFactory class="se.curity.identityserver.logging.AuditDatabaseConnectionFactory" method="getDatabaseConnection" />
<Column name="id" pattern="%structured_data_id" />
<Column name="event_type" pattern="%structured_data_type" />
<Column name="message" pattern="%structured_data_message" />
<Column name="instant" isEventTimestamp="true" />
<Column name="event_instant" pattern="%K{instant}" />
<Column name="server" pattern="%K{server}" />
<Column name="subject" pattern="%K{subject}" />
<Column name="client" pattern="%K{client}" />
<Column name="resource" pattern="%K{resource}" />
<Column name="authenticated_subject" pattern="%K{authenticatedSubject}" />
<Column name="authenticated_client" pattern="%K{authenticatedClient}" />
<Column name="acr" pattern="%K{acr}" />
<Column name="endpoint" pattern="%K{endpoint}" />
<Column name="session" pattern="%K{session}" />
</JDBC>
The default audit to database appender configuration has the following properties:
- Audit events are posted to the
audittable. - The proprietary
se.curity.identityserver.logging.AuditDatabaseConnectionFactoryConnection Factory is used; which provides connectivity through a configured JDBC Data Access Provider . Only one such provider can be configured to collect audit messages at a time. - Each column in the target database table is explicitly mapped using a
Columnelement.
If you are using PostgreSQL datasource to log audit events, please note, that in the current version of Log4J (2.7) all columns (except if isEventTimestamp=“true”) are treated as unicode strings and their values are inserted via the PreparedStatement.setNString method, that is not supported by PostgreSQL JDBC driver. Log entries containing Feature is not implemented: PreparedStatement.setNString will indicate this problem in the server log.
To work around this issue you should explicitly declare all string columns as non-Unicode in your appender configuration. This is done by adding isUnicode="false" property to column definitions.
Batching Log Messages for performance#
By default, every message logged by the Database Appender will need to obtain a database connection from the JDBC connection pool. This can become a bottleneck if the server handles a very large event load.
To optimise for performance (at the cost of reliability), it is possible to batch messages to minimize the impact of each individual message.
To do that, use the bufferSize attribute as shown below:
Setting the bufferSize attribute:
<JDBC name="audit-db" tableName="audit" bufferSize="8">
Curity includes a healthcheck for the Database Appender, but to enable it, you must set the log4j2.formatMsgAsync system property to true. That will cause a message similar to the one below to be logged every few seconds:
Logger healthcheck message:
se.curity.identityserver.app.Log4jMonitor - Current logging system health level is [OK]: PT0.000449917S
If the delay between an event occurring and the message being flushed out is within a reasonable limit, the above message will contain [OK].
If it takes longer than expected, you may also see one of [SLOW] (over 250ms), [VERY_SLOW] (over 1sec) and [CRITICAL] (over 2sec).
A system that is working within reasonable conditions should only very rarely report anything other than [OK]. Long delays are normally caused by a logger appender running too slowly. Batching messages as explained above may help if that’s a problem.
For more information about configuring the JDBC appender, please consult the Apache Log4j 2 Manual.
Audit Data#
Audit events carry a common set of parameters; some present in all events, others not.
Mandatory#
These parameters are present in all audit events.
type: the type of the audit event.id: the unique ID of the audit event.instant: the instant the audit event occurred.message: a human readable message detailing the audit event.
Optional#
These parameters are present in some audit events; depending on the context of the event.
subject: the subject affected by the audit event.client: the client affected by the audit event.resource: the resource affected by the audit event.authenticatedSubject: the authenticated subject that triggered the audit event. For userinfo and token related events, contains the subject value provided by authentication, before pseudo-anonymization is applied.authenticatedClient: the authenticated client that triggered the audit event.acr: the ACR of the authenticator involved in the audit event.endpoint: the endpoint called to trigger the audit event.session: the session on which the audit event was triggered.
Audit Events#
profile-added#
Event that occurs when a new profile is added to the server.
type: profile-addedjava type: ProfileAddedSystemEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | no | no | no | no | no |
token-introspected#
Event that occurs when a token is introspected by an external source.
type: token-introspectedjava type: IntrospectionOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | yes | no | no | no |
refresh-token-issued#
Event that occurs when an OAuth refresh token is issued.
type: refresh-token-issuedjava type: IssuedRefreshTokenOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | maybe | no | no | no |
refresh-token-revoked#
Event that occurs when an OAuth refresh token is revoked by an external source.
type: refresh-token-revokedjava type: RevokedRefreshTokenOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | yes | no | no | no |
access-token-issued#
Event that occurs when an OAuth access token is issued.
type: access-token-issuedjava type: IssuedAccessTokenOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | maybe | no | no | no |
access-token-revoked#
Event that occurs when an OAuth access token is revoked by an external source.
type: access-token-revokedjava type: RevokedAccessTokenOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | yes | no | no | no |
id-token-issued#
Event that occurs when an OpenID Connect ID token is issued.
type: id-token-issuedjava type: IssuedIdTokenOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | no | no | maybe | maybe | no | no | no |
initial-dcr-access-token-issued#
Event that occurs when a DCR initial access token is issued.
type: initial-dcr-access-token-issuedjava type: IssuedInitialAccessTokenDcrOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | maybe | no | no | no |
initial-dcr-access-token-consumed#
Event that occurs when a DCR initial access token is consumed registering a dynamic client.
type: initial-dcr-access-token-consumedjava type: ConsumedInitialAccessTokenDcrOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | no | no | no | no |
initial-dcr-access-token-revoked#
Event that occurs when a DCR initial access token is revoked by an external source.
type: initial-dcr-access-token-revokedjava type: RevokedInitialAccessTokenDcrOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | yes | no | no | no | no |
dcr-client-registered#
Event that occurs when an OAuth client is dynamically registered (DCR).
type: dcr-client-registeredjava type: RegisteredDcrClientOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | yes | no | maybe | maybe | no | no | no |
user-info#
Event that occurs when an oauth-userinfo is successfully queried.
type: user-infojava type: UserInfoOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | no | yes | yes | no | no | no | no |
authorization-code-issued#
Event that occurs when an OAuth authorization code is issued.
type: authorization-code-issuedjava type: IssuedAuthorizationCodeOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | maybe | maybe | no | no | no |
authorization-code-consumed#
Event that occurs when an OAuth authorization code is consumed.
type: authorization-code-consumedjava type: ConsumedAuthorizationCodeOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | no | yes | no | no | no |
delegation-issued#
Event that occurs when a delegation is issued.
type: delegation-issuedjava type: IssuedDelegationOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | maybe | maybe | no | no | no |
delegation-revoked#
Event that occurs when a delegation is revoked.
type: delegation-revokedjava type: RevokedDelegationOAuthEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | yes | no | maybe | maybe | no | no | no |
account-created#
Event that occurs when an account is created.
type: account-createdjava type: CreatedAccountEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | no | no | no | no | no | no | no |
accounts-linked#
Event that occurs when an account is linked.
type: accounts-linkedjava type: LinkedAccountEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | no | no | no | no | no | no | no |
account-activated#
Event that occurs when an account is activated.
type: account-activatedjava type: ActivatedAccountEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | no | no | no | no | no | no | no |
account-deleted#
Event that occurs when an account is deleted.
type: account-deletedjava type: DeletedAccountEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | no | no | no | no | no | no | no |
scim-account-updated#
Event that occurs when an account is updated through SCIM.
type: scim-account-updatedjava type: AccountUpdatedScimEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | yes | yes | no | no | no | no |
scim-account-created#
Event that occurs when an account is created through SCIM.
type: scim-account-createdjava type: AccountCreatedScimEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | yes | yes | no | no | no | no |
scim-account-deleted#
Event that occurs when an account is deleted through SCIM.
type: scim-account-deletedjava type: AccountDeletedScimEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | yes | yes | no | no | no | no |
access-token-authentication#
Event that occurs at successful authentication using an OAuth access token.
type: access-token-authenticationjava type: AccessTokenAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | yes | no | maybe | yes | no |
client-authentication-success#
Event that occurs when a client is successfully authenticated.
type: client-authentication-successjava type: SuccessClientAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | no | yes | no | yes | no |
client-authentication-failure#
Event that occurs when a client fails to authenticate.
type: client-authentication-failurejava type: FailureClientAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | yes | no | no | no | no | yes | no |
cat-verification-failed#
Event that occurs when a client fails to authenticate.
type: cat-verification-failedjava type: FailedCatVerificationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | yes | no | no | no | no | no | no |
logout#
Event that occurs on user logout.
type: logoutjava type: LogoutAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | yes | no | yes | no | yes |
user-authentication-success#
Event that occurs on successful user authentication.
type: user-authentication-successjava type: SuccessAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | maybe | no | yes | no | yes | no | yes |
user-sso-authentication-success#
Event that occurs on successful user SSO authentication.
type: user-sso-authentication-successjava type: SuccessSsoAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | maybe | no | yes | no | yes | no | yes |
sso-session-created#
Event that occurs when an SSO session is created
type: sso-session-createdjava type: CreatedSsoSessionEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | maybe | no | yes | no | yes | no | yes |
bc-authentication-start#
Event that occurs when back-channel authentication is started.
type: bc-authentication-startjava type: StartedBackchannelAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| yes | no | no | no | yes | no | no | yes |
bc-authentication-success#
Event that occurs when back-channel authentication succeeds.
type: bc-authentication-successjava type: SuccessBackchannelAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | yes | yes | yes | no | yes |
bc-authentication-failure#
Event that occurs when back-channel authentication fails.
type: bc-authentication-failurejava type: FailureBackchannelAuthenticationEvent
Optional audit data presence:
| subject | client | resource | authenticatedSubject | authenticatedClient | acr | endpoint | session |
|---|---|---|---|---|---|---|---|
| no | no | no | no | yes | no | no | yes |