Frontend integration¶
The JavaScript library operates as a fully independent component within the system architecture. It handles key generation and rotation directly on the client (browser) side. Authentication tokens are single-use, generated client-side, and freshly created for every interaction with the server, including GET requests.
Integrating the JavaScript client into the web application is straightforward: simply embed a script tag directly in the HTML document.
<script src="/relock/relock.js" nonce="bEbGDRxhjvw=" defer></script>
The embedded JavaScript client interacts with the application server by invoking specific routes using the native Fetch API to perform HTTP requests and handle responses. This allows the client to communicate with server-side components, including those responsible for relaying direct messages to the Relock service.
Fetch API requests¶
The Fetch API requests facilitate the request-level authentication. Relock leverages one-time ephemeral keys and elliptic curve signatures for rapid, high-security request-level authentication in web applications.
When making a request, the custom Relock headers—the token and the signature—take precedence over any X-Key-Token
/X-Key-Signature
cookies that might be generated during key rotation. The token is always unique and for one-time use, ensuring each request is individually authenticated.
// Generate ephemeral authentication token and signature
let token = window.relock.token();
let signature = window.relock.sign(token);
// Construct and send the authenticated request
return fetch('https://some.domain.com/some/path', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
// Custom Relock headers
'X-Key-Token': token.hexlify(), // The ephemeral one-time-use token
'X-Key-Signature': signature.hexlify(), // Ed25519 signature of the payload
'X-Key-Time': Math.floor(Date.now() / 1000), // Optional: timestamp for added security
},
credentials: 'include', // Include cookies for cross-origin requests
body: JSON.stringify(body), // Payload to be signed and sent
});
Relock events¶
Relock dispatches custom browser events to inform the application about key status changes and authentication states, enabling dynamic UI updates and redirects.
Key established event (XKeyEstablished)¶
The XKeyEstablished
event triggers when the Relock authentication process successfully establishes or updates an ephemeral key. This event provides information about the user’s authentication state, allowing the application to evaluate authentication status and direct the user accordingly.
Upon receiving this event, the application can redirect the user to:
A page for known but unauthenticated users (e.g., a password entry page).
A page for unknown users (e.g., for step-up authentication).
A page for already authenticated users.
// Event listener for 'XKeyEstablished' to handle key establishment and authentication state
window.addEventListener('XKeyEstablished', function(event) {
if (event.detail.authenticated === false) {
if (event.detail.owner === true)
document.location = // Redirect to known but unauthenticated user page
else
document.location = // Redirect to unknown user page
} else {
document.location = // Redirect to page for already authenticated user
}
});
Rekeying events (XReKeying and X-Key-Rekeying-Done)¶
The XReKeying
and X-Key-Rekeying-Done
manage the key rotation process, allowing developers to provide users with appropriate feedback during key updates and handle rekeying failures.
The XReKeying
event is dispatched at the start of the key rekeying process and can be used to display a loading indicator or other UI feedback to the user.
The X-Key-Rekeying-Done
event is dispatched upon the completion of the key rekeying process. If rekeying fails (e.g., due to an invalid ephemeral key), the application can take appropriate action, such as redirecting the user to an error page or forcing re-authentication. This event can also be used to hide loading indicators.
// Event listener for 'XReKeying' event to show loading indicator during key rekeying process
document.addEventListener('XReKeying', function(event) {
document.getElementsByClassName("loader").forEach((el) => {
el.style.visibility = "visible"; // Show loading indicators
});
}.bind(this));
// Event listener for 'X-Key-Rekeying-Done' event to hide loading indicator after rekeying is complete
document.addEventListener('X-Key-Rekeying-Done', function(event) {
setTimeout(() => {
document.getElementsByClassName("loader").forEach((el) => {
el.style.visibility = "hidden"; // Hide loading indicators after delay
});
}, 500); // Optional delay for smooth UI transition
}.bind(this));
// Alternatively, event listener for 'X-Key-Rekeying-Done' to handle rekeying failures
window.addEventListener('X-Key-Rekeying-Done', function(event) {
if (!event.detail.valid) {
document.location = // Redirect due to ephemeral key authentication failure
}
});
View change events (beforeunload and x-close)¶
In Single-Page Applications (SPAs), traditional page unload events typically don’t fire during view changes. To ensure Relock properly manages keys within a multi-tab browser environment, it’s necessary to manually dispatch events to inform the Relock object about view transitions. This is crucial for maintaining security, consistency, and session integrity by ensuring keys are rotated or invalidated as needed when the user switches views or tabs.
The beforeunload
event signals the Relock object to handle key rotation or invalidation before the view or tab changes.
The x-close
event, dispatched after a brief delay, simulates content purging from a tab or the user navigating away, helping Relock manage key rotation across multiple tabs.
These manual dispatch events ensure that keys are correctly managed even when traditional unload events do not fire in SPAs.
// Dispatching a 'beforeunload' event to inform Relock about the view change
window.dispatchEvent(new CustomEvent('beforeunload', {
bubbles: true,
detail: { manual: true }
}));
// Dispatching an 'x-close' event after a brief delay, simulating tab or view closure
window.setTimeout(() => {
window.dispatchEvent(new CustomEvent('x-close', {
bubbles: true,
detail: { manual: true }
}));
}, 100);
Exposed properties and methods¶
The JavaScript library exposes its functionality through a global JavaScript object, providing the following methods and properties for direct interaction, enabling various operations central to Relock’s client-side authentication and session management.
Properties¶
id
(read-only): The hexadecimal representation of the active ephemeral key’s hash, which uniquely identifies the cryptographic key pair currently in use by the browser instance for Relock’s operations.
public
(read-only): The hexadecimal representation of the browser’s origin-bound public key, which is part of the cryptographic pair used by the client for signing data.
screen
: The current screen ID, which serves as a unique identifier for the browser tab. If not present when the getter method is called, a new unique ID is generated and stored.
server
(read-only): The hexadecimal representation of the Relock service instance ID, which identifies the specific Relock service instance that the client is currently associated with.
xsid
: The Relock session ID which is provided by the Relock service and managed in local storage to maintain session state across browser tabs and restarts.
Methods¶
init()
initializes internal mechanisms to manage the client’s session state, including binding relevant browser event listeners and establishing an activity monitor to detect idle periods and manage session timeouts.
token([size])
generates a new ephemeral, one-time-use authentication token for each request.size
(optional
,number
): The desired byte length of the token. Default: 32 bytes.Returns: A
Uint8Array
representing the generated token, which is empty if a required internal secret is not yet established.
sign(data)
signs the provided data using the browser’s internally managed private key.data
(Uint8Array
): The data to be signed.Returns: A
Uint8Array
representing the cryptographic signature, which is empty if the input data is empty or the private key is unavailable.
verify(data, signature)
verifies a server-generated signature against provided data using the browser’s internally managed public key.data
(Uint8Array
): The original data that was signed by the server.signature
(Uint8Array
): The cryptographic signature to verify.Returns: A
boolean
indicating whether the signature is valid for the given data and public key.
validate(token)
validates an incoming token against the current client-side ephemeral key, confirming the client’s ability to re-derive a shared secret based on the token.token
(Uint8Array
): The token to validate, provided by the server as part of the challenge-response protocol. Default: 32-byte emptyUint8Array
.Returns: A
boolean
indicating whether the provided token successfully validates against the internal client-side state.
clear([redirect])
initiates a client-side cleanup process, purging all Relock-related data from the browser’s local and session storage. This operation also triggers a corresponding data purge on the application server via a specific HTTP route.redirect
(optional
,boolean
): If false or omitted, after clearing, the page will automatically redirect to the root path (/
) with a short delay.Behavior: Clears relevant client-side storage items. If not prevented by the redirect parameter, the browser will navigate to the application’s root URL.