Go SDK for user monitoring


Sqreen protects your application users against major threats, such as account takeover, password bruteforce, suspicious activities coming from TOR or an unusual VPN.

The Go agent does not automatically detect your web framework and you have to install the middleware functions for the web framework you use to use the SDK methods described below.

You can find a Go documentation reference of the SDK at https://godoc.org/github.com/sqreen/go-agent/sdk.

User monitoring SDK

The Sqreen SDK integration relies on methods such as TrackSignup() and TrackAuth() allowing you to track security-related events of a given user.

Here is a full example:

uid := sdk.EventUserIdentifiersMap{"uid": "my-uid"}
sqUser := sdk.FromContext(ctx).ForUser(uid)
sqUser.TrackSignup()

User scope

ForUser() provides user monitoring SDK methods:

uid := sdk.EventUserIdentifiersMap{"uid": "my-uid"}
sqreen := sdk.FromContext(ctx)
sqUser := sqreen.ForUser(uid)
sqUser.TrackEvent("my.user.event")

The user identifiers given to ForUser() should uniquely identify the user. Sqreen's interface uses them to help you identify which users are at risk, or which are attacking your application. The hash keys and values must be strings.

Tracking a user authentication

TrackAuth(), TrackAuthSuccess() and TrackAuthFailure() allows you to track successful or failed users logins.

uid := sdk.EventUserIdentifiersMap{"uid": "my-uid"}
sqUser := sdk.FromContext(ctx).ForUser(uid)
sqUser.TrackAuthSuccess()

Sqreen integration at signup and login

You should not call TrachAuth() or success/failure alternatives each time you check a user session in your application, but rather each time a user logs into your app.

Tracking a user sign-up

TrackSignup() allows to track users sign-ups.

uid := sdk.EventUserIdentifiersMap{"uid": "my-uid"}
sqUser := sdk.FromContext(ctx).ForUser(uid)
sqUser.TrackSignup()

Tracking a user

Identify() allows you to associate the user to the current request so that Sqreen can apply security rules targeting specific users when necessary. Sqreen automatically associates every TrackEvent() call performed within the scope of the user-identified request with this user, unless overwritten with WithUserIdentifiers().

uid := sdk.EventUserIdentifiersMap{"uid": "my-uid"}
sqUser := sdk.FromContext(ctx).ForUser(uid)
sqUser.Identify()

User security automation - Blocking users

Security automation allows you to block or redirect users and IP addresses. Sqreen automatically detects IP addresses from the request, but requires you to explicitly associate user-identifiers with requests, using the Identify() SDK method.

Method MatchSecurityResponse() then allows you to check if a security response matches the identified user. If it does, stop the request handler so that Sqreen's middleware function can abort it by applying the configured security response.

Usage example:

func handler(w http.ResponseWriter, r *http.Request) {
    // Get the request record.
    sqreen := sdk.FromContext(r.Context())

    // Example of globally identifying a user and checking if the request
    // should be aborted.
    uid := sdk.EventUserIdentifiersMap{"uid": "my-uid"}
    sqUser := sqreen.ForUser(uid)
    sqUser.Identify() // Globally associate this user to the current request
    if match, _ := sqUser.MatchSecurityResponse(); match {
        // Return to stop further handling the request and let Sqreen's
        // middleware apply and abort the request.
        return
    }
    // Not blocked.
    fmt.Fprintf(w, "OK")
}

Method MatchSecurityResponse() also returns an error, which you can use to bubble-up and stop a deep call stack with the classic Go error handling pattern:

func handler(w http.ResponseWriter, r *http.Request) {
    if err := subfunction(r.Context()); err != nil {
        // If nested in another function, you can still
        // bubble-up the error by returning it again.
        return
    }
    fmt.Fprintf(w, "OK")
}

func subfunction(ctx context.Context) error {
    // Get the request record.
    sqreen := sdk.FromContext(ctx)

    // Example of globally identifying a user and checking if the request
    // should be aborted.
    uid := sdk.EventUserIdentifiersMap{"uid": "my-uid"}
    sqUser := sqreen.ForUser(uid)
    sqUser.Identify() // Globally associate this user to the current request
    if match, err := sqUser.MatchSecurityResponse(); match {
        // Return to stop further handling the request and let Sqreen's
        // middleware apply and abort the request.
        return err
    }
    // Not blocked.
    fmt.Fprintf(w, "OK")
}

Sqreen recommends building or using it in a user-authentication middleware for the web framework you use so that you can deploy it to all your endpoints and block them as soon as possible when necessary.

Example for net/http:

func MyUserMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Get the request record created by Sqreen's middleware function and
        // stored into the request context.
        sqreen := sdk.FromContext(ctx)

        // Example of globally identifying a user and checking if the request
        // should be aborted.
        uid := /* compute your user id based on the request headers or payload */
        sqUser := sqreen.ForUser(uid)
        sqUser.Identify() // Globally associate this user to the current request
        if match, __ := sqUser.MatchSecurityResponse(); match {
            // Return to stop further handling the request and let Sqreen's
            // middleware apply and abort the request.
            return
        }
        // Not blocked, continue with next handler.
        next.ServeHTTP(w, r)
    }
}

// ...
// Build a handler by chaining middlewares and making sure Sqreen's comes first.
handler := sqhttp.Middleware(MyUserMiddleware(myHandler))
// ...

User identification

User monitoring and PII

To learn more about sending sensitive data to us without leaking any Personally Identifying Information (PII), visit this blogpost to learn some best practices around user tracking.

For users with a composite primary key (more than one value), send all the values to identify them accurately on Sqreen's user interface.

For example, if you are are operating a whitelabel platform and it identifies your users by their email and the shop ID, you can send these identifiers like this:

uid := sdk.EventUserIdentifiersMap{
    "email": user.email,
    "platform_id": user.platform_id,
}
sqUser := sdk.FromContext(ctx).ForUser(uid)
sqUser.TrackSignup()

The Sqreen SDK only accepts user identifiers

Do not send any other information (like the auth failure reason). Sqreen will consider them as part of the user identifier, and will not be able to merge successful and failed authentications.

Primary key

Sqreen tries to determine a primary key amongst the keys you provided. Sqreen uses the following keywords to determine the user primary identification key: email, mail, e-mail, username, login.

If Sqreen cannot find any of those keys, it uses the first key in alphabetic order.

If Sqreen finds more than one key, it uses the first in the sequence mentioned above.