Skip to main content

Restrict an embedding link

The embedding feature in Imply Polaris provides non-Polaris users with a way to view visualizations outside the Polaris UI.

You can create public links to visualizations that anyone can access and view. See Embed visualizations for information on creating public links.

Restricted links are a more secure alternative to public links. Restricted links permit access only when the URL includes a parameter containing a signature. You create signatures programmatically using the secret key and additional parameters.

To generate restricted links you must perform the following tasks. The parameter names relate to the example scripts below.

  1. Create a restricted link and secret key.
    • url and SECRET_KEY parameters
  2. Define the link creation time.
    • created parameter
  3. Optional: Apply a data cube access filter.
    • cubeAccessFilter parameter
  4. Optional: Define an access filter for the link.
    • linkAccessFilter parameter
  5. Generate a restricted link.
info

You must use the exact parameter names created, cubeAccessFilter, and linkAccessFilter for Polaris to recognize them. See the example scripts for implementation examples.

See Embed visualizations for details on how to create a restricted link and secret key in the Polaris UI. You can also use the Embedding API to create a private key for an embedding link.

Set the created parameter to a string value representing the time the link was created, in milliseconds. See the example scripts for examples.

When a user accesses a restricted link, Polaris verifies the signature. If created is less than an hour ago, Polaris stores a cookie containing the authentication details. The link enables cookie creation for an hour. Polaris revokes link access at cookie creation time plus time to live from the link properties.

Optional: Apply a data cube access filter

If you're creating a restricted link for data cube that has an access filter applied, you can apply that access filter to your link.

For example, you might set up a Koalas to the Max data cube with an access filter that allows analysts in France to see only the data relevant to their home country and the United States. See the access filter example for a full example.

To find the access filter ID to plug into your script:

  1. In the Polaris UI, click Data cubes in the left pane.
  2. Click the name of the data cube that underlies the link view.
  3. Click the edit icon in the top right to edit the data cube.
  4. Click the Access filters tab and click the edit icon in the top right corner of the page.
  5. Click the view details icon to the right of the filter name.
  6. Copy the Group ID that appears.

Set the cubeAccessFilter parameter to the ID.

In addition to, or instead of, applying a data cube access filter, you can define an access filter for your specific link.

For example, if you apply the data cube filter for analysts in France outlined in the access filter example, you might want to apply an extra filter to your link for managers in Paris to view. This filter would further restrict the data in the embedded visualization to match the city name Paris:

t."cityname" = 'Paris'

Define the access filter in the linkAccessFilter parameter.

Next, programmatically generate a signature for your link using the restricted link as follows:

  1. Import your secret key.
    The key is in Privacy Enhanced Mail (PEM) format. Import it using the Elliptic Curve Digital Signature Algorithm (ECDSA) with a P-256 curve and ensure that it has signing permissions.
  2. Create a payload of parameters with the following names, in the following order: {cubeAccessFilter, linkAccessFilter, created}.
    You can include unused parameters as undefined if you're using JavaScript or TypeScript. Otherwise, omit unused parameters.
  3. Sign the payload using the ECDSA algorithm SHA-256 and ensure it's in IEEE P1363 format.

To access the restricted link, include the signature and signed parameters as query parameters.

The URL format is as follows:

https://ORGANIZATION_NAME.app.imply.io/e/REGION:CLOUD+PROJECT_ID+EMBED_LINK_ID/UNIQUE_ID?signature=SIGNATURE&cubeAccessFilter=CUBE_FILTER&linkAccessFilter=LINK_FILTER

Replace UNIQUE_ID with an alphanumeric stringthis is required if you want to embed the same visualization multiple times on the same page.

Including the CLOUD property is optional. If omitted, Polaris infers the cloud service provider from the REGION property.

For example:

https://example.app.imply.io/e/us-east-1:aws+adc305e1-2e77-40df-805f-ef0f6cd4f164+34392300657dc3c5d0/1?signature=W4HDEO4-FOX54V-cskOX&cubeAccessFilter=0e760716-b0b4-4b60-bd68&linkAccessFilter=t."cityname"='Paris'&created=1679003827755

You can add extra query parameters to the link, to vary the data in the visualization while applying the same restrictions through the signature.

The way in which you implement the link generation depends on your specific use case. As an example, you could create a session token when a user logs into your application. You could set the session token expiry to the same period as your restricted link's time to live.

Using this configuration, you would only need to create the restricted link once per user session.

Example scripts

See the following scripts for detailed Python and JavaScript examples of programmatically generating links:

import base64
import json
import time

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.primitives import hashes
from URLSearchParams import URLSearchParams

# Secret key from the Polaris UI
secretKeyPEM = "SECRET_KEY";

# Link URL from the Polaris UI
url = `https://example.app.imply.io/e/us-east-1:aws+adc305e1-2e77-40df-805f-ef0f6cd4f164+34392300657dc3c5d0/1?signature=W4HDEO4-FOX54V-cskOX&cubeAccessFilter=0e760716-b0b4-4b60-bd68&linkAccessFilter=t."cityname"='Paris'&created=1679003827755`

# ID of the data cube access filter
cubeAccessFilter = "676fd330-aabc-4d76-b1a3-e9f1eff4b3a2";

# SQL access filter to apply to the link
linkAccessFilter = `t."cityname"='Paris'`;

# String value of the time the link was created, in milliseconds
created = str(int(time.time() * 1000));

# Payload containing the required parameters
# Sign the payload parameters in the following order: {cubeAccessFilter, linkAccessFilter, created}
payload = {"created": created}

# Separators to prevent adding whitespace around symbols
payload = json.dumps(payload, separators=(',', ':')).encode('utf-8')

# Load the secret key
secretKey = load_pem_private_key(secretKeyPEM, password=None, backend=default_backend())

# Generate a signature format using ECDSA P-256
signature = secretKey.sign(
payload,
ec.ECDSA(hashes.SHA256())
)

# Convert signature format to IEEE P1363
(r, s) = decode_dss_signature(signature)
signatureP1363 = r.to_bytes(32, byteorder='big') + s.to_bytes(32, byteorder='big')

# Output signature as a URL-safe base64 string
print('payload signed: ', payload)
print('signature created: ', base64.urlsafe_b64encode(signatureP1363).decode('utf-8'))

# Build the restricted link from the signed parameters
src = URLSearchParams(url).append(
{"created": created, "signature": base64.urlsafe_b64encode(signatureP1363).decode('utf-8')})
print('You can now access your restricted link from: ', src)