Secure Anonymous Tokens

Secure Anonymous Tokens (SATs) can allow users to authenticate using Xi Frame’s Session API. These tokens, generated by a secure API call, allow admins to provide their users with access to Xi Frame resources on-demand without prompting for another set of credentials. There are many use-cases where this type of authentication could be useful, such as software trials, demos, or kiosk-like experiences, for example.

Additionally, the SAT API can be customized with additional parameters, some of which can be populated via environment variables in the remote system.

Overview

Using the SAT API, a web server can request a token on-demand (when a page or endpoint is requested, for example) and provide it to the Xi Frame Session API for sessions.

../_images/session_api_sat_workflow_diagram.png

Getting Started

Requirements

  • Xi Frame Administrative access (Customer, Org, or Account level).

  • Administrative API access enabled.

  • Secure Anonymous Token provider enabled with Launchpad users.

  • Web server to host Secure Anonymous Token API integration.

REST API Credentials

The Secure Anonymous Token API can be consumed over REST endpoints to retrieve tokens. This requires an API integration with the proper roles/permissions.

Creating a new API integration

To get started, be sure to login as an administrator to gain access to API settings.

  1. There are two ways to start this process:

    1. From the Dashboard of the account, navigate to the “Users” page.

    2. If you start from the Admin view, navigate to the entity (Customer, Organization, or Account) you wish to update and click on the ellipsis listed next to it to select “Users.”

    ../_images/add_api_00.png
  2. Enable the “API” toggle and save – a new tab entitled “API” will appear.

../_images/add_api_0.png
  1. Click on the API tab and then click the “Add API” link.

../_images/add_api_1.png
  1. Give this new API integration a name; for this example, we’ll use “API to create anonymous tokens”. Then, select a role and scope based on your scenario below.

For account-level integrations, choose the API - Generate Anonymous Account Token role, along with the account you’re configuring access for.

For organization or customer level integrations, you’ll need to specify the API - Generate Anonymous Organization Token and API - Generate Anonymous Customer Token, respectively.

../_images/add_api_2.png
  1. Click “Add.” The new API will show up in the API list. Click the options menu for the new API and select “Manage Credentials”.

../_images/add_api_3.png
  1. You’ll be prompted to create a new API key – start by giving it a name, then click the PLUS button on the right.

../_images/add_api_4.png
  1. You’ll now see your Client ID and Client Secret. Copy these values to somewhere safe, as you won’t be able to see the secret again after leaving this screen.

../_images/add_api_5.png
  1. That’s it! Now you’re ready to add a SAT Provider in the next section.

Creating a Secure Anonymous Token Provider

  1. There are two ways to start this process:

    1. From the Dashboard of the account, navigate to the “Users” page where you will land on the Authentication tab.

    2. If you are starting from the Admin view, navigate to the entity (Customer, Organization, or Account) and click on the ellipsis listed next to it to select “Users.”

    ../_images/add_api_00.png
  2. Enable the Secure Anonymous option under Authentication and save; a new Secure Anonymous tab will show up.

../_images/secure_anon_setup_1.png
  1. Click the Secure Anonymous tab, then click the “Add Provider” link.

../_images/secure_anon_setup_2.png
  1. You’ll be prompted to describe and configure your new Secure Anonymous provider. You can specify the following:

Anonymous Provider Properties

Description

A short description of what you plan to use the Anonymous Token provider for (e.g., public trials)

Token Duration

how long until the token expires and is no longer valid.

Roles and Scope

The role will typically be a launchpad user, and the scope is which account/Launchpad you’d like to provide access to via these tokens.


  1. Give it a description that makes sense for your use case, e.g. “Token provider for product trials”. Then, set the token duration you’d like. Finally, select a Role and scope – we recommend only configuring the role for Launchpad Users for security reasons.

../_images/secure_anon_setup_3.png
  1. Your new Anonymous Access Provider will appear. Click the ellipsis next to the provider and select “Playground.” Test generating tokens using the new provider, as well as various syntax examples demonstrating how to make a request for tokens.

../_images/secure_anon_setup_4.png

Generating Secure Anonymous Tokens

Now that we have an API Client ID and Client Secret from the API setup steps above, we can use the dynamic code snippet examples provided in the Secure Anonymous Playground. Making a token request is pretty simple. It requires API credentials, making a HMAC signature based on those credentials, then a HTTP POST to your SAT Provider’s endpoint.

Security Considerations

Requests for SATs should be executed from a secure backend environment. Requests like these should not be made from client-side javascript, for example, as the API credentials can be exposed to the public.

Warning

It is your responsibility to secure any self-hosted endpoints that process SAT requests. To clarify, there should not be a public URL on the web that prints out free tokens to any visitor – avoiding this and using best-practices will help prevent unauthorized access, abuse of resources, legal issues, or worse.

Code examples

In the Secure Anonymous Playground, we have a examples for requesting tokens written in Python 3, Node.js, curl, Powershell, and PHP. To try these for yourself, copy an example in your preferred language, then paste in your Client ID and Client Secret, then execute the code. Executing the examples should return a token if everything is configured properly.

Here’s an example that prints the output of a SAT request in Python 3:

#!/bin/env python

import hashlib
import hmac
import time
import requests
import base64

