Plugin SSO

Plugin SSO

Staffbase is extensible by providing additional functionality via plugins. Plugins are external mobile-ready web applications that may be embedded into the Staffbase client and that third-parties may provide via Staffbase’s Plugin API. Conceptually, they are organized into a set of instances. When the admin of a Staffbase organization decides to employ a plugin, she installs it in her organization. For example, one may manage a set of different Google Maps displayed in Staffbase with the Maps plugin provided by Staffbase. Each map is an instance of the Maps plugin.

When a user wants to access a plugin instance, Staffbase will forward the user to the external web application, in the example above to the configured Google Maps instance. The web application has to manage all data displayed to the user itself. Therefore, it requires certain pieces of information when being accessed. For example which instance (map) to display in a specific request, and whether or not the requesting user may alter the data displayed. This is where the Plugin API’s single sign-on comes into play.

The process of accessing a plugin instance is shown in the figure below and consists of three steps: The client’s request to access the plugin (1), the single sign-on (2) and the display of the data (3). When talking about the process of accessing a plugin instance in Staffbase, we will refer to Staffbase as the Client, to the Staffbase Cloud, which serves as the backend for the client, as the Identity Provider (IP) and to the plugin web application as the Relying Party (RP).  

The flow how SSO is handled when developing a third party plugin for Staffbase

In order to protect the data displayed by the plugin, a relationship of trust needs to be established between the IP and the RP. For example, the IP needs to check whether the client may access a requested plugin instance or not. Moreover, the IP needs to transfer the client to the plugin web application which requires the IP to add a signature to the client’s request. This transfer is the exact purpose of the single sign-on (SSO) process and this document outlines the employed methodology.

Methodology

The Staffbase Plugin SSO is based on the technology of JSON Web Tokens (JWT). They are an open industry standard defined in RFC 7519 and widely accepted in security-related standards such as OpenID Connect. More information is available at jwt.io. On the website, there are multiple resources on the standard as well as a list of robust and complete implementations for various platforms.

The IP will forward the client’s request to an end point of the RP which was previously communicated between the parties. When forwarding, the IP will append a query parameter called jwt to the pre-defined endpoint URL of the RP. This parameter will contain the JWT, therefore a set of claims on the requesting user’s identity and a signature by the IP. When receiving a sign-on attempt, the RP has to check the signature of the JWT in the first place.

Despite the JWT supporting a wide range of algorithms, we had to restrict the employed algorithm to RS256. The Relying Party should deny all attempts to sign in using other algorithms. This is an immediate security requirement. The algorithm also implies that the RP need to know the IP’s public key that is used to verify the signature of the JWT. This public key will be unique for each plugin.

The body of the JWT will be of the following structure – containing both information used in the JWT standard and claims concerning Staffbase.

{
  "aud": "map",
  "exp": 1453287153,
  "nbf": 1453287033,
  "iat": 1453287093,
  "iss": "api.staffbase.com",
  "instance_id": "55c79b6ee4b06c6fb19bd1e2",
  "instance_name": "Our locations",
  "sub": "541954c3e4b08bbdce1a340a",
  "external_id": "jdoe",
  "name": "John Doe",
  "given_name": "John",
  "family_name": "Doe",
  "role": "editor",
  "type": "user",
  "theming_text": "#000000",
  "theming_bg": "#FFFFFF",
  "locale": "en-US"
}

The audience (aud) of the JWT will be set to the id of the plugin in Staffbase’s ecosystem. The IP will provide the RP with such an id and it is required that the RP always verifies this id when verifying a single sign-on attempt.

The token will be valid for exactly one minute. Therefore, the IP will set an expiry date (exp), which date the token should not be used before (nbf) and the date when the token was issued (iat). The Relying Party has to make sure that this constraint is met.

The RP has to verify the constraints regarding the JWT information above in order to ensure a secure access to its data.

In addition to that, the JWT will contain several properties. These are provided by Staffbase and have the following semantics:

  • instance_id: the id of the plugin instance to access. For example, the id of the map to show. A plugin web application should create a new data set if required when encountering an id for the first time.
  • instance_name: the name this instance of the plugin has in Staffbase.
  • sub: the id of the user accessing the plugin.
  • external_id: the id of the user accessing the plugin in an external system, if configured in the IP.
  • name: either the combined name of the user or the name of the token.
  • given_name: the first name of the user accessing.
  • family_name: the last name of the user accessing.
  • role: the role of the accessing user. If this is set to “editor”, the requesting user may manage the contents of the plugin instance (instance_id), i.e. she has administration rights.
  • type: the type of the accessing entity could be either a “user” or a “token”.
  • theming_text: the color of the text that is configured in Staffbase.
  • theming_bg: the color of the background that is configured in Staffbase. 
  • locale: the locale of the requesting user in the format of language tags.

