For the complete documentation index, see llms.txt. This page is also available as Markdown.

Technical Guide

Detailed guide on how to deploy the cloud backend and frontend files on your servers.

1. BridgeXR

The BridgeXR management application consists of a simple frontend and backend. We provide everything needed to deploy both applications and an example configuration in the deployment package. Keep in mind that the provided configuration is an example and needs to be adjusted to be deployed for production use if you choose to do so. The provided configuration example showcases all mandatory settings needed to run the application.

2. Azure Integration

We provide integration with Azure Active Directory B2C SSO (3. SSO Integration), Azure Key Vault (5.2 Configuration) and Azure Blob Storage (5.1.2 Object Storage).

3. SSO Integration

3.1 Azure Active Directory B2C

In order to integrate with Azure Active Directory B2C SSO we need the following parameters:

Frontend:

  • Application (client) ID

  • Authority URL

Backend:

  • JWKS URI (found in the openid-configuration of the Azure AD B2C tenant)

For the frontend, the Application (client) ID and Authority URL are needed to configure the MSAL library used for authentication and have to be set in the msal.json found in the public directory of the supplied frontend files.

For the backend, the JWKS URI is needed to validate the tokens issued by Azure AD B2C and has to be set in the OidcKeysURL configuration key.

The API permissions needed are as follows:

  • User.Read

  • email

  • profile

The redirect URIs under Authentication need to be configured as follows:

  • Single-page application

    • https://<host>/msal-login-popup — needed for the Web Dashboard

    • http://localhost:51273/StreamingAssets/callback.html — needed for the Unity Wizard

  • Android

    • msauth://com.zoe.bridgexr.client/<hash> — needed for the Android client (for more information about the hash consult the app documentation or contact us)

  • Mobile and desktop applications

    • unityhub://editor/authentication.editorAddons.editorLink/oauth2/

    • http://localhost:8080/zoe/bridgexr/oauth2/

Refer to msal-client-application-configuration for more information.

3.2 Others

If a different SSO integration is needed, please contact us.

If no SSO integration is provided, the only way to log in is with credentials manually managed in the database. BridgeXR does not provide management facilities for user credentials.

4. Frontend

The frontend application is delivered as a folder of static files that must be served as a Single Page Application (SPA) on your own infrastructure.

The routing is handled client-side, so the web server should always return the index.html file for any unknown paths, rather than a 404.

