Authentication
Impact Finance Web App sessions are secured using encrypted session cookies.
In order to create a session, the end-user must be authenticated, i.e. the Impact Finance Web App must get reliable proof of the end user's identity.
NOTE: Here, "identity", should not be understood as meaning the end-users Personal Identifiable Information (PII), but rather any opaque identifier which is stable across sessions and recognizable by you as the user's
externalId
in the API.
The following participants are involved in the authentication:
- Bank Client App: Your mobile or web retail banking application, running on your end-user's device.
- Impact Finance Client-Side App: The client-side part of the Impact Finance web application (consisting of HTML and JS resources), running inside a native Webview or iframe, in your Bank Client App, on your end-user's device.
- Impact Finance Backend: The server-side part of the Impact Finance web application, running either as SaaS by us or self-hosted by you. This server is both responsible for serving the HTML and JS resources, as well as handling any other HTTP requests made by the running Impact Finance Client-Side App.
- Bank Authorization Server: The service(s) hosted by you, responsible for issuing ID tokens and helping out in validating and / or exchanging them for user identifiers.
Currently, the Impact Finance Web App supports two different ways of authenticating the end-user. Either using OpenID Connect ID tokens and asymmetric signatures, or using opaque tokens validated by your backend. In either case, the overall flow is the same: An ID token is provided by your Bank Client App to the Impact Finance Backend, which validates the token with the help of your Authorization Server and creates a cookie-based session for the user identified by the token.
- As a first step, your Bank Client App is responsible for getting an ID token as proof the end-user's identity. You are free to implement this step in any way you like. As an example, assuming the Bank Client App is a mobile application, you could use the OpenID Connect Authorization Code Flow with Proof Key for Code Exchange (PKCE) to generate an OpenID Connect ID token. See example here.
- Secondly, you Bank Client App should create a Webview or iframe to load and
run the Impact Finance Client-Side App in.
The first web page is loaded by making a
POST
request to/users/verify_token
on the Impact Finance Backend. The request body should contain atoken
parameter with the end-user's ID token. (BothContent-Type: application/x-www-form-urlencoded
andapplication/json
are acceptable.) Note that our SDKs can help you out in this step and abstract away the work of creating and loading the Webview. Please see separate documentation for each platform. - In this step, the Impact Finance Backend validates the token and extracts the end-user's identity using the mechanism of your choosing. See Authenticating with OpenID Connect ID Tokens and Asymmetric Signatures, or Authenticating with Opaque Tokens for details on each approach.
- If the token is proven to be valid, the Impact Finance Backend now creates a session for the end-user authenticated by the token.
- The response back to the Webview or iframe is a 302 redirect to a
<location>
with aSet-Cookie
header containing the newly created session cookie. - The Webview or iframe follows the redirect and sends a request for the
<location>
together with aCookie
header containing the Impact Finance Session Cookie. - From now on, the cookie is the authentication mechanism proving that each subsequent request is coming from a legitimate user, as well as who that user is.
- Given a valid session cookie, the Impact Finance Backend now responds to the request. It may also update the session cookie with any new data added to the session.
- Without a valid session cookie, the Impact Finance Backend responds to all requests with a 401 Forbidden response.
- Likewise, if the token can not be proved to be valid in step 3 above, the
Impact Finance Backend responds to the
/users/verify_token
request with 401 Forbidden.
Session Cookie Security Properties
Encryption
The session cookie is encrypted with AES using a 256-bit key in Galois/Counter Mode, providing both integrity as well as confidentiality to its contents; Without breaking this encryption a malicious user can neither see nor change any of the data stored in it.
Limited lifetime
The session cookie has a limited life time, after which it expires and is no longer usable.
Please see Keeping the Session Alive for more information on how to configure this expiration time, as well as how to extend the life time while the end-user is actively using the application.
NOTE we are not relying on the browser's mechanism to clean up the cookie using the Expires or Max-Age attributes. Instead, the expiration timestamp is stored in the session data itself, so that the Impact Finance Backend is in full control over invalidating expired cookies.
Sign Out / Session Invalidation
By sending a onSignOutRequested
message to the Impact Finance Client-Side App,
the end-user can be actively signed out, and the session invalidated.
See Sign Out.
Note that this not only removes the cookie from the browser, but also stores the invalidated session ID in the Impact Finance backend to invalidate the existing cookies attached to that session, preventing possible hijacking.
Authenticating with OpenID Connect ID Tokens and asymmetric signatures
Using this authentication mechanism, the ID Token should be in the form of a signed (and optionally encrypted) JSON Web Token (JWT), containing the following minimal set of claims to limit data exposure:
iss
: Issuer Identifier for your Authorization Server. It is communicated out-of-band (configured in DEPo) during integration.sub
: Subject Identifier, i.e. the end-user ID recognizable by you as theexternalId
in the API. If possible, we recommend using a Pairwise Pseudonymous Identifier (PPID).aud
: Audience that this ID Token is intended for. It is communicated out-of-band (configured in DEPo) during integration.exp
: Expiration time, after which the token will not be valid. Also, see token-renewed sessions on how this value affects session duration.iat
: Time at which the JWT was issued.
To improve the user experience of Shared Dreams ("Group Dreams"), the following additional claims should be provided:
given_name
: Given name(s) or first name(s) of the End User.family_name
: Surname(s) or last name(s) of the End-User. To limit data exposure, it's enough to give away the first letter of the family name.
DES expects asymmetric token signatures, with a public key set exposed at a public JWKS endpoint. This endpoint is is configurable in DEPo.
Using this mechanism, the above sequence diagram is expanded as follows:
- 3a: The public keys (a JSON Web Key Set) used to verify the token is exposed
at a configurable JWKS endpoint hosted by you.
If the token has a
kid
value the Impact Finance Backend hasn't seen before or its JWKS cache has expired (the cache expiration time is configurable in DEPo), it will call your JWKS endpoint to fetch new keys. This allows rotating the keys without disrupting service. - 3b: Using the public keys, the Impact Finance Backend can verify and decode ID tokens itself without consulting your Authorization server on each authentication request.
Authenticating with Opaque tokens validated by your backend
The Impact Finance App can also be configured to use opaque tokens, requiring a synchronous call to your Authorization Server for validation on each authentication request.
- 3a: On every authentication request, the Impact Finance Backend makes a call
to your
auth_verify_url
(configurable in DEPo) to validate the token. - 3b: If the Bank Authorization Server deems the token as valid, it responds
with status code
200 OK
and a JSON response body like{ "user": { "id": <id> }}
, where<id>
is the end-user ID. - 3c: If the Bank Authorization Server deems the token as invalid, it can
respond with any
4xx Client Error
status code to fail the authentication.
To improve the user experience of
Shared Dreams ("Group Dreams"), the following additional
information should be provided by the auth_verify_url
endpoint:
given_name
: Given name(s) or first name(s) of the End User.family_name
: Surname(s) or last name(s) of the End-User. To limit data exposure, it's enough to give away the first letter of the family name.