Remote Login API
The Neuron® publishes a Remote Login API that can be used by trusted remote systems that want to authenticate (or Multi-Factor Authenticate) their users by using digital identities managed by the federated Neuron® network.
While both the QuickLogin API and the Remote Login API request users with digital identities to perform a digital signature, the Remote Login API differs from the QuickLogin API in the following ways:
QuickLogin is initiated by the user, for instance by scanning a code and requesting a quick-login process to begin on a service, possibly remote service. The Remote Login API is initiated by the remote service that wants to authenticate a user, for instance, as part of multi-factor authentication (MFA) of their users.
QuickLogin can be implemented by any service, as the process is initiated by the users themselves. The Remote Login API can only be used by trusted services, with appropriate credentials and privileges.
Endpoint
To access the Remote Login API, use the /RemoteLogin resource on any Neuron in the federated network with which you have credentials and privileges to access the Remote Login API.
Agent API
The Remote Login API is not part of the Agent API, which is an API where remote entities can create identities themselves and act on the federated Neuron® network. Once such an identity has been created, they can use this identity to petition a signature from a remote party, referencing their Legal ID. This is done by using the QuickLogin Agent/Legal/PetitionSignature resource. It serves a similar purpose as the Remote Login, and allows the requesting identity to present themselves to the user using their own identity. The response will be different also, and the method to retrieve it. The response will be information about the digitial identity itself. The Remote Login API however, will generate a JWT token for the remote service, which can be used to identify the authenticated user.
Credentials
The remote service can authenticate itself to the Neuron® using either any of the WWW-Authenticate mechanisms available on the resource, a Bearer token issued by the broker, or Mutual TLS (mTLS), identifying the service using its domain certificate. The user to be authenticated must also have the appropriate privileges to be able to use the Remote Login API. Contact the administrator of the Neuron® to ensure you have the appropriate credentials and privileges necessary to access the API.
Domains
The Neuron® Network is federated. The remote system only needs to connect to a connected Neuron in the federated network, and can still authenticate users, regardless on what neurons the users are connected to. The interoperability across domains ensures that users can be authenticated properly.
Address Types
The Remote Login API can authenticate users based on different types of identifiers. The distinction is called Address Type:
The principal and recommended address type (Legal ID) is indicated by setting the
AddressTypeparameter toLegalId. This is the identifier of the Legal ID of the user, which will be used to sign the signature request, allowing the Neuron to return a Bearer token with information about the authenticated user. Care should be taken to update this identifier over time, as the user updates their Legal Identity.An alternative address type is indicated by setting the
AddressTypeparameter toJID, identifying the Jabber ID of the user instead of the user’s Legal ID. This method is not recommended, as it can be used to communicate with the user without first granting permission. It might also leak personal information about the user, without consent. But it can be used for development or testing purposes, or when the information is public.Note: When using the
JIDaddress type, the Neuron hosting the account must be of build2025-12-30or later.
Request Format
A request is made by POSTing a JSON Object (Content-Type application/json) to the /RemoteLogin resource. The contents of the payload may vary, depending on the options chosen. See the sections below for detailed information about the parameters available.
Response Methods
The Remote Login API supports multiple ways in which a login response can be delivered to the caller:
A delayed response is indicated by the
ResponseMethodparameter being set toDelayedResponse. In this case, the resource waits with responding to the request until the user has signed or rejected the signature request. Once that happens, a response is returned to the caller.This method is the simplest to implement, but may result in the connection being dropped or closed by intermediate proxies, firewalls, or load balancers. The request can also be left hanging, if the user ignores the request. The method should there fore only be used during initial development. It is indicated by the
ResponseMethodparameter being set toPoll.The caller can regularly poll the status of the request. Once the request is made, a
PetitionIdis returned immediately. ThisPetitionIdcan be used to poll the status of the request regularly.This method is relatively simple to implement, and does not require the remote system to be accessible on the Internet. But the polling interval affects the latency in the response being returned. It also adds needless load on the Neuron, as each polling request needs to be processed.
The Neuron can call the remote system back via a callback URL once a response is returned from the user. This method requires the remote system to be accessible on the Internet however. The mechanism is indicated by the
ResponseMethodparameter being set toCallback.This method is efficient, and results in low latency. But it requires the remote system to be accessible on the Internet. Use this method in production environments. Also consider using this method together with Mutual TLS (mTLS) authentication, in both directions, to ensure the authenticity of the parties involved.
All responses, regardless of method, will consist of a JSON object, using Internet Content-Type application/json.
The Neuron can send an asynchronous event over a WebSocket connection, when a response is ready. This method requires the remote system to maintain a WebSocket connection to the Neuron for the duration of the petition. The WebSocket in turn is identified using a
TabID. The Neuron maintains a collection of open Tabs, as long as sessions can be maintained (i.e. cookies are enabled). The WebSocket mechanism is indicated by theResponseMethodparameter being set toWebSocketEvent.This method is also efficient, and results in low latency. It does not require the caller to be accessible on the Internet. But it requires an additional WebSocket connection to be made and maintained. Use this method in production environments where low latency is critical, and where the caller is not accessible on the Internet.
Note: The Neuron® publishes a Javascript resource at
/Events.jswhich sets up such a WebSocket connection able to receive and forward such events.
Privileges
The be able to access the Remote Login API, the remote system must have been granted appropriate privileges. The privileges required depends on the request being made.
The first privilege checked, is related to the Response Method requested. By assigning different privileges for different response methods, the administrator of the Neuron can control which response methods are available to different remote system. The following privileges are available, and the appropriate privilege must be granted to the remote system:
RemoteLogin.Method.DelayedResponsefor delayed responses.RemoteLogin.Method.Pollfor allowing remote systems to poll for responses.RemoteLogin.Method.Callbackpermits callbacks to be made to the remote system.RemoteLogin.Method.WebSocketEventpermits asynchronous events to be sent over websockets.RemoteLogin.Method.Refreshpermits the caller to refresh a token it has created.
The second privilege checked, is related to the Address Type requested, as follows:
RemoteLogin.Type.LegalIdallows petitioning for a digital signature request of a Legal Identity.RemoteLogin.Type.JIDallows petitioning for a digital signature request of a Jabber ID.
The third privilege checked, is related to the domain of the account hosting the user digital identity (not the component subdomain related to the legal service hosting the legal identity). The privilege is of the form: RemoteLogin.Domain.DOMAIN, where DOMAIN is comprised of the name parts of the domain, in reverse order, separated by dots. For instance, requesting a digital signature of a user with an account on account@lab.tagroot.io and a Legal ID GUID@legal.lab.tagroot.io, would require the privilage RemoteLogin.Domain.io.tagroot.lab.
Note: When assigning privileges to users, it is possible to provide an entire tree or branch of privileges, by simply granting privileges to the root or intermediate privilege nodes. For instance, granting the privilege RemoteLogin.Domain would grant privileges to initiate remote login on all domains, for example.
Encryption
All requests require transport encryption (TLS) of at least 128 bits, unless on a developer machine (i.e. a machine without a configured domain).
JWT Tokens
Successful user authentication will result in a JWT token to be issued and returned as proof of authentication. This token will expire after a given time. This time is specified in the request, as a number of seconds (1-3600) the token needs to be valid. Before the token expires, the caller needs to refresh the token to ensure the token can be properly validated.
Note: It is assumed that the caller is able to parse the contents of the tokens themselves. Online parsers and libraries are readily available.
Claims available in the token, once created, include:
| JWT claims | ||
|---|---|---|
jti |
JWT ID | Unique identifier of the token. |
iss |
Issuer | The domain of the Neuron issuing the token. |
client_id |
Client ID | The identifier of the Legal ID used to authenticate the user. |
sub |
Subject | The address of the user being authenticated and provided in the initial petition request. |
aud |
Audience | The domain (if using mTLS) or user name (if using WWW-Authenticate of the remote system requesting the user authentication. |
iat |
Issued At | Timestamp of when the token was issued, as the number of seconds past the UNIX Epoch time. |
exp |
Expiration Time | Timestamp of when the token expires, as the number of seconds past the UNIX Epoch time. |
Transparency
All remote login petitions include a purpose that will be presented to the user. The caller should provide sufficient and transparent information to the user about why the signature is requested. If the purpose string does not include the user name (or domain name if mTLS is used), the user name (or domain name) will be prefixed to the purpose string, so the user can see from where the request originated.
Return Codes
Requests to resources will return an HTTP responde code. Following are the most common response codes that can be returned:
| Code | Description |
|---|---|
| 200 | Request processed OK. |
| 400 | Bad request, most probably due to the content sent in the request not conforming to the specification. |
| 401 | Unauthorized access to a resource was prevented. Client must login first. |
| 403 | Forbidden access to resource was stopped. Client does not have sufficient privileges to access resource or perform requested action, or access is done using unencrypted, or a connection that is not sufficiently encrypted. |
| 404 | Resource, or item referenced in request, was not found. |
| 405 | Method not allowed. A resource was accessed using an HTTP method not supported by the resource. |
| 406 | Content sent, or content requested in a format that is not supported by the resource. |
| 429 | Too many requests have been made, for this resource, or any of the referenced resources in the request. |
Requests
Following sections describe the different requests that can be made to the Remote Login API.
Initiating a Delayed Response Petition
To initiate a remote login petition with a delayed response, the following request is made:
{
"AddressType": "LegalId|JID",
"Address": "xs:string",
"ResponseMethod": "DelayedResponse",
"Seconds": "xs:positiveInteger (1-3600)",
"Purpose": "xs:string"
}
The request does not return until the user has signed or rejected the signature request. If the user signs the request, the following response is returned:
{
"Pending": false,
"Token": "xs:string"
}
If the user rejects the request, a 404 Not Found error response is returned.
Initiating a Polled Response Petition
To initiate a polled remote login petition, the following request is made:
{
"AddressType": "LegalId|JID",
"Address": "xs:string",
"ResponseMethod": "Poll",
"Seconds": "xs:positiveInteger (1-3600)",
"Purpose": "xs:string"
}
The resource immediately returns the following response:
{
"PetitionId": "xs:string"
}
Initiating a Callback Response Petition
To initiate a remote login petition where a callback will be made when a response is returned, the following request is made:
{
"AddressType": "LegalId|JID",
"Address": "xs:string",
"ResponseMethod": "Callback",
"CallbackURL": "xs:anyURI",
"Seconds": "xs:positiveInteger (1-3600)",
"Purpose": "xs:string"
}
The resource immediately returns the following response:
{
"PetitionId": "xs:string"
}
This PetitionId can be used for polling, if necessary, but the main purpose is to associate callback messages with the original request. When a response has been received from the user, the following JSON object is POSTed to the Callback URL provided in the request:
{
"PetitionId": "xs:string",
"Rejected": "xs:boolean",
"Token": "xs:string"
}
Initiating a WebSocket Event Response Petition
To initiate a remote login petition where the response will be sent as a websocket event when a response is returned, the following request is made:
{
"AddressType": "LegalId|JID",
"Address": "xs:string",
"ResponseMethod": "WebSocketEvent",
"TabID": "xs:string",
"Function": "xs:string",
"Seconds": "xs:positiveInteger (1-3600)",
"Purpose": "xs:string"
}
The resource immediately returns the following response:
{
"PetitionId": "xs:string"
}
This PetitionId can be used for polling, if necessary, but the main purpose is to associate callback messages with the original request. When a response has been received from the user, the following JSON object is sent to the appropriate Tab and its associated WebSocket, as indicated by TabID in the request.
{
"PetitionId": "xs:string",
"Rejected": "xs:boolean",
"Token": "xs:string"
}
If the /Events.js resource is used to set up the WebSocket, the object will be forwarded to the application by calling the function named in the request. The function must be defined in the application, and take one argument. This argument will receive the JSON object included in the event. Example:
function OnRemoteLoginResponse(Response)
{
console.log("Remote Login Response received:");
console.log(Response.PetitionId);
console.log(Response.Rejected);
console.log(Response.Token);
}
Polling Petition
If the ResponseMethod parameter was set to Poll in the initial request, the remote system can poll for the status of the petition using the following request:
{
"PetitionId": "xs:string"
}
Note: A petition can only be polled by the same entity that initiated the request.
The response to the polling request will be a JSON object with the following fields, as long as the petition has not been rejected by the user. The token will be empty while the petition is still pending.
{
"Pending": "xs:boolean",
"Token": "xs:string"
}
Note: If the petition was rejected by the user, the polling request will receive a 404 Not Found error response.
Validating a Token
Once a token has been received from the Remote Login API, it can be validated by the remote system, or any third part with access to the Neuron. This is done by sending the following request:
{
"Token": "xs:string"
}
The response to the validation request will be a JSON object with the following fields:
{
"Valid": "xs:boolean"
}
Note: The remote system will need to have credentials to access the Neuron, but to not need any special privileges to validate tokens. An entity does not need to be able to initiate a remote login peitition, to be able to validate a token.
Refreshing a Token
Before a token expires, the remote system needs to refresh the token to ensure it stays valid. This is done by sending the following request:
{
"Token": "xs:string",
"Seconds": "xs:positiveInteger (1-3600)"
}
The response to the validation request will be a JSON object with the following fields:
{
"Valid": "xs:boolean",
"Token": "xs:string (Optional)"
}
Note: The token in the response will only be available if Valid is true. A caller can only refresh tokens resulting from petitions it has initiated itself.
Note 2: A token can only be refreshed by the same entity that requested it to be created in the first place.