The frontend requires /api to be mapped to the backend while stripping the /api prefix (e.g., https://frontend.local/api/foo/bar gets redirected to http[s]://backend.local/foo/bar internally).

The frontend files must be served over HTTPS, and the following headers must be set to allow the WebGPU component to work:

  • Cross-Origin-Opener-Policy: same-origin

  • Cross-Origin-Embedder-Policy: require-corp

Refer to SharedArrayBuffer#security_requirements for more information.

For files served from /WebGL/ the appropriate gzip headers must be set for the browser to transparently use the compressed files.

We provide an example nginx configuration for serving the frontend and proxying to the backend. If you use a different web server and encounter deployment issues, please contact us.

5. Backend

The backend consists of a standalone binary for x86-64-linux that can be deployed via most contemporary mechanisms. If a different target is needed, please contact us.

Configuration is handled via environment variables, configuration files, or integrations with configuration providers, as outlined in §5.2 Configuration.

There are no additional requirements regarding the deployment method, so deploying on a Virtual Machine or Container from any provider should be possible.

We provide a prefilled (as far as possible) example config file and Dockerfile for the backend. If you encounter issues running the provided binary on your chosen infrastructure, please contact us.

5.1 Dependencies on External Services

Postgres

The backend uses a Postgres database to store most of its data.

Database migrations are handled by the backend, which assumes full access to the database defined in the application's connection string.

We do not provide backups on our side, so setting up a backup strategy for the database is the responsibility of the deployer.

Object Storage

For binary data, we defer to mature object storage solutions, and provide integrations with Azure Blob Storage and S3-compatible object storage.

We do not provide backups on our side, so setting up a backup strategy for the object storage is the responsibility of the deployer.

Azure Blob Storage

We provide integration with Azure Blob Storage for storing data. If you encounter issues with our Azure Blob Storage integration, please contact us.

S3-compatible Object Storage

We provide integration with S3-compatible object storage solutions for storing data.

This is tested using MinIO and AWS S3. If you encounter issues with a different S3-compatible storage solution, please contact us.

5.2 Configuration

The backend can be configured via:

  • Configuration files (config.{json,yaml}, .env)

  • Command-line flags

  • Environment variables

  • Azure Key Vault

The specific keys which can be configured are found in the Appendix.


Appendix: Configuration Keys

Name
Description
CLI
JSON/YAML
Env/Dotenv
Azure Key Vault

Host

Host the main api server binds to

--host 0.0.0.0

{"HOST": "0.0.0.0"}

RCL_HOST=0.0.0.0

Name: host | Secret Value: 0.0.0.0

Port

Port the main api server binds to

--port 8080

{"PORT": "8080"}

RCL_PORT=8080

Name: port | Secret Value: 8080

Log Level

Log level for the server

--log-level INFO

{"LOG_LEVEL": "INFO"}

RCL_LOG_LEVEL=INFO

Name: log-level | Secret Value: INFO

Jwt Duration

Duration of JWT tokens created by the application

--jwt-duration 1h

{"JWT_DURATION": "1h"}

RCL_JWT_DURATION=1h

Name: jwt-duration | Secret Value: 1h

Refresh Duration

Duration of refresh tokens created by the application

--refresh-duration 0

{"REFRESH_DURATION": "0"}

RCL_REFRESH_DURATION=0

Name: refresh-duration | Secret Value: 0

Jwt Private Key Path

Path to JWT private key

--jwt-private-key-path /opt/jwt.pem

{"JWT_PRIVATE_KEY_PATH": "/opt/jwt.pem"}

RCL_JWT_PRIVATE_KEY_PATH=/opt/jwt.pem

Name: jwt-private-key-path | Secret Value: /opt/jwt.pem

Db Connection String

Connection string to the postgres database

--db-connection-string postgres://user:pass@localhost:5432/BridgeXR

{"DB_CONNECTION_STRING": "postgres://user:pass@localhost:5432/BridgeXR"}

RCL_DB_CONNECTION_STRING=postgres://user:pass@localhost:5432/BridgeXR

Name: db-connection-string | Secret Value: postgres://user:pass@localhost:5432/BridgeXR

Aws Endpoint

AWS endpoint parameter for S3-compatible object storage

--aws-endpoint minio.example.com:9900

{"AWS_ENDPOINT": "minio.example.com:9900"}

RCL_AWS_ENDPOINT=minio.example.com:9900

Name: aws-endpoint | Secret Value: minio.example.com:9900

Aws Access Key ID

AWS access key id parameter for S3-compatible object storage

--aws-access-key-id minio_user

{"AWS_ACCESS_KEY_ID": "minio_user"}

RCL_AWS_ACCESS_KEY_ID=minio_user

Name: aws-access-key-id | Secret Value: minio_user

Aws Secret Access Key

AWS secret access key parameter for S3-compatible object storage

--aws-secret-access-key minio_password

{"AWS_SECRET_ACCESS_KEY": "minio_password"}

RCL_AWS_SECRET_ACCESS_KEY=minio_password

Name: aws-secret-access-key | Secret Value: minio_password

Aws Bucket Name

AWS bucket parameter for S3-compatible object storage

--aws-bucket-name bridge-xr

{"AWS_BUCKET_NAME": "bridge-xr"}

RCL_AWS_BUCKET_NAME=bridge-xr

Name: aws-bucket-name | Secret Value: bridge-xr

Aws Endpoint Secure

Use HTTPS for access to S3-compatible object storage

--aws-endpoint-secure true

{"AWS_ENDPOINT_SECURE": "true"}

RCL_AWS_ENDPOINT_SECURE=true

Name: aws-endpoint-secure | Secret Value: true

Aws Endpoint Public Secure

Use HTTPS for access to the public url of the S3-compatible object storage

--aws-endpoint-public-secure true

{"AWS_ENDPOINT_PUBLIC_SECURE": "true"}

RCL_AWS_ENDPOINT_PUBLIC_SECURE=true

Name: aws-endpoint-public-secure | Secret Value: true

Key Vault Url

URL to the key vault

--key-vault-url https://example.vault.azure.net/

{"KEY_VAULT_URL": "https://example.vault.azure.net/"}

RCL_KEY_VAULT_URL=https://example.vault.azure.net/

This parameter cannot be configured via Azure Key Vault

Jwt Azure Key Name

Name of the key in Azure Key Vault used for JWT signing and verification

--jwt-azure-key-name jwt-key

{"JWT_AZURE_KEY_NAME": "jwt-key"}

RCL_JWT_AZURE_KEY_NAME=jwt-key

Name: jwt-azure-key-name | Secret Value: jwt-key

Azure Blob Container Name

Name of the Azure Blob Storage container

--azure-blob-container-name ExampleContainer

{"AZURE_BLOB_CONTAINER_NAME": "ExampleContainer"}

RCL_AZURE_BLOB_CONTAINER_NAME=ExampleContainer

Name: azure-blob-container-name | Secret Value: ExampleContainer

Azure Blob Account Name

Name of the Azure Blob Storage account

--azure-blob-account-name ExampleAccount

{"AZURE_BLOB_ACCOUNT_NAME": "ExampleAccount"}

RCL_AZURE_BLOB_ACCOUNT_NAME=ExampleAccount

Name: azure-blob-account-name | Secret Value: ExampleAccount

Azure Blob Account Key

Account key for the Azure Blob Storage account

--azure-blob-account-key ExampleKey

{"AZURE_BLOB_ACCOUNT_KEY": "ExampleKey"}

RCL_AZURE_BLOB_ACCOUNT_KEY=ExampleKey

Name: azure-blob-account-key | Secret Value: ExampleKey

Azure Blob Account URL

URL of the Azure Blob Storage account

--azure-blob-account-url https://example.blob.core.windows.net/

{"AZURE_BLOB_ACCOUNT_URL": "https://example.blob.core.windows.net/"}

RCL_AZURE_BLOB_ACCOUNT_URL=https://example.blob.core.windows.net/

Name: azure-blob-account-url | Secret Value: https://example.blob.core.windows.net/

Oidc Keys URL

URL to fetch OIDC keys used for Microsoft identity platform integration

--oidc-keys-url example.com/discovery/v2.0/keys

{"OIDC_KEYS_URL": "example.com/discovery/v2.0/keys"}

RCL_OIDC_KEYS_URL=example.com/discovery/v2.0/keys

Name: oidc-keys-url | Secret Value: example.com/discovery/v2.0/keys

Oidc Keys Refresh Interval

Interval to refresh the OIDC keys

--oidc-keys-refresh-interval 1h

{"OIDC_KEYS_REFRESH_INTERVAL": "1h"}

RCL_OIDC_KEYS_REFRESH_INTERVAL=1h

Name: oidc-keys-refresh-interval | Secret Value: 1h

Licensing Host

Host the licensing server listens on

--licensing-host

{"LICENSING_HOST": ""}

RCL_LICENSING_HOST=

Name: licensing-host | Secret Value:

Licensing Port

Port the licensing server listens on

--licensing-port

{"LICENSING_PORT": ""}

RCL_LICENSING_PORT=

Name: licensing-port | Secret Value:

Licensing Client Cert Path

Path to the licensing client certificate

--licensing-client-cert-path /opt/licensing_client_cert.pem

{"LICENSING_CLIENT_CERT_PATH": "/opt/licensing_client_cert.pem"}

RCL_LICENSING_CLIENT_CERT_PATH=/opt/licensing_client_cert.pem

Name: licensing-client-cert-path | Secret Value: /opt/licensing_client_cert.pem

Licensing Client Key Path

Path to the licensing client key

--licensing-client-key-path /opt/licensing_client_key.pem

{"LICENSING_CLIENT_KEY_PATH": "/opt/licensing_client_key.pem"}

RCL_LICENSING_CLIENT_KEY_PATH=/opt/licensing_client_key.pem

Name: licensing-client-key-path | Secret Value: /opt/licensing_client_key.pem

Last updated