Devops Guide

Overview

For a general overview of common devops tasks for Synapse services see Synapse Devops Guide - Overview.

Common Devops Tasks

Enable Alpha/Beta Features

The UI sometimes adds new features that are under active development and may be unstable and/or not finalized. You can enable these features in your deployment by setting the feature flag to true. The following feature flags are currently available:

feature:modules

Enable the Modules tool on this UI instance. (alpha)

feature:spotlight

Enable the Spotlight tool on this UI instance. (beta)

The following features have now been enabled by default:

feature:powerups

Set false to disable the Power-Ups tool on this UI instance.

feature:stories

Set false to disable the Stories tool on this UI instance. (beta)

feature:workflows

Set false to disable the Workflows tool on this UI instance. (beta)

The feature flags will remain for backwards compatibility, and some features may still be considered beta. You can set the flag to false to disable a particular feature.

Use Custom HTTPS Certificates

The UI will automatically generate a self-signed certificate and key if they are not found at sslcert.crt and sslkey.pem in the storage directory. At any time, you can replace these self-signed files with a certificate and key generated using easycert or generated and signed by an external CA.

for example, to map in these files from a parent certs directory the docker-compose.yaml volumes section would be:

volumes:
  - ./storage:/vertex/storage
  - ../certs/fullchain.pem:/vertex/storage/sslcert.pem
  - ../certs/privkey.pem:/vertex/storage/sslkey.pem

Enable a Custom HSTS Header

Like all other Cells, the Synapse UI can be configured to add additional headers to all HTTPS server responses via the https:headers configuration option.

For example, to set a custom HSTS header using an environment variable:

SYN_OPTIC_HTTPS_HEADERS: '{"Strict-Transport-Security": "max-age=31536000; includeSubDomains; preload"}'

This configuration option can also be enabled by editing the cell.yaml file:

https:headers:
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload'

Use Azure AD to Authenicate Users

The Synapse UI can optionally be configured to authenticate and authorize users by integrating with the Microsoft identity platform. End users will be able to authenticate using the OAuth 2.0 authorization code flow and securely prove group membership to the UI. When necessary, Cortex users will be created and be granted/denied admin privileges in accordance with Azure AD group membership. Azure AD will be the source of truth for user access and admin privilege, but all standard Cell permissions are managed in Synapse and applied to users as per usual.

Existing Cortex Users

When configuring Azure AD Authentication on a Cortex with existing users, a Cortex user can be bound to an Azure user by ensuring the Azure user profile email field matches the Cortex user email. This will cause the initial login via Azure to avoid creating a new user and instead bind the existing Cortex user to the Azure user.

Azure and Synapse UI Configuration

To configure the UI to use Azure AD for authentication you will need:

  • An active Azure subscription with access to Azure AD.

  • The necessary permissions to create a new App registration.

  • Access to or the necessary permissions to create two groups, one for regular users and one for Admins.

Configuration Steps
  1. Navigate to the Azure portal, login to your account and navigate to the Azure AD area of the portal.

  2. Select Register a New Application. Enter an informative name and configure the supported account types. Under Redirect URI select Single-page application (SPA) in the drop-down and enter the URL https://<your.ui.domain>/login. See the Microsoft documentation for more detailed information.

  3. In the overview of your new App, record the following IDs:

    • Directory (tenant) ID

    • Application (client) ID

  4. In the Manage section of the App menu, select Expose an API and then Add a scope. When prompted to set the Application ID URI, leave it as the default. Create the new scope with the name synapse.optic.login, allow Admins and users to consent, and make sure it is Enabled. The name of the scope can be customized if desired, as long as the scope name is also provided to the cell as auth:azure:scope. The following are suggested names for the display name and description of the scope:

    Admin/User consent display name

    UI Azure AD Auth

    Admin/User consent description

    Allow the UI to authenticate you with Azure AD

  5. In the Manage section of the App menu, select Token configuration. Select Add optional claim and set the Token type to Access and ensure email is selected and click Add. Next select Add groups claim. Check the box for Security Groups and then click Save.

  6. Return to the main Azure AD area and then navigate to Groups configuration.

  7. Find or create two groups to designate users that can access the UI. The first groups members will be authorized for access as a regular user. The second groups members will be authorized Admin access to the UI. Record both groups Object ID.

  8. Add the following configuration (with your values) to the UI cell.yaml:

    ---
    
    # ... other cell configuration ...
    
    auth:azure: true
    auth:azure:tenantId: <Directory (tenant) ID>
    auth:azure:authority: https://login.microsoftonline.com/<Directory (tenant) ID>
    auth:azure:clientId: <Application (client) ID>
    auth:azure:userGroupId: <Regular user Group Object ID>
    auth:azure:adminGroupId: <Admin user Group Object ID>
    
  9. Start or restart the UI cell and the configuration will become active.

