Data published to Moesif¶
To build your analytics dashboards, WSO2 Identity Server sends a record of identity activity - logins, sign-ups, sessions, tokens, and more - to Moesif.
This page tells you exactly what is sent. Use it to understand what your dashboards can show, and to answer privacy and compliance questions about your users' data. If you build your own charts in Moesif, it also names the attribute you need to filter or group by.
Note
This page evolves. Each time a new dashboard or insight is added, the events behind it are added here too.
What gets sent, at a glance¶
Six kinds of events are published. Each one answers a different question about your organization.
| Event | Sent when | Helps you answer |
|---|---|---|
| Login | A user tries to log in, at every step of the login flow. | How many people are logging in, how often logins fail and why, which connections and multi-factor authentication (MFA) methods are actually used. |
| Sign-up | A user account is created. | How fast you are growing, and whether new users arrive through self sign-up, invitations, or an administrator. |
| Session | A session starts, is refreshed, or ends. | How many users are active right now, how long sessions last, and why they end. |
| Token issuance | An OAuth2 or OpenID Connect token is issued, or a token request fails. | Which applications consume tokens, which grant types they use, and how much machine-to-machine traffic you have. |
| Flow step | Each step of a self-registration, password recovery, or invited-user registration flow. | Where users drop out of your sign-up and recovery funnels. |
| Organization switch | A user switches into an organization in a business-to-business (B2B) setup. | Which organizations your users actually work in. |
What personal data is included¶
These events describe real people, so they carry personal data. Across the events, the following may be published:
- Who the user is - their username and unique user ID, the user store they belong to, and any attribute you use as a login identifier, such as an email address, mobile number, or national identity number. Login events additionally carry the roles assigned to the user.
- Where they connected from - their IP address and the user agent of their browser or app.
- What they were doing - the organization, application, and connection involved in the activity.
A few things are deliberately not sent:
- No passwords, no one-time passwords, and no credentials of any kind.
- No token values. Tokens are identified by an ID only, never by their contents.
- No user profile attributes other than those listed above. Nothing else is read from the user's profile.
You decide which of these events are published. If a category is not useful to you, leave its publisher off. See Set up Moesif analytics.
How an event is shaped¶
Every event arrives in Moesif in the same envelope, sent to the Moesif Actions API:
{
"actionName": "User-Authentication",
"userId": "<user ID>",
"companyId": "<organization ID>",
"request": {
"time": "<event timestamp>",
"ipAddress": "<end user IP address>"
},
"metadata": {
"...": "attributes specific to this event type"
}
}
actionNamenames the kind of event. Filter on this in Moesif to isolate one event type.userIdandcompanyIdare how Moesif groups activity by user and by organization.userIdis left out when the event happens before a user can be identified, such as a login that fails at the username step.- Everything else lives under
metadata- that is where the attributes listed below appear. - The user agent travels as the
User-Agentheader of the request, not in the body.
Two conventions are worth knowing when you build charts:
- An attribute that could not be resolved for a particular event carries the literal value
NOT_AVAILABLErather than being dropped, so exclude that value when you total the results. - Most timestamps are ISO-8601 strings. The exceptions are epoch milliseconds:
_timestampon login and session events, andcreatedTimestamp,updatedTimestamp, andterminationTimestampon session events. Each row below states the unit.
Logins¶
Login events are the busiest stream. One event is published for each step of a login flow, and one for the final outcome, so a two-factor login produces multiple events that share the same contextId.
actionName: User-Authentication
The attributes you will reach for most often are authenticationSuccess (did the login work), serviceProvider (which application), stepAuthenticator (which factor), identityProvider (which connection), and errorCode (why it failed).
All login attributes
| Attribute | Description |
|---|---|
contextId | Correlates every step of a single login attempt. Group by this to reconstruct one user's login journey. |
eventId | Unique ID of this event. |
eventType | Whether this event reports a single step or the final authentication outcome. |
authenticationSuccess | Whether the login as a whole succeeded. |
authStepSuccess | Whether this individual step succeeded. |
authenticationStep | Step number in the login flow that this event reports on. |
stepAuthenticator | Authenticator used at this step, such as username and password, or an MFA authenticator. |
identityProvider | Connection used at this step. |
identityProviderType | Whether that connection is local or federated. |
identityProviders | All connections involved in the login flow. |
authenticators | All authenticators involved in the login flow. |
username | Fully qualified username of the user. |
localUserName | Username of the user in the local user store. |
usernameUserInput | Identifier the user actually typed at the login screen. This may be an email address, mobile number, or another login identifier. |
userStoreDomain | User store domain the user belongs to. |
rolesCommaSeparated | Roles assigned to the user, as a comma-separated list. |
isFirstLogin | Whether this is the user's first login. |
serviceProvider | Application the user logged in to. |
inboundAuthType | Protocol the application used, such as OAuth2/OIDC or SAML. |
tenantDomain | Organization the login belongs to. |
userResidingOrgId | Organization the user is resident in. |
userAccessingOrgId | Organization the user is accessing. |
spResidingOrgId | Organization the application is resident in. |
isOrganizationLogin | Whether the login happened in an organization (B2B) context. |
isSharedAppLogin | Whether the login was to an application shared with an organization. |
remoteIp | IP address the login came from. |
region | Region resolved for the login. |
rememberMeEnabled | Whether the user selected "remember me". |
forceAuthEnabled | Whether the application forced re-authentication. |
passiveAuthEnabled | Whether this was a passive authentication request. |
duration | How long the authentication took, in milliseconds. |
errorCode | Error code, when the login or step failed. |
_timestamp | When the event was recorded, in epoch milliseconds. |
customParam1 to customParam5 | Reserved for custom values added through extensions. Empty unless an extension populates them. |
Sign-ups¶
One event per account created, whichever way the account came into existence.
actionName: User-Registration
userOnboardedMethod is the attribute that makes this stream useful: it separates self sign-ups from invitations and administrator-created accounts.
All sign-up attributes
| Attribute | Description |
|---|---|
eventId | Unique ID of this event. |
createdTimeStamp | When the account was created, as an ISO-8601 string. |
userOnboardedMethod | How the account was onboarded: SELF_SIGNUP, USER_INVITE, or ADMIN_INITIATED. |
userstoreDomain | User store the account was created in. |
tenantDomain | Organization the account belongs to. |
userResidingOrgId | Organization the user is resident in. |
Sessions¶
Three events per session: one at creation, one for each update, and one when the session ends.
actionName: User-Session
Use action to tell those three apart, activeSessionCount for concurrency, and the timestamps to work out how long sessions live.
All session attributes
| Attribute | Description |
|---|---|
sessionId | Unique ID of the session. |
action | Which part of the lifecycle this event reports: creation, update, or termination. |
createdTimestamp | When the session was created, in epoch milliseconds. |
updatedTimestamp | When the session was last updated, in epoch milliseconds. |
terminationTimestamp | When the session ended, in epoch milliseconds. |
activeSessionCount | How many sessions the user holds at this moment. |
username | Username of the session owner. |
userStoreDomain | User store domain the user belongs to. |
tenantDomain | Organization the session belongs to. |
serviceProvider | Application the session was established for. |
identityProviders | Connections involved in establishing the session. |
remoteIp | IP address the session came from. |
region | Region resolved for the session. |
userAgent | User agent of the browser or client that established the session. |
rememberMeEnabled | Whether the session was established with "remember me". |
_timestamp | When the event was recorded, in epoch milliseconds. |
Tokens¶
One event per token request, successful or not. Machine-to-machine (M2M) tokens are included.
actionName: OAuth-Token-Issuance
grantType, clientId, and userType are what most token dashboards are built on. existingTokenUsed is worth knowing about. It marks a request served from an existing valid token rather than a newly issued one, which is why token counts and login counts do not line up.
No token values are published
Only tokenId, an opaque identifier, is sent. The access token, refresh token, and ID token contents never leave WSO2 Identity Server.
All token attributes
| Attribute | Description |
|---|---|
clientId | Client ID of the application the token was issued to. |
grantType | OAuth2 grant type used. |
userType | Whether the token was issued for an end user or an application. |
userId | Unique ID of the user the token was issued for. |
userName | Username of the user the token was issued for. |
userStoreDomain | User store domain the user belongs to. |
actor | Acting identity behind the request, when a token is requested on behalf of another identity. |
tokenId | Identifier of the issued token. Not the token itself. |
iat | When the token was issued, as an ISO-8601 string. |
authorizedScopes | Scopes granted to the token. |
unauthorizedScopes | Scopes requested but not granted. |
accessTokenValidityMillis | Access token validity, in milliseconds. |
refreshTokenValidityMillis | Refresh token validity, in milliseconds. |
existingTokenUsed | Whether an existing valid token was returned instead of issuing a new one. |
tenantDomain | Organization the request belongs to. |
rootTenantDomain | Root organization of the request. |
issuerOrganizationId | Organization that issued the token. |
accessingOrganizationId | Organization the token grants access to. |
appResidentTenantId | Tenant the application is resident in. |
appResidentOrgUuid | Organization the application is resident in. |
subOrgRequest | Whether the request came from one of your sub-organizations. |
remoteIp | IP address the request came from. |
errorCode | Error code, when the request failed. |
errorMsg | Error message, when the request failed. |
publishingTime | When the event was published, as an ISO-8601 string. |
Flows¶
Self-registration, password recovery, and invited-user registration are multi-step flows, and this stream publishes one event per step. That is what makes funnel analysis possible: you can see how many users started sign-up, how many reached email verification, and how many finished.
actionName: User-Registration-Flow, Password-Recovery-Flow, or Invited-User-Registration-Flow
Group by flowId to follow one user through a flow, and by currentNodeId and nodeResponseStatus to find the step where people drop out.
How anonymous steps are linked to users
Early sign-up steps run before the user account exists. No user ID can be attached to them, so they are published against an anonymous identifier.
When the flow completes, a user link event goes to the Moesif Users API. It ties that anonymous identifier to the new user ID, so the funnel joins up end to end. The link event carries only those two identifiers.
All flow attributes
| Attribute | Description |
|---|---|
flowType | Which flow this is, such as registration or password recovery. |
flowId | Correlates every step of a single flow execution. |
stepType | Which kind of step was executed. |
currentNodeId | ID of the node that was executed. |
currentNodeType | Which kind of node was executed. |
nodeResponseStatus | Outcome of the node execution. |
nodeResponseType | Which kind of response the node produced. |
executorName | Executor that ran the step, for example the executor for a particular verification method. |
applicationId | Application the flow was started from. |
tenantDomain | Organization the flow belongs to. |
organizationId | Unique ID of that organization. |
isOrganizationLogin | Whether the flow ran in an organization (B2B) context. |
publishTimestamp | When the event was published, as an ISO-8601 string. |
errorCode | Error code, when the step failed. |
Organization switches¶
In a B2B setup, a user who belongs to one organization can access another. Each switch is published as an event.
actionName: Organization-Switch
userResidentOrgId is where the user comes from and userAccessingOrgId is where they went, so a breakdown of the two shows how your organizations relate to each other.
All organization switch attributes
| Attribute | Description |
|---|---|
userResidentOrgId | The user's home organization. |
userAccessingOrgId | Organization the user switched into. |
serviceProvider | Application the switch was performed for. |
serviceProviderTenantDomain | Tenant that application belongs to. |
tenantDomain | Organization the switch belongs to. |
errorCode | Error code, when the switch failed. |
publishTime | When the event was published, as an ISO-8601 string. |
A note on sub-organizations¶
Activity inside your sub-organizations is published against the root organization, so everything lands in one place rather than being scattered across workspaces. The originating organization is preserved in attributes such as userResidingOrgId and userAccessingOrgId, so you can still filter or break down any chart by it.