# Client credentials
client_id = "<Your API Client ID goes here>"
client_secret = b"<Your API Client Secret goes here>"

# Create signature
timestamp = int(time.time())
to_sign = "%s%s" % (timestamp, client_id)
signature = hmac.new(client_secret, to_sign.encode('utf-8'), hashlib.sha256).hexdigest()

# Prepare http request headers
headers = { "X-Frame-ClientId": client_id, "X-Frame-Timestamp": str(timestamp), "X-Frame-Signature": signature }

# Include optional params such as first_name, last_name, email_domain, email or metadata.
body = {}

# Make request
r = requests.post("https://api.console.nutanix.com/v1/<Entity type here (customer, organization, or account)>/<Entity ID goes here>/secure-anonymous/<Secure anonymous provider ID goes here>/tokens", headers=headers, data=body)

# Print the response (a JWT)
print r.json()

Anonymous Token Parameters

You can provide a few optional parameters when generating anonymous tokens. These parameters let you customize the information provided in the JWT, allowing you to set properties such as:

  • First Name

  • Last Name

  • Email Address

  • Email Domain

Optional Anonymous Token Parameters

Name

Type

Description

first_name

string

“John” for example.

last_name

string

“Smith” for example.

email

string

Example: john.smith@acme.com

email_domain

string

Example: acme.com. This will return xxxxxxx@acme.com.

metadata

object

An object containing any additional information you’d like to supply for your users/token.

Metadata

You can provide custom information for a user when generating Secure Anonymous Tokens – this type of metadata is often called assertions. A simple Node.js example is available on on Github that demonstrates how to populate metadata and query it after a token’s been generated. We’ll use code snippets from this repository in examples below.

Populating metadata

When requesting a token, you can supply a metadata object to the body of the request.

first_name: "Jason",
last_name: "Thompson",
email: "jason.123456@acme.com",
metadata: {
  exampleId: 123456,
  language: "EN",
  timezone: "PT"
}

Querying metadata

Querying metadata is a simple GET request along with an Authorization header specifying the token. The token must be specified in the “Bearer” format, and the API endpoint is https://cpanel-backend-prod.frame.nutanix.com/api/rest/v1/me/assertions.

async function getUserAssertions(token) {
  const result = await axios({
    url:
      "https://cpanel-backend-prod.frame.nutanix.com/api/rest/v1/me/assertions",
    headers: { Authorization: `Bearer ${token}` },
  });

  return result.data;
}

Retrieving Metadata from within Windows

This metadata can also be retrieved from within the remote OS environment during a running session. This is made easy through the use of a session token that’s made available as an environment variable labeled as FRAME_SESSION_TOKEN. This Session Token is different than the token used to start the session (and can’t be used for starting sessions), but it relates to the same user. This token also requires a different endpoint for querying the assertions. Here’s an example of how to do this in Powershell (5.x):

# Set TLS compatibility for Powershell 5.x
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12

$sessionToken = "$env:FRAME_SESSION_TOKEN"
$uri = 'https://messaging.frame.nutanix.com/api/rest/v1/me/assertions'
$headers = @{'Authorization' = "Bearer $sessionToken"}

$response = Invoke-RestMethod -Uri $uri -Headers $headers -ContentType "application/json" -Method Get

Write-Host $response

Note

You can query metadata like this in a “pre-session” script and use the supplied information to customize your applications/environment, mount network drives, etc. Please reach out to your Nutanix rep for more information and guidance on how to do this.

Viewing Metadata from Launchpad

Anyone can view their metadata from Launchpad from the account profile page. To view the supplied metadata or “assertions,” a user can click on their name at the top-right of the Launchpad to open their User menu. From there, click “edit.” This will take you to the user’s profile page – from there, click Advanced on the left-hand side. This page shows a table of assertions for the current user, like so:

../_images/secure_anon_launchpad_view_assertions.png

Customize auth flow

When using SATs with Launchpad or Launch links, specific metadata should be specified to point to customer-built and customer-hosted URLs that control what happens when a user logs out or in from Frame’s UIs.

metadata: {
  exampleId: 123456,
  frame_login_url: "https://example.com/log-back-into-frame",
  frame_logout_url: "https://example.com/log-out-and-thank-you"
}

In the example above, we specified frame_login_url and frame_logout_url. When these are present, we’ll honor the values supplied when users are using our UI.

These URLs are used when Launchpad and Launch link users are inactive (no keyboard or mouse activity) for 15 minutes. When this happens, we log the user out and prompt the user with options to Leave or Log back in.

../_images/secure_anon_launchpad_logout_inactivity.png

Additionally, when using the Launchpad, the logout URL is tied to the Logout button from the Profile menu at the top-right of the Launchpad. When a user clicks this, Frame invalidates the user’s token and redirects the user’s browser to the URL specified in the SAT’s metadata.

../_images/secure_anon_launchpad_logout_button.png

Note

To ensure a great experience, the URL supplied for frame_login_url should be used to route a user to your website to generate a new token, then redirect the user back to their original location with that token. This ensures compatibility between Launchpad, Launch Links, and PWAs while using Secure Anonymous Tokens.

Note

SAML2 Users can also take advantage of these custom auth URLs if they specify these parameters in their identity provider’s assertion/claims. The process to do this varies for each identity provider; please refer to your identity provider’s documentation about adding custom assertions/claims.