Role based Authentication

The UI can optionally be configured to support validation of the roles claim in addition to scope and groups. This is especially useful for supporting Daemon apps that need to use a client credentials flow, where dynamic scopes and delegated permissions are not allowed because the Daemon is acting on its own.

In this example we’ll create the necessary Application roles on the existing UI app, create a Azure AD Daemon app with a client secret and permissions to the UI API, and finally provide an example of acquiring a token and using it to login and run a Storm query via API.

  1. Navigate to the Azure portal, login to your account and go to the Azure AD area of the portal.

  2. Find the existing UI App and navigate to it. Go to App roles to add two Application roles. One for regular users and one for Admins. Set the membership type to Application, and set Display name, Value, and Description as desired. Record both roles Value. These roles will be allow other Azure applications to gain to access to the UI API when the corresponding permission is added to the app and configured in the UI cell.yaml.

  3. Head back to Azure AD and select Register a New Application to create an application for your Daemon app. Leave the Redirect URL section empty and click Register.

  4. In the overview of your new App, record the Application (client) ID as your Daemon app client ID.

  5. In the Manage section of the App menu, select API Permissions and then Add a permission. Select the APIs my organization uses tab and find or search for for the existing UI app and click on it. Now select Application permissions and choose togrant this app either Admin or regular user based access by selecting on of the App roles created earlier. Click Add permissions at the bottom to save.

  6. Still in API Permissions, click Grant admin consent to activate the new Application permission for the client credential flow.

  7. Go to Certificates & secrets and create either a Certificate or client secret credential. In this example, click New client secret to create a secret and be sure to record the secret’s Value.

  8. Add the following configuration (with your values) to the UI cell.yaml:

    ---
    
    auth:azure: true
    # ... other azure configuration
    
    auth:azure:userRole: <Regular user App role Value>
    auth:azure:adminRole: <Admin user App role Value>
    
  9. Now you can use your desired approach (e.g. MSAL or plain HTTP requests) to obtain an access token that will be validated by the UI API. The Daemon app will have a Cortex user provisioned for it on first login, with the user name matching the Daemon apps client ID. The user can be subsequently renamed as desired. Below is an example using the Microsoft supported MSAL <https://msal-python.readthedocs.io/> and requests libraries to acquire a token, login to the UI API and run a Storm query.:

    import msal
    import json
    import requests
    
    ui_url = 'https://loop.vertex.link:4443'
    
    # Configure according to your Azure AD configuration
    azure_conf = {
        "authority": "https://login.microsoftonline.com/<your tentant ID>",
        "client_id": "<your daemon app client ID>",
        "scope": ["api://<optic api app client ID>/.default"],
        "secret": "<your client secret>",
    }
    
    # Create a preferably long-lived app instance that maintains a token cache.
    app = msal.ConfidentialClientApplication(
        azure_conf['client_id'],
        authority=azure_conf['authority'],
        client_credential=azure_conf['secret']
    )
    
    # Acquire an access token from Azure.
    result = app.acquire_token_for_client(scopes=azure_conf['scope'])
    token = result['access_token']
    
    # Login to UI API with the token
    sess = requests.Session()
    resp = sess.post(f'{ui_url}/api/v1/optic/login', data=json.dumps({'token': token}), verify=False)
    
    # Run a Storm query
    data = json.dumps({'query': '$lib.print("Hello Storm!")'})
    resp = sess.post(f'{ui_url}/api/v1/storm', data=data, stream=True, verify=True)
    
    # Iterate and output the chunked response
    for chunk in resp.raw.read_chunked():
        if not chunk:
            break
        mesg = json.loads(chunk)
        print(mesg)
    

Use SAML 2.0 to Authenticate Users

The Synapse UI can optionally be configured to authenticate users using a configured SAML Identity Provider and acting as a SAML Service Provider. Cortex users are expected to already exist and will be looked up by email provided in the SAML assertion. Note that all normal Cell permissions are managed in Synapse and applied to users as per usual.