If the JWT is valid in regards of its signature and the constraints mentioned above, the RP may safely display the data and functionality associated with the requested plugin instance to the requesting user.

It should, however, be kept in mind that the JWT is only valid for a short period of time. Any subsequent request should therefore be authenticated, for example using sessions, by the RP itself. The RP has to ensure that a Staffbase user may view different plugin instances simultaneously in the same browser. A session-based approach has to make sure that a session may allow access to multiple plugin instances. Otherwise, there may be side effects.

Anonymous mode

Plugins in Staffbase can be run in two different modes. The normal mode is described above. The anonymous mode should be used for plugins that do not require any special information about the user who accesses the plugin herself. To reduce the risk of a data leakage the RP should challenge their plugin’s scope and decide, if the anonymous mode is enough to achieve the plugin’s purpose.

Beside the standard information about the JWT stated above the only Staffbase specific information will be the instance_id, instance_name, theming_text, theming_bg and the locale that is included into the JWT.

{
  "aud": "map",
  "exp": 1453287153,
  "iat": 1453287093,
  "iss": "app.staffbase.com",
  "instance_id": "55c79b6ee4b06c6fb19bd1e2",
  "instance_name": "Our locations",
  "theming_text": "#000000",
  "theming_bg": "#FFFFFF",
  "locale": "en-US"
}

Example

For this example, we consider the following scenario: We want to implement a plugin which has the id “map” and the public key (see below) assigned by Staffbase. Moreover, the plugin’s end point for displaying information to an end user is defined as “http://example.com”.

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
-----END PUBLIC KEY-----

Now, the plugin web application gets a request with the query parameter jwt having the following value:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJtYXAiLCJleHAiOjE0NTMyODcxNTMsIm5iZiI6MTQ1MzI4NzAzMywiaWF0IjoxNDUzMjg3MDkzLCJpc3MiOiJhcGkuc3RhZmZiYXNlLmNvbSIsImluc3RhbmNlX2lkIjoiNTVjNzliNmVlNGIwNmM2ZmIxOWJkMWUyIiwiaW5zdGFuY2VfbmFtZSI6Ik91ciBsb2NhdGlvbnMiLCJzdWIiOiI1NDE5NTRjM2U0YjA4YmJkY2UxYTM0MGEiLCJleHRlcm5hbF9pZCI6Impkb2UiLCJuYW1lIjoiSm9obiBEb2UiLCJnaXZlbl9uYW1lIjoiSm9obiIsImZhbWlseV9uYW1lIjoiRG9lIiwicm9sZSI6ImVkaXRvciIsInR5cGUiOiJ1c2VyIiwidGhlbWluZ190ZXh0IjoiIzAwMDAwMCIsInRoZW1pbmdfYmciOiIjRkZGRkZGIiwibG9jYWxlIjoiZW4tVVMifQ.f_Ev681l4u7TcOHdeHc1VR2VzvYrprHFEjXte4wb4m54-3Zb5VPR76FN3KMNyrCXya60rUp7K_EY9YASO1VCs5e0xOee76LyhYYk3VnVhfrLBfrOm1LRzdJU9fnxzAgdyL3gwMzNleaXcQG_wurVYC0rXaLqy22PZFDbTdSU2Kw

Using the debugger on jwt.io, one can now see the payload of the token being:

{
  "aud": "map",
  "exp": 1453287153,
  "nbf": 1453287033,
  "iat": 1453287093,
  "iss": "api.staffbase.com",
  "instance_id": "55c79b6ee4b06c6fb19bd1e2",
  "instance_name": "Our locations",
  "sub": "541954c3e4b08bbdce1a340a",
  "external_id": "jdoe",
  "name": "John Doe",
  "given_name": "John",
  "family_name": "Doe",
  "role": "editor",
  "type": "user",
  "theming_text": "#000000",
  "theming_bg": "#FFFFFF",
  "locale": "en-US"
}

As we can see, the payload contains information on the requesting user. In order to verify the sign-on attempt, the RP can now verify the JWT’s signature using the public key. The debugger will declare “Signature verified” for this secret. For others, it will state “Invalid Signature”.

If the signature is correct and the JWT satisfies the other constraints declared in this document, the RP can now use the JWT’s payload to serve content to the requesting user.

jwt.io provides code examples for .NET, Java, Python, Node.js, PHP, Ruby and others and there’s an example skeleton implementation written by Staffbase available on Bitbucket (https://bitbucket.org/mitarbeiterapp/plugin-skeleton-java). We also offer a SDK for PHP on Github (https://github.com/Staffbase/plugins-sdk-php).