This developer guide / walkthrough of CIDM is aimed specfically at web server based application developers. It is expected that the reader has a basic understanding of REST services, HTML and CSS. There are loads of useful guides and walkthroughs provided by auth0, it is worth searching their site to supplement this guide, try https://auth0.com/docs/quickstart/webapp and https://auth0.com/docs/quickstart/backend as a starting point.
If you are running a client-server web application and want to manage the customer athentication process from the server side then you have the option of using the 'authentication code flow' method (explained in detail here). This method does not utilize the profile widget and therefore requires your server to entirely manage the user session and login/logout state. It is simple to get working however will require additional coding / plugging into an existing security library of your choosing (e.g. in the case of Java, the Spring Security framework is a common choice). The steps are as follows:
The steps discussed in depth in the next sections.
You can use a library to create a sign-in link, for example there is a Java library here: https://auth0.com/docs/quickstart/webapp/java-spring-security-mvc/01-login. However if you can't find a suitable library for your server-side language then a link can be constructed manually.
The structure of a sign-in URL is as follows:
https://[auth-domain]/authorize?
client_id=[your-client-id]
&response_type=code
&audience=https://auth.staging-services.qld.gov.au
&scope=openid%20[Level_1 or Level_2]
&redirect_uri=[Your callback URL]
Here is a working example:
https://login.auth.staging-services.qld.gov.au/authorize?
client_id=8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7
&response_type=code
&audience=https://auth.staging-services.qld.gov.au
&scope=openid%20Level_1
&redirect_uri=https://servicesmadesimpler.govnet.qld.gov.au/qgcidm/demo/neo-server-side-auth/
Try it!
Have a look in the URL bar when you return (you should see a code in the response).
When users are successfully returned to your callback URL your webserver will have access to the 'code' querystring parameter. The code is not much use on its own, however it is an opaque string which enables server side retrieval of an OIDC conformant access token. The code should be collected and stored in memory for the next step.
In order to authenticate a user to CIDM Neo, you need an access token. Since you are getting the access token from the server side, it will last 2 hours. Getting an access token is a simple POST request to our authentication service as detailed below:
Endpoint: https://login.auth.staging-services.qld.gov.au/oauth/token
Header: Content-Type: application/json
Body:
{
"grant_type": "authorization_code",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code": "YOUR_AUTHORIZATION_CODE",
"redirect_uri": "https://YOUR_APP/callback" //The URL must match exactly the redirect_uri passed to /authorize
}
Example body:
{
"grant_type": "authorization_code",
"client_id": "8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7",
"client_secret": "di4dUO8Fwe**********7CWeq1O6",
"code": "AqPbbOoXvmTQIhVI",
"redirect_uri": "https://servicesmadesimpler.govnet.qld.gov.au/qgcidm/demo/neo-server-side-auth/"
}
Example 200 response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9EazVRekU0UkRJeVJUazNRekkwTWtJNU1rSkdNamxCTTBOQ016WXlRVVpETUVZeU5VUTRSQSJ9.eyJodHRwczovL2F1dGguc3RhZ2luZy1zZXJ2aWNlcy5xbGQuZ292LmF1L3Nlc3Npb25faWQiOiIwN2E3ZDg2MTlkYTI3ODUyZDAzNmVkMzRhNDRkNWY2MTM0ZTlmZmQzNjdhNjcyY2ZiNTEwZDUxZTY0Nzg4ZmM4IiwiaHR0cHM6Ly9hdXRoLnN0YWdpbmctc2VydmljZXMucWxkLmdvdi5hdS9wYXJ0bmVyIjoiR29vZ2xlIiwiaHR0cHM6Ly9hdXRoLnN0YWdpbmctc2VydmljZXMucWxkLmdvdi5hdS9wYXJ0bmVyX2tleSI6IjdmNjIzM2JmOWU3Y2Q1MWIzZWE3YTk5M2ZjOTBjMmEwNjcyYzM1Zjg3MzFlMGFhZDUyOTU2ZWMzMjkyNGRhYmFlYzk5YWFmM2UxMzk0YWNiMjk3YTFlN2ZjYTViY2I5ZTczMGRhZTgxZWZiYTVmY2IxMmI4ZjVkMmI3NmQ2NTI5ZDgyZGRjNDM3ZmNiMTc4MDliNjM5ZGY0MmYzN2EwMmQ0ZGUwNzczYjc0ZDRjN2IwMmJiYzZhYWJhMDZiNjExOWYxNmY5Y2I1MGMyNjAwYzIxYzY1OWJkOTQ4YTcxN2JiNDg1MzgyZGQ2ZTE3ZjZkYjFmMGQiLCJodHRwczovL2F1dGguc3RhZ2luZy1zZXJ2aWNlcy5xbGQuZ292LmF1L3FpZCI6ImY5MGNmNWEyLTJmZGQtNDEyNS05ODJmLWMzMmIxZDgyMmQyYSIsImh0dHBzOi8vYXV0aC5zdGFnaW5nLXNlcnZpY2VzLnFsZC5nb3YuYXUvbGFzdF9sb2dpbiI6IjIwMTgtMTEtMTFUMjM6NDk6MDcuMzc5WiIsImlzcyI6Imh0dHBzOi8vdWF0LnFsZC1nb3Ytc3RnLmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDExMTYwNzYyNjEzMTE0MzQxMDM2MSIsImF1ZCI6WyJodHRwczovL2F1dGguc3RhZ2luZy1zZXJ2aWNlcy5xbGQuZ292LmF1IiwiaHR0cHM6Ly91YXQucWxkLWdvdi1zdGcuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTU0MTk4NDA3OCwiZXhwIjoxNTQyMDcwNDc4LCJhenAiOiI4YXFJRlZGTnJocHdzOGR2M1c1QzNGQU5VTWZpcXpLNyIsInNjb3BlIjoib3BlbmlkIn0.L3rAwIi8UjsfrFlZTCy4Ge5yzwLkHubUyhNMdiC1cg1rmC-xf_mUYy8H0kfU8tAohVVUkSb5OGIDyWl6Uz2awhUeQGhMMNzEbhb_fEhDJET3Y0aFU7wmg1Nl7qphEeQ7AobObwCdmRgkM79rxRIEbvR97TKoBJTwTu2hrWDBwiFrbQFloqYhiEq5ZtjokULjUQeMTBdVCc2jtziIWXRF6MlB9dqcza3A6R64kt5O-6O56NrLwDrjMfPQ6nqTNwZbPAxzKoCFMmpn6qew9W271FT4seoBpx5tRRMu67pohIySyeED-3a7da4k1pNQx97Fg1s8bddNYiFbYsf51cpp9Q",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9EazVRekU0UkRJeVJUazNRekkwTWtJNU1rSkdNamxCTTBOQ016WXlRVVpETUVZeU5VUTRSQSJ9.eyJodHRwczovL2F1dGguc3RhZ2luZy1zZXJ2aWNlcy5xbGQuZ292LmF1L2VtYWlsIjoic3RldmVuLmJvd2RlbkBkc2l0aS5xbGQuZ292LmF1IiwiaHR0cHM6Ly9hdXRoLnN0YWdpbmctc2VydmljZXMucWxkLmdvdi5hdS9waWN0dXJlIjoiaHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tLy1qQUVmQzdqd21WMC9BQUFBQUFBQUFBSS9BQUFBQUFBQUFBQS9BQnRObGJCdWROeU8tcHBfV1RuZ2EtSzczcEwwTThRd3J3L21vL3Bob3RvLmpwZyIsImh0dHBzOi8vYXV0aC5zdGFnaW5nLXNlcnZpY2VzLnFsZC5nb3YuYXUvdXNlcl9pZCI6Imdvb2dsZS1vYXV0aDJ8MTExNjA3NjI2MTMxMTQzNDEwMzYxIiwiaHR0cHM6Ly9hdXRoLnN0YWdpbmctc2VydmljZXMucWxkLmdvdi5hdS9jbGllbnRJRCI6IjhhcUlGVkZOcmhwd3M4ZHYzVzVDM0ZBTlVNZmlxeks3IiwiaHR0cHM6Ly9hdXRoLnN0YWdpbmctc2VydmljZXMucWxkLmdvdi5hdS9hcHBfbWV0YWRhdGEiOnsicWlkIjoiZjkwY2Y1YTItMmZkZC00MTI1LTk4MmYtYzMyYjFkODIyZDJhIiwiZ2l2ZW5fbmFtZSI6ImM3NzRjOWM4ZjIxY2M4NjJiMzY4ODUyNjhmNjdkODUyNDM4N2E1NGEwYTgzNTMzNzZmODg4NjBlMmM5NzQzNzhkZTE1MzJmMjY2N2JlNWNkYmRiNTFiNjVjZTE2YzVmNmI5OThlMTE4NTI4NTZhNDZhMjRmYjA4YjMzYTRiYzRhYzc5MWY5YmI0MDcyMWU5NDRjNjRiZGU4ODA2Y2E5ZmM5YjRkOWYxYjNjYjA5NjZhZmU4YThhNTc4OGExZWVkZTM3ZjQiLCJmYW1pbHlfbmFtZSI6IjFhNTMzYjVlNDQ1N2M2NzIyZWMyNjViMDliODUwNDQ1ZTFkYjgwZWE2OWJjNDk3ZmQ4MDNhOWUxNzU2N2FjZDcwNDhmZWViZmFhNzlkM2JkMWY4MThiYTNjM2I3YTZmZWEyZDNiOTc0ZTg5M2YzMmRjMWE4ZjNiMjA4MGM0NDU4NWRhZDk0ZGZmZmJmOTRiM2Q3N2Q0OWZmMzc5MzViZDY1NzY1NmQ5ZWIyNGNmZmE2ZTliZjU1YThhNThkZDgzNDE3OTAiLCJuYW1lIjoiZDkwZTEzOTExOWU0ZThkYWZjZmQ4MDI1OTI1ODM0ZjM1ZDgyMjlmMWVjZGQ5YWE1OGFmMTI2MDMzZjRkY2NmNjVlN2ZmZTJlZWE4OTFlYzljYzVlZTAzYTM2MWRmNDdkMGRjN2I2N2IyMjkxYzNmM2QzZDAyNTkyMzBmYWJmYjY5N2ZmMjdiM2UwNWVhMjgyZWFlY2M4ZDEyNmNlOWNlMjZhNzU1YWI4OWNjMjAzOTNjZjY5MzcwOGVjOThkNWI4N2JlZGIwNDFmOWY4ODcwMmYwYjY3MGUzM2Y0NjcyMjQyMTUyMGJkMzc5NzA3ODQ5YWYxMSIsIm5pY2tuYW1lIjoiYmQ3MWEzNWIwNmQzOTg3NzY2ZDQwY2E1NGJmODI5NmNkNTkxNGYwM2FkNzY0NGRhZWFkODUxN2FkNDUzYTI0MDAwZjY0NTcxNTcyYzllMmVlZDg2MzEwZjE4YjU4ZDkwNTNkYWY4NjBjZGZiNGY5YjlmMWMwOTg2ZGZhODIyM2JlZTc2M2Q3NDZhY2M3MjQ3MDU4ZDY4NDY4ZGRlYmI3OWViNTIzYTcyNzU0MzY0NzRmMzdhYjlhMWExNTM0NzBhYTg5NzczZGMxZjg3ZjQxZGNiIiwiX2VuY3J5cHRlZCI6eyJnaXZlbl9uYW1lIjp0cnVlLCJmYW1pbHlfbmFtZSI6dHJ1ZSwibmFtZSI6dHJ1ZSwibmlja25hbWUiOnRydWV9LCJzZW5kX3dlbGNvbWVfZW1haWwiOmZhbHNlLCJxZ2FfZW1haWxfdmVyaWZpZWQiOnRydWUsInNvbWVfZmllbGQiOiJZIiwicHJldmlvdXNfbG9naW4iOiIyMDE4LTExLTExVDIzOjQ5OjA3LjM3OVoiLCJzY29wZSI6Im9wZW5pZCBMZXZlbF8xIn0sImlzcyI6Imh0dHBzOi8vdWF0LnFsZC1nb3Ytc3RnLmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDExMTYwNzYyNjEzMTE0MzQxMDM2MSIsImF1ZCI6IjhhcUlGVkZOcmhwd3M4ZHYzVzVDM0ZBTlVNZmlxeks3IiwiaWF0IjoxNTQxOTg0MDc4LCJleHAiOjE1NDE5OTEyNzh9.tGOhmcFpgicpMuI82WLJA7HsAZJrqQBRCnkwB64KBvqc8c3Pb_zDRC_LHXWifVZwyickM7eo2Rv3sG4laUMGJlkBPlccnbHI0kAejhHUILpaYTSRVhqWak-wu9qkLNCP0_gzhiyrmbwMc3hU4gbB0OWUWDdiCh5oSTcGVVusEbmogLeW3p3S5LUBZP1JJKnZDr2qyjA2WqIoHUL1hgSYtJHqw-OdWasH-GlaRd6zPxqiqIWa7qchKpzUXGCFFBKXWvqVtW8_GTMcFDHfJ5hR2_N5Y-6VbuPJy7O-aZlRfTIpZVkIYd3DBRFCR75qcvYcepnzs-b8SamgeN394Unrxg",
"scope": "openid",
"expires_in": 86400,
"token_type": "Bearer"
}
Example 4** response:
{
"error": "invalid_grant",
"error_description": "Invalid authorization code"
}
The tokens returned via the authentication code flow are JWTs and conform to Open ID Connect standards. There is no need to validate these tokens since they are retrieved directly from the authentication service. You can decode the ID token (JWT anatomy info at jwt.io) and retrieve any necessary values. You can attach the access token to your http session management and security framework. There are plenty of libraries out there which can facilitate this process and auth0 provides numerous quickstart guides at https://auth0.com/docs/quickstart/backend.
If you require a level 2 identity then you must check the customer's identity level using the token that was returned to the service. This has been made simple via the customer identity API.
Call the staging version of the Customer Identity API using the following configurations:
https://api.auth.staging-services.qld.gov.au/v1/customer_identity
HTTP GET
authorization : {Customers JWT Token}
x-api-key (this is only for testing, won't work in production) : DN3x8j0F5b8hxfBakq9h33pkcVuo47FH7qH4eaXY
None
A successful request (200) will return a JSON formatted response. Anything other than 200 indicates a failure in authentication (typically 4xx) or service availability issue (typically 5xx)
{
"qid" : "f90cf5a2-2fdd-4125-982f-c32b1d822d2a",
"AAL" : {
"AAL" : "1",
"IAAL" : "1",
"IRAL" : "2"
},
"share_always" : true
}
Inspect the response and if the AAL value is not 2 then commence the orchestration flow (see next Section)
CIDM Neo provides an orchestrated workflow for taking a customer with a Level 1 starting point, progressing them through relevant steps and returning them as a Level 2 identity along with the customers' sharing preference authorization. If the customer doesn't complete the required steps then they are returned without having their details upgraded to AAL2.
Commence the orchestration flow using the following configurations:
https://admin.auth.staging-services.qld.gov.au/profile/control
HTTP GET
No headers
level={level}&returnTo={serviceURL}&clientID={clientID}&service_name={serviceName}&authoritative_attributes={authAttribs}&self_asserted_attributes={selfAttribs}
e.g. level=Level_2&returnTo=https://servicesmadesimpler.govnet.qld.gov.au/qgcidm/demo/neo-server-side-auth&clientID=8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7&service_name=Not%20Specified&authoritative_attributes=QID,Email,AAL,IAAL,IRAL,GivenName,FamilyName,MiddleName&self_asserted_attributes=Picture
#token={token}
e.g. #token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik9EazVRekU0UkRJeVJUazNRekkwTWtJNU1rSkdNamxCTTBOQ016WXlRVVpETUVZeU5VUTRSQSJ9.eyJodHRwczovL2F1dGguc3RhZ2luZy1zZXJ2aWNlcy5xbGQuZ292LmF1L3Nlc3Npb25faWQiOiIwN2E3ZDg2MTlkYTI3ODUyZDAzNmVkMzRhNDRkNWY2MTM0ZTlmZmQzNjdhNjcyY2ZiNTEwZDUxZTY0Nzg4ZmM4IiwiaHR0cHM6Ly9hdXRoLnN0YWdpbmctc2VydmljZXMucWxkLmdvdi5hdS9wYXJ0bmVyIjoiR29vZ2xlIiwiaHR0cHM6Ly9hdXRoLnN0YWdpbmctc2VydmljZXMucWxkLmdvdi5hdS9wYXJ0bmVyX2tleSI6IjdmNjIzM2JmOWU3Y2Q1MWIzZWE3YTk5M2ZjOTBjMmEwNjcyYzM1Zjg3MzFlMGFhZDUyOTU2ZWMzMjkyNGRhYmFlYzk5YWFmM2UxMzk0YWNiMjk3YTFlN2ZjYTViY2I5ZTczMGRhZTgxZWZiYTVmY2IxMmI4ZjVkMmI3NmQ2NTI5ZDgyZGRjNDM3ZmNiMTc4MDliNjM5ZGY0MmYzN2EwMmQ0ZGUwNzczYjc0ZDRjN2IwMmJiYzZhYWJhMDZiNjExOWYxNmY5Y2I1MGMyNjAwYzIxYzY1OWJkOTQ4YTcxN2JiNDg1MzgyZGQ2ZTE3ZjZkYjFmMGQiLCJodHRwczovL2F1dGguc3RhZ2luZy1zZXJ2aWNlcy5xbGQuZ292LmF1L3FpZCI6ImY5MGNmNWEyLTJmZGQtNDEyNS05ODJmLWMzMmIxZDgyMmQyYSIsImh0dHBzOi8vYXV0aC5zdGFnaW5nLXNlcnZpY2VzLnFsZC5nb3YuYXUvbGFzdF9sb2dpbiI6IjIwMTgtMTEtMTFUMjM6NDk6MDcuMzc5WiIsImlzcyI6Imh0dHBzOi8vdWF0LnFsZC1nb3Ytc3RnLmF1dGgwLmNvbS8iLCJzdWIiOiJnb29nbGUtb2F1dGgyfDExMTYwNzYyNjEzMTE0MzQxMDM2MSIsImF1ZCI6WyJodHRwczovL2F1dGguc3RhZ2luZy1zZXJ2aWNlcy5xbGQuZ292LmF1IiwiaHR0cHM6Ly91YXQucWxkLWdvdi1zdGcuYXV0aDAuY29tL3VzZXJpbmZvIl0sImlhdCI6MTU0MTk4NDA3OCwiZXhwIjoxNTQyMDcwNDc4LCJhenAiOiI4YXFJRlZGTnJocHdzOGR2M1c1QzNGQU5VTWZpcXpLNyIsInNjb3BlIjoib3BlbmlkIn0.L3rAwIi8UjsfrFlZTCy4Ge5yzwLkHubUyhNMdiC1cg1rmC-xf_mUYy8H0kfU8tAohVVUkSb5OGIDyWl6Uz2awhUeQGhMMNzEbhb_fEhDJET3Y0aFU7wmg1Nl7qphEeQ7AobObwCdmRgkM79rxRIEbvR97TKoBJTwTu2hrWDBwiFrbQFloqYhiEq5ZtjokULjUQeMTBdVCc2jtziIWXRF6MlB9dqcza3A6R64kt5O-6O56NrLwDrjMfPQ6nqTNwZbPAxzKoCFMmpn6qew9W271FT4seoBpx5tRRMu67pohIySyeED-3a7da4k1pNQx97Fg1s8bddNYiFbYsf51cpp9Q
If you diden't specify a POST returnMethod then the orchestration flow will return to the specified 'returnTo' url with the following parameters:
Have a look in the URL bar when you return (you should see the response in the URL string).
In the browser, the $.qgcidm object looks after calling the Customer Attributes API, however if you are verifying a JWT on your server-side then you will need to make a request to the Customer Attributes API directly.
If you are requiring level 2 authentication then you should be checking the customer's identity levels before proceeding using the method descriibed above. Also, if you are requiring specific attributes that the customer has not provided an 'always share' authorization then you will need to include the release token that you retrieve at the end of the orchestration flow.
This is a REST based API which is aimed to be simple, multi-purposed and compatible with future identity and attribute release frameworks. It handles JWT verification and attribute release in the one API call. Currently it only supports the attributes attached to a CIDM identity and will be expanded upon in 2019. You can call the Customer Attributes API using a simple GET request from whichever server-side HTTP request library of your choosing.
Call the test version Customer Attributes API using the following configurations:
https://api.auth.staging-services.qld.gov.au/v1/customer_attributes
HTTP GET
authorization : {Customers JWT Token}
AttributeReleaseToken (if returned from the orchestration flow with 'shareAlways=false' then use this to access the specific attributes) : {releaseToken}
x-api-key (this is only for testing, won't work in production) : DN3x8j0F5b8hxfBakq9h33pkcVuo47FH7qH4eaXY
authoritative_attributes=QID,DateOfBirth,Email,UserId,AuthenticationMethod,GivenName,FamilyName&self_asserted_attributes=Name,Picture,GivenName,FamilyName&sign=false
A successful request (200) will return a JSON formatted response. Anything other than 200 indicates a failure in authentication (typically 4xx) or service availability issue (typically 5xx)
Specific documentation will be produced to cover the details of the Custommer Attributes API, in the meantime please refer to the Swagger API definition below for more details:
swagger: '2.0'
info:
version: '2017-11-06T11:38:32Z'
title: CIDM NEO Customer Attributes API
description: >
The Customer Attributes API supports the retrieval of both Verified and
Unverified Customer Attributes
## Version History:
* 0.1 Initial Draft of Customer Attributes API.
* 0.2 Updated to have a POST and a GET for Customer Attributes. The GET
being a less complex API/request.
* 0.3 Removed QID from Urls as they're not available in the JWT
* 0.4 Renamed resources to customer_shared and customer_attributes
* 0.5 Add admin APIS
* 0.6 Add MigrateIdentityDetail and correct typos
* 0.7 Change VerifyEOIRequest model to include "claimed" attributes
* 0.8 Change to query parameters for admin/identities request
* 0.9 Add claimed attributes to VerifyEOIRequest
* 0.10 Update EventNotification structure
* 0.11 Changed "forumla" to "formula". Added "customer_identity/close"
* 0.12 Changed to use DELETE /admin/identities instead of the
/customer_identity/close
* 0.13 Changed /admin/identitites PUT to return QID
* 0.14 Added event_level enum to EventNotification, extra value to
event_status, extra structure to message, referer and user_agent
* 0.15 Add admin endpoint to return attribute metadata for requested
attributes
* 0.19 Add /admin/identities GET to retrieve all accounts for a given QID.
Add /admin/identities DELETE to delete linked identity
* 0.20 Add warning array to attribute responses to allow return of issues
with attributes in request
* 0.21 Add identity_status to MigrateIdentityResponse for flagging if an identity has been created or updated in create/update.
## Security:
1. Requires AWS API Gateway Key in the x-api-key header
2. Requires Auth0 User JWT in the Authorization header
## Usage:
### Accounts and Identities
An Account relates to the Authentication provider a User has logged in with.
e.g. Google, Microsoft, QGOV.
An Identity is where all attributes are attached to.
An Account will only have one Identity, however with Account Linking an
Identity may have more than one Account.
### Customer Sharing Preferences
#### Request:
```
export
CUSTOMER_JWT=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2Rldi5xbGQtZ292LWRldi5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMDU1MTcyMjA0MzQ1NjM4MDY1NTkiLCJhdWQiOiJLdTFseE1rQlFXY0NETHF1Q1BDNXpvc1cxdmhSTWtvWiIsImV4cCI6MTUxMDYyMTEzNiwiaWF0IjoxNTEwNjEzOTM2fQ.Kt7ifNQlA9IlUoncFRmaGsE5Gx1f8i87ukwl7QdQvRw
export API_KEY=cc2f0cbd-be66-431f-8b86-2f8d5ea30625
curl -v -H "Content-Type: application/json" -H "Accept: application/json" -H
"x-api-key: ${API_KEY}" -H "Authorization: Bearer ${CUSTOMER_JWT}"
https://api-customer-attributes.identity.test-services.qld.gov.au/v1/customer_shared
```
#### Response:
```JSON
{
"share" : "NOT_ALWAYS"
}
```
### Customer Attributes
#### Request:
```
export
CUSTOMER_JWT=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2Rldi5xbGQtZ292LWRldi5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMDU1MTcyMjA0MzQ1NjM4MDY1NTkiLCJhdWQiOiJLdTFseE1rQlFXY0NETHF1Q1BDNXpvc1cxdmhSTWtvWiIsImV4cCI6MTUxMDYyMTEzNiwiaWF0IjoxNTEwNjEzOTM2fQ.Kt7ifNQlA9IlUoncFRmaGsE5Gx1f8i87ukwl7QdQvRw
export API_KEY=cc2f0cbd-be66-431f-8b86-2f8d5ea30625
curl -v -H "Content-Type: application/json" -H "Accept: application/json" -H
"x-api-key: ${API_KEY}" -H "Authorization: Bearer ${CUSTOMER_JWT}"
https://api-customer-attributes.identity.test-services.qld.gov.au/v1/customer_attributes?authoritative_attributes=QID,DateOfBirth,Email&self_asserted_attributes=Name,UserId,AuthenticationMethod,Picture,FirstName,FamilyName,Nickname&sign=true
#Note the below won't actually work on the command line as it's over
multiple lines.
#Actual request value needs to be a URL encoded string of the JSON object.
i.e. JSON.stringify(ATTRIBUTES);
export ATTRIBUTES = "\
{
"attributes": [
{
"name": "GivenName",
"definition": {
"pedigree": "SELF_ASSERTED",
"signed": true,
}
},
{
"name": "FamilyName",
"definition": {
"pedigree": "AUTHORITATIVE",
"signed": true,
}
},
{
"name" : "Senior",
"definition": {
"source": "FORMULA",
"formula" : "Age >= 65"
}
}
]
}"
curl -v -H "Content-Type: application/json" -H "Accept: application/json" -H
"x-api-key: ${API_KEY}" -H "Authorization: Bearer ${CUSTOMER_JWT}"
https://api-customer-attributes.identity.test-services.qld.gov.au/v1/customer_attributes?attributes=${ATTRIBUTES}
```
#### Response:
```JSON
{
"attributes" : [
{
"name" : "GivenName",
"value": "Jeremy",
"metadata" : [
{
"name": "pedigree",
"value": "SELF_ASSERTED"
}
],
"definition": {
"source": "ATTRIBUTE",
"pedigree": "SELF_ASSERTED",
"signed": true,
}
},
{
"name" : "FamilyName",
"value": "Ford",
"metadata" : [
{
"name": "pedigree",
"value": "AUTHORITATIVE"
}
],
"definition": {
"source": "ATTRIBUTE",,
"pedigree": "AUTHORITATIVE",
"signed": true,
}
},
{
"name" : "Senior",
"value": "false",
"metadata" : [
{
"name": "pedigree",
"value": "AUTHORITATIVE"
}
],
"definition": {
"source": "FORMULA",
"signed": false,
"formula" : "Age >= 65"
}
}
],
"signed_attributes" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2Rldi5xbGQtZ292LWRldi5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMDU1MTcyMjA0MzQ1NjM4MDY1NTkiLCJhdWQiOiJLdTFseE1rQlFXY0NETHF1Q1BDNXpvc1cxdmhSTWtvWiIsImV4cCI6MTUxMDYyMTEzNiwiaWF0IjoxNTEwNjEzOTM2fQ.Kt7ifNQlA9IlUoncFRmaGsE5Gx1f8i87ukwl7QdQvRw"
}
```
### Verify Customer Attributes
#### Request:
```
export
SIGNED_ATTRIBUTES_JWT=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2Rldi5xbGQtZ292LWRldi5hdXRoMC5jb20vIiwic3ViIjoiZ29vZ2xlLW9hdXRoMnwxMDU1MTcyMjA0MzQ1NjM4MDY1NTkiLCJhdWQiOiJLdTFseE1rQlFXY0NETHF1Q1BDNXpvc1cxdmhSTWtvWiIsImV4cCI6MTUxMDYyMTEzNiwiaWF0IjoxNTEwNjEzOTM2fQ.Kt7ifNQlA9IlUoncFRmaGsE5Gx1f8i87ukwl7QdQvRw
export API_KEY=cc2f0cbd-be66-431f-8b86-2f8d5ea30625
curl -v -H "Content-Type: application/json" -H "Accept: application/json" -H
"x-api-key: ${API_KEY}" -d '{"signed_attributes"
:"${SIGNED_ATTRIBUTES_JWT}"}'
https://api-customer-attributes.identity.test-services.qld.gov.au/v1/verify_customer_attributes
```
#### Response:
```JSON
{
"attributes" : [
{
"name" : "GivenName",
"value": "Jeremy",
"metadata" : [
{
"name": "pedigree",
"value": "AUTHORITATIVE"
}
],
"definition": {
"source": "ATTRIBUTE",
"pedigree": "AUTHORITATIVE",
"signed": true,
}
},
{
"name" : "FamilyName",
"value": "Ford",
"metadata" : [
{
"name": "pedigree",
"value": "AUTHORITATIVE"
}
],
"definition": {
"source": "ATTRIBUTE",,
"pedigree": "AUTHORITATIVE",
"signed": true,
}
}
}
```
host: api.auth.services.qld.gov.au
basePath: /v1
schemes:
- https
paths:
/customer_events:
get:
summary: Retrieves usage for the authenticated user based on the given criteria
description: >
Retrieves the Events of the nominated type for the authenticated user.
Supports view usage
produces:
- application/json
parameters:
- name: event_categories
type: string
in: query
description: Comma separated list of event_categories to include.
- name: event_types
type: string
in: query
description: Comma separated list of event_types to include
required: false
- name: date_from
type: string
format: date-time
in: query
description: Earliest event date to query
required: false
- name: date_to
type: string
format: date-time
in: query
description: Latest event date to query
required: false
- $ref: '#/parameters/page_offset'
- $ref: '#/parameters/page_limit'
responses:
'200':
description: HTTP 200 Success Response.
schema:
$ref: '#/definitions/EventSummaryResponse'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'400':
description: >-
Bad request. Either event_type was not supplied, or one or more
query parameters were an invalid format. Do not attempt the request
until the input has been fixed
schema:
$ref: '#/definitions/ValidationError'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'401':
description: >-
Unauthorized request. Missing, Invalid, or Expired credentials
provided
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'404':
description: The specified Event Type was not found
schema:
$ref: '#/definitions/Error'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'500':
description: Unknown Server Error.
schema:
$ref: '#/definitions/Error'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
security:
- api_key: []
- auth0JWTAuthorizer: []
x-amazon-apigateway-request-validator: params-only
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Origin: '''*'''
requestParameters:
integration.request.header.Accept-Encoding: '''utf8'''
uri: 'http://{{ InternalUri }}/rest/customer_events'
passthroughBehavior: when_no_match
httpMethod: GET
contentHandling: CONVERT_TO_TEXT
connectionType: VPC_LINK
connectionId: '{{ VpcLinkId }}'
type: http_proxy
/customer_identity:
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Methods: '''DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'''
method.response.header.Access-Control-Allow-Headers: >-
'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'
method.response.header.Access-Control-Allow-Origin: '''*'''
requestTemplates:
application/json: '{"statusCode": 200}'
passthroughBehavior: when_no_match
type: mock
get:
summary: Retrieves core Session based Identity Authentication details
description: >
Retrieves core Session based Identity Authentication details. Allows
callers to determine if StepUp, EOI, or SharingPreferences is required
prior to retrieving Attributes
produces:
- application/json
responses:
'200':
description: HTTP 200 Success Response.
schema:
$ref: '#/definitions/CustomerIdentitySession'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'401':
description: >-
Unauthorized request. Missing, Invalid, or Expired credentials
provided
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'500':
description: Unknown Server Error.
schema:
$ref: '#/definitions/Error'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
security:
- api_key: []
- auth0JWTAuthorizer: []
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Origin: '''*'''
requestParameters:
integration.request.header.Accept-Encoding: '''utf8'''
uri: 'http://{{ InternalUri }}/rest/customer_identity'
passthroughBehavior: when_no_match
httpMethod: GET
contentHandling: CONVERT_TO_TEXT
connectionType: VPC_LINK
connectionId: '{{ VpcLinkId }}'
type: http_proxy
/customer_attributes:
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Methods: '''DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'''
method.response.header.Access-Control-Allow-Headers: >-
'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'
method.response.header.Access-Control-Allow-Origin: '''*'''
requestTemplates:
application/json: '{"statusCode": 200}'
passthroughBehavior: when_no_match
type: mock
get:
produces:
- application/json
parameters:
- name: authoritative_attributes
in: query
description: >-
Comma separated list of Attribute Names that are required at an
AUTHORITATIVE pedigree
required: false
type: string
- name: self_asserted_attributes
in: query
description: >-
Comma separated list of Attribute Names that are required at, at
least, a SELF_ASSERTED pedigree
required: false
type: string
- name: sign
in: query
description: Boolean flag to indicate if all attributes should be signed
required: false
type: string
responses:
'200':
description: HTTP 200 Success Response.
schema:
$ref: '#/definitions/CustomerAttributesResponse'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'204':
description: No Content. None of the requested Attributes had a value.
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'400':
description: >-
Bad request. No Attributes requested, or at least one invalid
Attribute or Formula was provided. Do not attempt the request until
the input has been fixed
schema:
$ref: '#/definitions/ValidationError'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'401':
description: >-
Unauthorized request. Missing, Invalid, or Expired credentials
provided
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'500':
description: Unknown Server Error.
schema:
$ref: '#/definitions/Error'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
security:
- api_key: []
- auth0JWTAuthorizer: []
x-amazon-apigateway-request-validator: params-only
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Origin: '''*'''
requestParameters:
integration.request.header.Accept-Encoding: '''utf8'''
uri: 'http://{{ InternalUri }}/rest/customer_attributes'
passthroughBehavior: when_no_match
httpMethod: GET
contentHandling: CONVERT_TO_TEXT
connectionType: VPC_LINK
connectionId: '{{ VpcLinkId }}'
type: http_proxy
post:
produces:
- application/json
parameters:
- name: attributes
in: body
description: Attributes to Retrieve
schema:
type: object
items:
$ref: '#/definitions/CustomerAttributesRequest'
responses:
'200':
description: HTTP 200 Success Response.
schema:
$ref: '#/definitions/CustomerAttributesResponse'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'204':
description: No Content. None of the requested Attributes had a value.
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'400':
description: >-
Bad request. No Attributes requested, or at least one invalid
Attribute or Formula was provided. Do not attempt the request until
the input has been fixed
schema:
$ref: '#/definitions/ValidationError'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'401':
description: >-
Unauthorized request. Missing, Invalid, or Expired credentials
provided
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'500':
description: Unknown Server Error.
schema:
$ref: '#/definitions/Error'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
security:
- api_key: []
- auth0JWTAuthorizer: []
x-amazon-apigateway-request-validator: body-only
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Origin: '''*'''
requestParameters:
integration.request.header.Accept-Encoding: '''utf8'''
uri: 'http://{{ InternalUri }}/rest/customer_attributes'
passthroughBehavior: when_no_match
httpMethod: POST
contentHandling: CONVERT_TO_TEXT
connectionType: VPC_LINK
connectionId: '{{ VpcLinkId }}'
type: http_proxy
/verify_customer_attributes:
options:
consumes:
- application/json
produces:
- application/json
responses:
'200':
description: 200 response
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Methods: '''DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'''
method.response.header.Access-Control-Allow-Headers: >-
'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'
method.response.header.Access-Control-Allow-Origin: '''*'''
requestTemplates:
application/json: '{"statusCode": 200}'
passthroughBehavior: when_no_match
type: mock
post:
produces:
- application/json
parameters:
- name: signed_attributes
in: body
description: Signed Attributes to verify
schema:
type: object
items:
$ref: '#/definitions/VerifyAttributesRequest'
responses:
'200':
description: HTTP 200 Success Response.
schema:
$ref: '#/definitions/VerifyAttributesResponse'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'400':
description: Bad request. Invalid request payload
schema:
$ref: '#/definitions/ValidationError'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'401':
description: >-
Unauthorized request. Provided signed_attributes value has been
tampered with and must not be trusted
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
'500':
description: Unknown Server Error.
schema:
$ref: '#/definitions/Error'
headers:
Content-Type:
type: string
Access-Control-Allow-Origin:
type: string
security:
- api_key: []
x-amazon-apigateway-request-validator: body-only
x-amazon-apigateway-integration:
responses:
default:
statusCode: '200'
responseParameters:
method.response.header.Access-Control-Allow-Origin: '''*'''
requestParameters:
integration.request.header.Accept-Encoding: '''utf8'''
uri: 'http://{{ InternalUri }}/rest/verify_customer_attributes'
passthroughBehavior: when_no_match
httpMethod: POST
contentHandling: CONVERT_TO_TEXT
connectionType: VPC_LINK
connectionId: '{{ VpcLinkId }}'
type: http_proxy
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
auth0JWTAuthorizer:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: custom
x-amazon-apigateway-authorizer:
authorizerUri: >-
arn:aws:apigateway:{{ Region
}}:lambda:path/2015-03-31/functions/arn:aws:lambda:{{ Region }}:{{
AwsAccount }}:function:{{ Product}}AuthorizationLambda/invocations
authorizerResultTtlInSeconds: 300
type: token
auth0ServiceJWTAuthorizer:
type: apiKey
name: Authorization
in: header
x-amazon-apigateway-authtype: custom
x-amazon-apigateway-authorizer:
authorizerUri: >-
arn:aws:apigateway:{{ Region
}}:lambda:path/2015-03-31/functions/arn:aws:lambda:{{ Region }}:{{
AwsAccount }}:function:{{
Product}}ServiceAuthorizationLambda/invocations
authorizerResultTtlInSeconds: 300
type: token
x-amazon-apigateway-gateway-responses:
DEFAULT_5XX:
responseTemplates:
application/json: |
{
"code" : "401",
"message" : "Unauthorized",
"description" : "Unauthorized"
}
responseParameters:
gatewayresponse.header.Access-Control-Allow-Methods: '''GET,OPTIONS'''
gatewayresponse.header.Access-Control-Allow-Origin: '''*'''
gatewayresponse.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
BAD_REQUEST_PARAMETERS:
statusCode: 400
responseTemplates:
application/json: |
{
"code" : "400",
"message" : "Invalid Request Parameters",
"description" : "Invalid input",
"validation_failures" : [
{
"property" : "request",
"failure_reason" : "$context.error.message"
} , {
"property" : "params",
"failure_reason" : "$context.error.validationErrorString"
}
]
}
responseParameters:
gatewayresponse.header.Access-Control-Allow-Methods: '''GET,OPTIONS'''
gatewayresponse.header.Access-Control-Allow-Origin: '''*'''
gatewayresponse.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
BAD_REQUEST_BODY:
statusCode: 400
responseTemplates:
application/json: |
{
"code" : "400",
"message" : "Invalid JSON or Payload content",
"description" : "Invalid input",
"validation_failures" : [
{
"property" : "request",
"failure_reason" : "$context.error.message"
} , {
"property" : "body",
"failure_reason" : "$context.error.validationErrorString"
}
]
}
responseParameters:
gatewayresponse.header.Access-Control-Allow-Methods: '''GET,OPTIONS'''
gatewayresponse.header.Access-Control-Allow-Origin: '''*'''
gatewayresponse.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
INVALID_API_KEY:
statusCode: 401
responseTemplates:
application/json: |
{
"code" : "401",
"message" : "Invalid API KEY",
"description" : "Unauthorized"
}
responseParameters:
gatewayresponse.header.Access-Control-Allow-Methods: '''GET,OPTIONS'''
gatewayresponse.header.Access-Control-Allow-Origin: '''*'''
gatewayresponse.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
UNAUTHORIZED:
statusCode: 401
responseTemplates:
application/json: |
{
"code" : "401",
"message" : "Unauthorized",
"description" : "Unauthorized"
}
responseParameters:
gatewayresponse.header.Access-Control-Allow-Methods: '''GET,OPTIONS'''
gatewayresponse.header.Access-Control-Allow-Origin: '''*'''
gatewayresponse.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
ACCESS_DENIED:
statusCode: 403
responseTemplates:
application/json: |
{
"code" : "403",
"message" : "Forbidden",
"description" : "Forbidden"
}
responseParameters:
gatewayresponse.header.Access-Control-Allow-Methods: '''GET,OPTIONS'''
gatewayresponse.header.Access-Control-Allow-Origin: '''*'''
gatewayresponse.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
DEFAULT_4XX:
responseTemplates:
application/json: |
{
"code" : "4XX",
"message" : "$context.error.message",
"description" : "Client Error"
}
responseParameters:
gatewayresponse.header.Access-Control-Allow-Methods: '''GET,OPTIONS'''
gatewayresponse.header.Access-Control-Allow-Origin: '''*'''
gatewayresponse.header.Access-Control-Allow-Headers: '''Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'''
x-amazon-apigateway-request-validators:
params-only:
validateRequestParameters: true
validateRequestBody: false
body-only:
validateRequestParameters: false
validateRequestBody: true
body-and-params:
validateRequestParameters: true
validateRequestBody: true
parameters:
qid:
name: qid
in: query
type: string
description: Unqiue Customer Identifier
page_offset:
name: page_offset
in: query
description: Current page number
required: false
type: integer
format: int32
default: 0
minimum: 0
page_limit:
name: page_limit
in: query
description: Limits the number of returned items
required: false
type: integer
format: int32
default: 10
minimum: 10
maximum: 100
multipleOf: 10
definitions:
EventTypesResponse:
type: object
properties:
event_types:
type: array
items:
$ref: '#/definitions/EventType'
EventType:
type: object
properties:
name:
type: string
description: Name of the Event Type
version:
type: integer
format: int32
description: Version of the Event Type
EventNotification:
description: A representation of CIDM Neo event data for audit logging
type: object
required:
- timestamp
- event_id
- event_type
- event_source
- event_status
properties:
qid:
description: Queensland Government Identity
type: string
ga360_id:
description: >-
client id provided by Google Analytics, multiple can be passed in for
session unification purposes
type: array
items:
type: string
ip:
description: ipv4 or ipv6 address associated with customer
type: string
user_id:
description: Authentication service user Id value e.g. Auth0 user_id
type: string
cet_interaction_id:
description: >-
Customer Enquiry Tracking ID, if available, unique to the customer's
enquiry
type: string
service_group_id:
description: SIR service grouping ID
type: string
interaction_id:
description: SIR interaction ID
type: string
service_context:
description: SIR service context
type: string
cidm_neo_client_id:
description: Authentication service agency ID value e.g. Auth0 client_id
type: string
user_agent:
description: browser user agent
type: string
referer:
description: web URL of service generating event (if available)
type: string
origin:
description: web origin of service generating event (if available)
type: string
auth_session_id:
description: unique identifier for a customer's authenticated session
type: string
auth_details:
description: additional unmapped details from the auth0 logs
type: object
component_id:
description: OSSSIO Component ID as per Component Monitoring Framework
type: string
aws_arn:
description: Unique AWS infrastructure identifier
type: string
cidm_neo_env:
description: CIDM Neo system environment
type: string
relevant_version:
description: 'Version of API, function or application where the event occurred'
type: string
associated_release:
description: >-
Release associated with the version of API, function or application
where the event occurred
type: string
module_name:
description: Application module where the event occurred
type: string
class_name:
description: Java application class file name
type: string
function_name:
description: Function name where runtime event occurred
type: string
line_of_code:
description: Line number in the code to signify where the event occurred
type: number
journey_id:
description: Identifier for microservice tracing of an individual journey
type: string
segment_id:
description: >-
Identifier for microservice tracing of a segment within an individual
journey
type: string
external_event_id:
description: 'event ID generated by external system such as Auth0, lambda or GreenID'
type: string
journey_type:
description: >-
standardised name for a particular microservice flow, enums based on
BRS
type: string
enum:
- qgov_authentication
- create_qgov_sign_in
- prove_id
- sign_out
- qgov_forgotten_password
- qgov_change_username
- update_mobile
- change_name
- update_sharing_preference
- close_identity
- account_linking
segment_type:
description: >-
standardised name for a segment that occurs within microservice flows,
enums based on BRS
type: string
enum:
- validate_authentication_request
- provide_sign_in_options
- create_id_first_time_usage
- check_username_diff_credential_type
- sign_in_with_third_party_cred_provider
- provide_link_or_create_option
- link_sign_in_to_identity
- provide_auth_step_up_option
- request_eoi
- green_id_form
- process_eoi_response
- store_attributes_and_meta
- send_attribute_storage_notification
- check_sharing_preference
- provide_sharing_options
- process_sharing_choice
- send_authentication_response
- send_new_user_welcome_email
- provide_new_qgov_input_form
- validate_new_qgov_input_data
- verify_email_address
- store_new_qgov_sign_in
- sign_out_client_side
- provide_username_input_form
- validate_forgot_pw_input
- active_session_pw_change_request
- send_verification_code
- provide_verification_code_input
- check_verification_code
- provide_new_pw_input
- validate_new_pw
- store_new_pw
- send_pw_change_notification
- provide_change_username_input_form
- validate_change_username_input
- store_new_qgov_username
- active_session_change_mobile_request
- provide_update_mobile_input_form
- validate_update_mobile_input
- store_updated_mobile_number
- send_mobile_updated_notification
- active_session_change_name_request
- store_changed_name
- active_session_change_sharing_request
- provide_sharing_pref_input_form
- validate_sharing_pref_input
- store_updated_sharing_preference
- active_session_close_account_request
- provide_close_account_input_form
- deactivate_identity_and_sign_in_accounts
- send_identity_closure_notification
- active_session_link_accounts
- provide_link_account_input_form
- link_account_to_identity
- recalculate_credential_strength
- supply_evidence_of_linkage
- unlink_account_from_identity
component_action:
description: >-
standardised name for an action being performed by the OSSSIO
component where the event occurred
type: string
external_event_type:
description: event taxonomy inherited from external event log
type: string
event_id:
description: unique identifier for a single event
type: string
event_type:
description: standardised convention for categorising the type of event occurring
type: string
enum:
- id_created
- id_search_result
- mob_verified
- redirect_url_received
- attributes_stored
- mob_change_request
- ac_linked
- ac_unlinked
- id_closed
- greenid_request
- greenid_response
- eoi_doc_verified
- change_name_request
- request_username_change
- username_changed
- verification_code_sent
- verification_code_checked
- input_validated
- form_rendered
- username_conflict
- attribute_meta_store
- customer_notification_sent
- sharing_pref_checked
- email_verified
- ac_stored
- change_pw_requested
- ac_closed
- credential_strength_calculated
- twilio_request
- twilio_response
- attributes_request
- log_data_delivery
- database_backup
- identity_migrated
- eoi_doc_migrated
- error_page_shown
- database_write
- database_read
event_source:
description: Descriptive name of application or component generating the event
type: string
event_level:
description: Priority or relevance categories for use in filters
type: string
enum:
- TRACE
- INFO
- DEBUG
- WARN
- ERROR
- FATAL
event_status:
description: 'Success, fail or alert indicator of the event'
type: string
enum:
- success
- fail
- alert
timestamp:
description: >-
Current time stamp value when the event occurred or as close as
possible to the time
type: string
format: date-time
logged_time:
description: time stamp value when the event was logged
type: string
format: date-time
message:
description: >-
an object with a value and metadata field. value is the message of the
event, short form, metadata is an object containing further key pairs
of data considered relevant to the message
type: object
properties:
value:
description: a string containing the text of the message
type: string
metadata:
description: an object containing useful data relating to the message
type: object
message_verbose:
description: >-
an object with a value and metadata field. value is the message of the
event, long form, metadata is an object containing further key pairs
of data considered relevant to the message
type: object
properties:
value:
description: a string containing the text of the verbose message
type: string
metadata:
description: an object containing useful data relating to the verbose message
type: object
RecordEventResponse:
type: object
properties:
request_id:
type: string
description: Unique Identifer generated for the Event. For logging purposes.
ResumeVerificationResponse:
type: object
required:
- qid
- verification_id
- verification_token
properties:
qid:
type: string
description: the QID of the existing user
verification_id:
type: string
description: Verification Id to use in subsequent calls
verification_token:
type: string
description: Token to use for resuming an existing Verification Session
InitialiseVerificationRequest:
type: object
required:
- qid
- verification_id
- verification_token
properties:
qid:
type: string
description: the QID of the existing user
verification_id:
type: string
description: Verification ID to identify a new EOI request
verification_token:
type: string
description: Token to use for resuming an existing Verification Session
DocumentVerificationRequest:
type: object
required:
- qid
- verification_token
- document_identifier
properties:
qid:
type: string
description: the QID of the existing user
verification_token:
type: string
description: Token to use for resuming an existing Verification Session
document_identifier:
type: string
description: 'Document Identifer from the Provider (e.g. qldregodvs, passportdvs)'
document_verification_status:
type: string
description: Document Verification Status
enum:
- STARTED
- VERIFIED
- FAILED
- ABORTED
EOIVerificationResponse:
type: object
required:
- qid
- verification_token
properties:
qid:
type: string
description: the QID of the existing user
verification_status:
type: string
description: the Verification status
enum:
- INPROGRESS
- VERIFIED
- CANCELLED
VerifyEOIRequest:
type: object
required:
- qid
- verification_token
- attributes
properties:
qid:
type: string
description: the QID of the existing user
verification_token:
type: string
description: Token to use for resuming an existing Verification Session
attributes:
type: array
items:
$ref: '#/definitions/CustomerAttributeDetail'
AbortEOIRequest:
type: object
required:
- qid
- verification_token
- fail_reason
properties:
qid:
type: string
description: the QID of the existing user
verification_token:
type: string
description: Token to use for resuming an existing Verification Session
fail_reason:
type: string
description: Document Verification Status
enum:
- USER_CANCELLED
- PROVIDER_CANCELLED
- EOI_ATTEMPTS_EXCEEDED
CustomerSharingPreference:
type: object
required:
- share
properties:
share:
type: string
enum:
- ALWAYS
- NOT_ALWAYS
AccountSearchResponse:
type: object
required:
- accounts
properties:
accounts:
type: array
items:
$ref: '#/definitions/AccountSummary'
AccountSummary:
type: object
required:
- partner_id
- account_id
properties:
partner_id:
type: string
description: 'the Partner Identifier (e.g. Google, QGOV)'
qid:
type: string
description: the Identity QID this Account is linked to
email:
type: string
description: the Email address associated with this Account
account_id:
type: string
description: the Account Identifier for this Partner
mobile:
type: string
description: Identity Management Mobile number if it exists
IdentitySummary:
type: object
required:
- qid
properties:
qid:
type: string
description: the QID of the existing user
email:
type: string
description: Account Management Email if it exists
mobile:
type: string
description: Account Management Mobile number if it exists
created_timestamp:
type: string
format: date-time
description: When this identity was created
modified_timestamp:
type: string
format: date-time
description: When this identity was last modified
IdentityMobile:
type: object
required:
- mobile
properties:
mobile:
type: string
description: Mobile Phone number
AccountEmail:
type: object
required:
- email
properties:
email:
type: string
description: Email Address
verified:
type: boolean
default: false
description: Flag to indicate the Email address has been verified
IdentityDetail:
type: object
required:
- partner_id
- partner_key
- account_identifier
properties:
qid:
type: string
description: the QID of the existing user
partner_id:
type: string
description: The Id of the partner that the user logs in with
partner_key:
type: string
description: The key (eg. email address) that identifies the user with the partner
account_identifier:
type: string
description: Unique Account Identifier for this provider
account_email:
type: string
description: Email address associated with this Account
attributes:
type: array
items:
$ref: '#/definitions/CustomerAttributeDetail'
MigrateIdentityDetail:
type: object
required:
- qid
- partner_id
- partner_key
- account_identifier
- create_timestamp
- modified_timestamp
- share_always_flag
properties:
qid:
type: string
description: the QID of the existing user
partner_id:
type: string
description: The Id of the partner that the user logs in with
partner_key:
type: string
description: The key (eg. email address) that identifies the user with the partner
account_identifier:
type: string
description: Unique Account Identifier for this provider
account_email:
type: string
description: Email address associated with this Account
attributes:
type: array
items:
$ref: '#/definitions/CustomerAttributeDetail'
eoi_documents:
type: array
items:
$ref: '#/definitions/EOIDocument'
create_timestamp:
type: string
format: date-time
description: When this identity was created in Classic
modified_timestamp:
type: string
format: date-time
description: When this identity was last modified in Classic
share_always_flag:
type: boolean
default: false
description: Flag to indicate this preference was set in Classic
EOIDocument:
type: object
required:
- document_type_id
- verified_datetime
properties:
document_type_id:
type: string
description: Document identifier of document used to verify attributes
verified_datetime:
type: string
format: date-time
description: Timestamp of when document used to verify attributes
IdentitySteppedUpRequest:
type: object
required:
- access_token
- stepup_method
- stepup_data
properties:
access_token:
type: string
description: Current Authentication JWT to register as stepped up
stepup_method:
type: string
description: Method used to perform Stepup
enum:
- MOBILE
- EMAIL
- MFA
stepup_data:
type: string
description: >-
Input used to perform Stepup. e.g. Mobile number when stepup_method is
MOBILE
CustomerIdentitySession:
type: object
required:
- qid
- AAL
- share_always
properties:
qid:
type: string
description: QID of the Authenticated User
AAL:
$ref: '#/definitions/AuthenticationStrength'
share_always:
type: boolean
description: >-
Indicates if the User has chosen to always share their identity
attributes
AuthenticationStrength:
type: object
required:
- AAL
- IAAL
- IRAL
properties:
AAL:
type: string
description: >
Authentication Assurance Level indicates the level of confidence the
service provider has in the premise that the customer using a service
is in fact the customer registered to access the service.
IAAL:
type: string
description: >
Identity Authentication Assurance Level is the measure used for the
level of assurance provided by the authentication process which occurs
each time a service is used
IRAL:
type: string
description: >
Identity Registration Assurance Level ? the level of assurance of the
identity of the person that is desired. This level is achieved by
using an appropriate process to verify their real-world identity.
IdentityAttributeReleaseRequest:
type: object
required:
- access_token
- client
properties:
access_token:
type: string
description: Current Authenticated Users access_token JWT
client:
type: string
description: Identifier of the service requesting these attributes
share_always:
type: string
description: Flag to indicate the Users global sharing preference
enum:
- 'Y'
- 'N'
attributes_released:
type: array
description: Array of Attribute Names to be released
items:
type: string
AttributeReleaseResponse:
type: object
required:
- attribute_release_token
properties:
attribute_release_token:
type: string
description: >-
token that is required by the Customer Attributes API to release
attributes
MigrateIdentityResponse:
type: object
required:
- migration_status
- qid
- identity_status
properties:
migration_status:
type: string
enum:
- ACCEPTED
- COMPLETED
qid:
type: string
description: the QID that has been created / updated
identity_status:
type: string
enum:
- CREATED
- UPDATED
- CLOSED
access_warnings:
type: array
items:
$ref: '#/definitions/AttributeAccessDetail'
EventSummaryResponse:
type: object
required:
- qid
- event_type
- event_count
properties:
qid:
type: string
description: the QID of the existing user
event_type:
type: string
description: Event Type for this Summary
event_count:
type: number
description: Count of Events that matched the input query
last_event_date:
type: string
format: date-time
description: Date Time (UTC) of the last event
CustomerAttributeDefinition:
type: object
required:
- source
properties:
source:
type: string
description: Source of Attribute Value
enum:
- ATTRIBUTE
- FORMULA
default: ATTRIBUTE
pedigree:
type: string
enum:
- AUTHORITATIVE
- SELF_ASSERTED
default: SELF_ASSERTED
description: >-
Indicates the Attribute Pedigree. Can be either AUTHORITATIVE or
SELF_ASSERTED
signed:
type: boolean
default: false
description: True if the Attribute will be signed in the Response.
formula:
type: string
description: >-
Formula for calculating the Attribute Value (i.e. 'Age > 65') where
source is FORMULA
CustomerAttributeRequest:
type: object
required:
- name
properties:
name:
type: string
description: Name of the Attribute in the Response
definition:
$ref: '#/definitions/CustomerAttributeDefinition'
AttributeMetadata:
type: object
required:
- name
- value
properties:
name:
type: string
description: Name of the Metadata Attribute
value:
type: string
description: Value of the Metadata Attribute
CustomerAttributesRequest:
type: object
required:
- attributes
properties:
attributes:
type: array
items:
$ref: '#/definitions/CustomerAttributeRequest'
AttributesMetadataResponse:
type: object
required:
- release_required
- required_aal
- attribute_metadata
properties:
release_required:
type: boolean
description: >-
Flag indicating whether any one of the requested attributes require
release
required_aal:
type: string
description: The maximum AAL level required for the set of attributes requested
attribute_metadata:
type: array
items:
$ref: '#/definitions/AttributeAccessDetail'
AttributeAccessDetail:
type: object
required:
- name
- attribute_status
properties:
name:
type: string
description: Name of the Attribute requested
attribute_status:
type: string
enum:
- OK
- INVALID_NAME
- NOT_AVAILABLE
- EOI_REQUIRED
- STEP_UP_REQUIRED
- RELEASE_REQUIRED
- NOT_PERSISTABLE
default: OK
description: Flag indicating the status of the attribute
release_required:
type: boolean
description: >-
Flag indicating whether the attribute is shareable without explicit
release
required_aal:
type: string
description: >-
required AAL level that the user needs to have achieved to get this
attribute
CustomerAttributesResponse:
type: object
required:
- attributes
properties:
attributes:
type: array
items:
$ref: '#/definitions/CustomerAttributeDetail'
signed_attributes:
type: string
description: JWT containing a Payload with each signed Attribute at the top level
access_warnings:
type: array
items:
$ref: '#/definitions/AttributeAccessDetail'
CustomerAttributeDetail:
type: object
required:
- name
- attribute_type
- metadata
- definition
properties:
attribute_type:
type: string
enum:
- STRING
- DATE
- DATETIME
- BOOLEAN
- INTEGER
- NUMERIC
- BYTE
- ADDRESS
name:
type: string
description: Name of the Attribute in the Response
metadata:
type: array
items:
$ref: '#/definitions/AttributeMetadata'
definition:
$ref: '#/definitions/CustomerAttributeDefinition'
value:
type: string
description: Default String Value of the Attribute in the Response
boolean_value:
$ref: '#/definitions/BooleanAttributeValue'
date_value:
$ref: '#/definitions/DateAttributeValue'
datetime_value:
$ref: '#/definitions/DateTimeAttributeValue'
integer_value:
$ref: '#/definitions/IntegerAttributeValue'
numeric_value:
$ref: '#/definitions/NumericAttributeValue'
byte_value:
$ref: '#/definitions/ByteArrayAttributeValue'
address_value:
$ref: '#/definitions/AddressAttributeValue'
BooleanAttributeValue:
type: object
required:
- value
properties:
value:
type: boolean
DateTimeAttributeValue:
type: object
required:
- value
properties:
value:
type: string
format: date-time
DateAttributeValue:
type: object
required:
- value
properties:
value:
type: string
format: date
NumericAttributeValue:
type: object
required:
- value
properties:
value:
type: number
IntegerAttributeValue:
type: object
required:
- value
properties:
value:
type: integer
format: int32
ByteArrayAttributeValue:
type: object
required:
- value
properties:
value:
type: string
format: byte
AddressAttributeValue:
type: object
required:
- value
properties:
value:
$ref: '#/definitions/CustomerAddress'
VerifyAttributesRequest:
type: object
required:
- signed_attributes
properties:
signed_attributes:
type: string
description: JWT returned from the attributes request
VerifyAttributesResponse:
type: object
required:
- attributes
properties:
attributes:
type: array
items:
$ref: '#/definitions/CustomerAttributeDetail'
CustomerAddress:
type: object
required:
- address_line_1
- location
- state_code
- postcode
properties:
address_start_date:
type: string
format: date
address_end_date:
type: string
format: date
address_line_1:
type: string
description: This is the first line of the address.
maxLength: 50
address_line_2:
type: string
description: This is the second line of the address.
maxLength: 50
address_line_3:
type: string
description: This is the third line of the address.
maxLength: 50
lot_number:
type: string
location:
type: string
description: 'This is the location (suburb, locality name) of the address.'
maxLength: 46
state_code:
type: string
description: This is the State Code of the address. (e.g. 'QLD')
maxLength: 3
postcode:
type: string
country_code:
type: string
description: This is the two letter ISO 3166 Country Code (e.g. 'AU')
minLength: 2
maxLength: 2
latitude:
type: number
format: double
description: 'Latitude of the Locality, if available.'
longitude:
type: number
format: double
description: 'Longitude of the Locality, if available.'
HealthResponse:
type: object
properties:
status:
type: string
Error:
type: object
properties:
code:
type: string
message:
type: string
description:
type: string
link:
type: string
ValidationFailures:
type: object
properties:
property:
type: string
description: Property name
failure_reason:
type: string
description: Failure reason
ValidationError:
type: object
properties:
code:
type: string
message:
type: string
description:
type: string
link:
type: string
validation_failures:
type: array
items:
$ref: '#/definitions/ValidationFailures'
When using server-side only authentication, customers will not have access to the CIDM Neo profile widget. The CIDM Neo profile widget provides customers with a quick access to sharing preferences, linked accounts, mobile number maintenance and account closure features. To provide access to these services you can either direct customers to My Account or launch the relevant widgets from an acitive browser session.
The easiest way to ensure calls to maintenance features are successful is to embed the request inside a redundant call to the orchestration flow previously described. The reason for this is that the orchestration flow creates browser cookies that are needed accross the maintenance widgets, therefore embedding the call in the orchestration returnTo parameter will set the request up for success. A redundant call to orchestration will not require the user to step up, share data or do evidence of identity, it will simply generate the necessary cookies in the browswer to run the maintenance widgets. The following URL will produce a redundant call to orchestration:
https://admin.auth.staging-services.qld.gov.au/profile/control?level=Level_1&returnTo=[ADD THE URL ENCODED MAINTENANCE WIDGET REQUEST HERE]&clientID=8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7&service_name=Not%20Specified#token=[USER ACCESS TOKEN GOES HERE]
Use the following endpoints to launch the maintenance features and be sure to include your return URL so that the customer does not get lost.
This is accessed directly via an endpoint and query parameters.
Endpoint
https://admin.auth.staging-services.qld.gov.au/share/change-sharing-preferences
Query parameters
cancelUrl={url encoded string stating where the customer goes after cancellation during the flow}
e.g. cancelUrl=https%3A%2F%2Fservicesmadesimpler.govnet.qld.gov.au%2Fqgcidm%2Fdemo%2Fneo-server-side-auth
bk={url encoded string staing where the customer will be returned upon completion of the flow}
e.g. bk=https%3A%2F%2Fservicesmadesimpler.govnet.qld.gov.au%2Fqgcidm%2Fdemo%2Fneo-server-side-auth
service_name={url encoded string describing the service name}
e.g. service_name=Test-Harness
Example embedded in redundant orchestration request
https://admin.auth.staging-services.qld.gov.au/profile/control?level=Level_1&returnTo=https%3A%2F%2Fadmin.auth.staging-services.qld.gov.au%2Fshare%2Fchange-sharing-preferences%3FcancelUrl%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26bk%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26service_name%3DTest-Harness&clientID=8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7&service_name=Not%20Specified#token=[CUSTOMER TOKEN]
Try launching sharing preferences widget
This is accessed via a re-authentication flow, the actual Change Mobile endpoint is embedded in the redirect_uri parameter and won't work if accessed directly (i.e. without re-authentication)
Endpoint
https://admin.auth.staging-services.qld.gov.au/changemobile
bk=https%3A%2F%2Fservicesmadesimpler.govnet.qld.gov.au%2Fqgcidm%2Fdemo%2Fneo-server-side-auth & cancelUrl=https%3A%2F%2Fservicesmadesimpler.govnet.qld.gov.au%2Fqgcidm%2Fdemo%2Fneo-server-side-auth
Example embedded in redundant orchestration request
https://admin.auth.staging-services.qld.gov.au/profile/control?level=Level_1&returnTo=https%3A%2F%2Fadmin.auth.staging-services.qld.gov.au%2Fchangemobile%3FcancelUrl%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26bk%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26service_name%3DTest-Harness&clientID=8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7&service_name=Not%20Specified#token=[CUSTOMER TOKEN]
Try launching the change mobile widget
Endpoint
https://admin.auth.staging-services.qld.gov.au/link
Query Parameters
bk=https%3A%2F%2Fservicesmadesimpler.govnet.qld.gov.au%2Fqgcidm%2Fdemo%2Fneo-server-side-auth & cancelUrl=https%3A%2F%2Fservicesmadesimpler.govnet.qld.gov.au%2Fqgcidm%2Fdemo%2Fneo-server-side-auth
Example embedded in redundant orchestration request
https://admin.auth.staging-services.qld.gov.au/profile/control?level=Level_1&returnTo=https%3A%2F%2Fadmin.auth.staging-services.qld.gov.au%2Flink%3FcancelUrl%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26bk%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26service_name%3DTest-Harness&clientID=8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7&service_name=Not%20Specified#token=[CUSTOMER TOKEN]
Try launching the linked accounts widget
Endpoint
https://admin.auth.staging-services.qld.gov.au/close
Query parameters
cancelUrl={url encoded string stating where the customer goes after cancellation during the flow}
e.g. cancelUrl=https%3A%2F%2Fservicesmadesimpler.govnet.qld.gov.au%2Fqgcidm%2Fdemo%2Fneo-server-side-auth
bk={url encoded string staing where the customer will be returned upon completion of the flow}
e.g. bk=https%3A%2F%2Fadmin.auth.staging-services.qld.gov.au%2Fprofile%2Fsign-out%3FserviceURL%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth
Example embedded in redundant orchestration request
https://admin.auth.staging-services.qld.gov.au/profile/control?level=Level_1&returnTo=https%3A%2F%2Fadmin.auth.staging-services.qld.gov.au%2Fclose%3FcancelUrl%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26bk%3Dhttps%253A%252F%252Fservicesmadesimpler.govnet.qld.gov.au%252Fqgcidm%252Fdemo%252Fneo-server-side-auth%26service_name%3DTest-Harness&clientID=8aqIFVFNrhpws8dv3W5C3FANUMfiqzK7&service_name=Not%20Specified#token=[CUSTOMER TOKEN]
Try launching the close account widget