SAML 2.0 and UI Configuration

To configure the UI to use SAML 2.0 for authentication you will need:

  • An SAML 2.0 IdP (Identity Provider) and its SAML metadata URL.

Below is an example of configuring an IdP and the UI to use SAML Auth. Step three contains the configuration necessary for the IdP. You will need to obtain the Identity Provider Issuer and Identity Provider metadata URL from the IdP.

For this example we will use Okta as the IdP to demonstrate the necessary SAML configuration values. To get started with Okta you can sign up for a free trial account. The steps below assume you are an Admininstrator of the Okta organization.

Configuration Steps
  1. Log in to Okta and navigate to the Applications tab. Click the Add Application button.

  2. Click Create New App and set the Platform to Web. Select SAML 2.0 for the Sign on method and then click Create. Input an appropriate App name like Optic. Download the UI logo from https://<your.ui.domain>/images/optic-logo-landscape.png and upload it as the App Logo so it will be easy to recognize for users. Click the Next button to continue.

  3. In the SAML Settings form, set the following values.

    Single sign on URL

    https://<your.ui.domain>/api/v1/optic/login

    Use this for Recipient URL and Destination URL

    checked

    Audience URI (SP Entity ID)

    https://<your.ui.domain>

    Default RelayState

    leave blank

    Name ID format

    Unspecified

    Application username

    Email

Click the Next button to continue.

  1. Select I’m an Okta customer adding an internal app and check the box for This is an internal app that we have created.

  2. In the Application Sign On settings tab, scroll down to find the info box indicating SAML 2.0 is not configured until you complete the setup instructions.. Click View Setup Instructions and copy the value for Identity Provider Issuer. Go back to the previous tab and in the same info box, right click the the link that says Identity Provider metadata and copy the link address. The Issuer and metadata URL will be needed to configure the UI later.

  3. The Okta Application is now configured. Be sure to assign the application to any Okta users or groups that should be able to access it. Also ensure that the Okta user email address will match the existing UI (Cortex) user email.

  4. Add the following configuration (with your values) to the UI cell.yaml:

    ---
    
    # ... other cell configuration ...
    
    auth:saml: true
    auth:saml:issuer: <Identity Provider Issuer>
    auth:saml:metadata:url: <Identity Provider metadata URL>
    
    # optionally override session expiration with a specified number of days
    auth:saml:session:length: 14 # days
    
  5. Start or restart the UI cell and the configuration will become active.

Enable Real User Monitoring

The Synapse UI can be configured to enable Real User Monitoring (RUM) capabilities for increased visibility into user activity, resources, and errors. Currently only Datadog RUM is supported.

Datadog

Datadog provides Real User Monitoring and a native browser library to manage it. You can read more about its features in Datadogs RUM documenation.

Configuration
  1. Follow the Datadog documentation steps to create a RUM Browser application.

  2. After generating a clientToken and applicationId for your UI instance, Add the configuration to your UI cell.yaml:

    ---
    
    # ... other cell configuration ...
    
    rum:datadog: true
    rum:datadog:appId: <applicationId>
    rum:datadog:clientToken: <clientToken>
    rum:datadog:site: 'datadogghq.com'  # or other site if applicable
    
    rum:datadog:service: 'optic'  # optional (default is 'optic')
    rum:datadog:env: 'example'  # 'dev', 'staging', 'production', etc. (default is none)
    rum:datadog:trackInteractions: true  # To enable automatic interaction tracking. (default is false) See documentation (https://docs.datadoghq.com/real_user_monitoring/browser/tracking_user_actions/) before enabling
    
  3. Start or restart the UI cell and the configuration will become active.

  4. Now when users are active in UI their activity will be collected by Datadog.

  5. Note that many Adblocking browser extensions/plugins will block this monitoring unless properly configured.

Storing User Login Timestamps

The Synapse UI will log when a user performs a login to the application using the standard logging mechanisms. In addition, the UI can also be configured to record this time in the Cortex as well. To enable this, the login:record option must be configured for the service.

For example, to enable this with an environment variable:

SYN_OPTIC_LOGIN_RECORD: "true"

This configuration option can also be enabled by editing the cell.yaml file:

login:record: true

To display the last login timestamp of a user, an admin in the Cortex can issue the following Storm query:

$user = $lib.auth.users.byname(foouser)
$date = $lib.jsonstor.get((optic, $user.iden, lastlogin))
if $date {
    $repr = $lib.model.type(time).repr($date)
    $lib.print($repr) }
else {
    $lib.print('No optic login for {name}', name=$user.name)
}

Devops Details

Docker Images

The Synapse UI is available as a Docker image from Docker Hub. The repository can be found at:

Note

There are tagged images available on Docker Hub which correspond to software releases seen in the changelog. There is also a v2.x.x tagged image available, which represents the latest released version of the software. The docker tag master is the latest development release. It is recommended to use images with specific version tags to avoid unintended updates, or the v2.x.x to stay only on released versions of the software.

Configuration Options

The following is a list of available configuration options.

aha:admin

An AHA client certificate CN to register as a local admin user.

Type

string

Environment Variable

SYN_OPTIC_AHA_ADMIN

aha:leader

The AHA service name to claim as the active instance of a storm service.

Type

string

Environment Variable

SYN_OPTIC_AHA_LEADER

aha:name

The name of the cell service in the aha service registry.

Type

string

Environment Variable

SYN_OPTIC_AHA_NAME

aha:network

The AHA service network. This makes aha:name/aha:leader relative names.

Type

string

Environment Variable

SYN_OPTIC_AHA_NETWORK

aha:provision

The telepath URL of the aha provisioning service.

Type

['string', 'array']

Environment Variable

SYN_OPTIC_AHA_PROVISION

aha:registry

The telepath URL of the aha service registry.

Type

['string', 'array']

Environment Variable

SYN_OPTIC_AHA_REGISTRY

aha:user

The username of this service when connecting to others.

Type

string

Environment Variable

SYN_OPTIC_AHA_USER

auth:anon

Allow anonymous telepath access by mapping to the given user name.

Type

string

Environment Variable

SYN_OPTIC_AUTH_ANON

auth:azure

Set True to enable auth via Azure AD.

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_AUTH_AZURE

auth:azure:adminGroupId

The Object ID of the Group to be allowed access as an admin user.

Type

string

Environment Variable

SYN_OPTIC_AUTH_AZURE_ADMINGROUPID

auth:azure:adminRole

The name of the Application role that is allowed access as an admin user. This is optional and intended for use with Daemon apps using a client credential flow.

Type

string

Environment Variable

SYN_OPTIC_AUTH_AZURE_ADMINROLE

auth:azure:authority

The Azure AD authority e.g. https://login.microsoftonline.com/<tenant id>

Type

string

Environment Variable

SYN_OPTIC_AUTH_AZURE_AUTHORITY

auth:azure:clientId

The Azure AD Application (client) ID.

Type

string

Environment Variable

SYN_OPTIC_AUTH_AZURE_CLIENTID

auth:azure:scope

The scope exposed by the app in the Azure Portal.

Type

string

Default Value

'synapse.optic.login'

Environment Variable

SYN_OPTIC_AUTH_AZURE_SCOPE

auth:azure:tenantId

The Azure AD Directory (tenant) ID.

Type

string

Environment Variable

SYN_OPTIC_AUTH_AZURE_TENANTID

auth:azure:userGroupId

The Object ID of the Group to be allowed access as a regular user.

Type

string

Environment Variable

SYN_OPTIC_AUTH_AZURE_USERGROUPID

auth:azure:userRole

The name of the Application role that is allowed access as a regular user. This is optional and intended for use with Daemon apps using a client credential flow.

Type

string

Environment Variable

SYN_OPTIC_AUTH_AZURE_USERROLE

auth:passwd

Set to <passwd> (local only) to bootstrap the root user password.

Type

string

Environment Variable

SYN_OPTIC_AUTH_PASSWD

auth:saml

Set True to enable auth via SAML 2.0.

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_AUTH_SAML

auth:saml:entityid

The entity (client) ID of the SAML SP. This is optional and if not provided will be https://<netloc>

Type

string

Environment Variable

SYN_OPTIC_AUTH_SAML_ENTITYID

auth:saml:issuer

The Identity Provider Issuer.

Type

string

Environment Variable

SYN_OPTIC_AUTH_SAML_ISSUER

auth:saml:metadata:url

The Identity Provider url to fetch SAML IdP metadata from.

Type

string

Environment Variable

SYN_OPTIC_AUTH_SAML_METADATA_URL

auth:saml:session:length

Optionally override the SAML response expiration time to expire user sessions after the specified number of days.

Type

number

Environment Variable

SYN_OPTIC_AUTH_SAML_SESSION_LENGTH

axon

Telepath url to axon.

Type

string

Environment Variable

SYN_OPTIC_AXON

backup:dir

A directory outside the service directory where backups will be saved. Defaults to ./backups in the service storage directory.

Type

string

Environment Variable

SYN_OPTIC_BACKUP_DIR

cortex

A telepath URL to a remote cortex.

Type

string

Environment Variable

SYN_OPTIC_CORTEX

dmon:listen

A config-driven way to specify the telepath bind URL.

Type

['string', 'null']

Environment Variable

SYN_OPTIC_DMON_LISTEN

email:addr

Address to use as the sender when sending emails.

Type

string

Default Value

'optic@vertex.link'

Environment Variable

SYN_OPTIC_EMAIL_ADDR

email:auth

Object containing username and password used to login to SMTP service.

Type

object

Properties

The object expects the following properties:

{
  "properties": {
    "pass": {
      "description": "SMTP password.",
      "type": "string"
    },
    "user": {
      "description": "SMTP username.",
      "type": "string"
    }
  },
  "required": [
    "user",
    "pass"
  ]
}
Environment Variable

SYN_OPTIC_EMAIL_AUTH

email:host

Host providing SMTP for sending emails.

Type

string

Environment Variable

SYN_OPTIC_EMAIL_HOST

email:port

Port providing SMTP for sending emails.

Type

integer

Default Value

25

Environment Variable

SYN_OPTIC_EMAIL_PORT

feature:modules

Set True to enable the Modules tool. (ALPHA)

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_FEATURE_MODULES

feature:powerups

Set False to disable the Power-Ups feature.

Type

boolean

Default Value

True

Environment Variable

SYN_OPTIC_FEATURE_POWERUPS

feature:spotlight

Set True to enable the Spotlight (beta) feature.

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_FEATURE_SPOTLIGHT

feature:stories

Set False to disable the Stories tool.

Type

boolean

Default Value

True

Environment Variable

SYN_OPTIC_FEATURE_STORIES

feature:workflows

Set False to disable the Workflows (beta) feature.

Type

boolean

Default Value

True

Environment Variable

SYN_OPTIC_FEATURE_WORKFLOWS

https:headers

Headers to add to all HTTPS server responses.

Type

object

Environment Variable

SYN_OPTIC_HTTPS_HEADERS

https:port

A config-driven way to specify the HTTPS port.

Type

['integer', 'null']

Environment Variable

SYN_OPTIC_HTTPS_PORT

jsonstor

Telepath url to a synapse jsonstor.

Type

string

Environment Variable

SYN_OPTIC_JSONSTOR

login:record

Store the last login time for interactive user logins in the Cortex JSONStor.

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_LOGIN_RECORD

magic:duration

How many seconds magic links are valid for. The default is one day.

Type

integer

Default Value

86400

Environment Variable

SYN_OPTIC_MAGIC_DURATION

netloc

The URL network location used to reach the server.

Type

string

Default Value

'loop.vertex.link:4443'

Environment Variable

SYN_OPTIC_NETLOC

nexslog:en

Record all changes to a stream file on disk. Required for mirroring (on both sides).

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_NEXSLOG_EN

rum:datadog

Set True to enable Datadog RUM

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_RUM_DATADOG

rum:datadog:appId

The Datadog applicationId

Type

string

Environment Variable

SYN_OPTIC_RUM_DATADOG_APPID

rum:datadog:clientToken

The Datadog clientToken

Type

string

Environment Variable

SYN_OPTIC_RUM_DATADOG_CLIENTTOKEN

rum:datadog:env

The Datadog env ex: ‘staging-1 or ‘prod’

Type

string

Environment Variable

SYN_OPTIC_RUM_DATADOG_ENV

rum:datadog:service

The Datadog service name

Type

string

Default Value

'optic'

Environment Variable

SYN_OPTIC_RUM_DATADOG_SERVICE

rum:datadog:site

The Datadog site

Type

string

Environment Variable

SYN_OPTIC_RUM_DATADOG_SITE

rum:datadog:trackInteractions

Enable automatic interaction tracking. See documentation https://docs.datadoghq.com/real_user_monitoring/browser/tracking_user_actions/

Type

boolean

Default Value

False

Environment Variable

SYN_OPTIC_RUM_DATADOG_TRACKINTERACTIONS