Skip to content

Configuration

The app is configured through environment variables. For bun run dev, bun run build and bun run start, copy .env.example to .env and adjust as needed; for the Docker image, pass them with docker run (see Docker).

The settings are read when the app starts (bun run start, docker run, bun run dev): change them, then restart the app, without building it again. The NEXT_PUBLIC_* settings reach the browser, so they are public: put no secrets in them. Values of NEXT_PUBLIC_* settings that are set when the app is built (e.g. in .env for bun run build, or on Vercel) apply where the environment of the started app doesn't set them; the Docker image is built without settings, so this doesn't apply there.

Variable Required Section
NEXT_PUBLIC_CLOUD_REGISTRY_URL yes Registry
NEXT_PUBLIC_ACCESS_PAGE_SIZE no Access dialog
NEXT_PUBLIC_INVITATION_LABEL_REQUIRED no Access dialog
NEXT_PUBLIC_APP_TITLE no Branding
NEXT_PUBLIC_APP_TITLE_SIZE no Branding
NEXT_PUBLIC_APP_TITLE_FONT no Branding
NEXT_PUBLIC_APP_LOGO no Branding
NEXT_PUBLIC_APP_LOGO_DARK no Branding
NEXT_PUBLIC_FOOTER_LOGO no Branding
NEXT_PUBLIC_FOOTER_LOGO_DARK no Branding
NEXT_PUBLIC_FOOTER_START_YEAR no Branding
LOGIN_PROVIDERS yes Login
LOGIN_REDIRECT_URI yes Login

Missing or invalid settings stop the app with a message that names the setting:

  • They stop bun run start, docker run and bun run dev; bun run build and docker build don't need them.
  • The registry URL, the issuers of the login providers and LOGIN_REDIRECT_URI must be https URLs (http only for localhost, *.localhost and loopback addresses, e.g. for development).
  • On Vercel, which deploys what it builds, they also stop the build (vercel build, or the build on Vercel's servers), so set them for every environment that builds, Preview included. vercel pull can't read sensitive variables: for those, such as LOGIN_PROVIDERS with the client secret, vercel build only checks that they are set, and checks the others as usual.

The defaults are given in each section. The login settings are described in Login, the branding in Branding.

Registry

Set NEXT_PUBLIC_CLOUD_REGISTRY_URL (required) to the registry's API, including the base path, e.g. https://registry.example.org/ga4gh/registry/v1. It must be an absolute https URL, or http for localhost and loopback addresses, without a user, password, query or fragment. Browsers call the API directly, so it must accept cross-origin requests from the app's address: the registry allows any origin by default (FOCA's security.cors).

The app's Content Security Policy lets browsers connect only to the app and to this URL's origin, and other sites can't frame the app. Scripts run only with a nonce that changes on every request, so pages are rendered per request and not cached. The policy still allows inline styles (used by components and libraries) and images from any https URL (logos). Don't let a proxy in front of the app add a second Content Security Policy: browsers enforce both, and one without the nonce blocks the app's scripts. On Vercel, the toolbar of preview deployments is blocked.

The app follows the registry's rules for registrations, as the registry publishes them in its service info (registrationRules of GET /service-info, see the registry's registration rules): the edit form offers and accepts only the environments that the registry allows (custom.endpoints.services.environments), also for services that already have another one (the registry checks them on every change), or any text if it allows any environment; it accepts only service URLs with the schemes that the registry allows (custom.endpoints.services.url_schemes); and the environment filter of the list shows the allowed environments that are in use first, in the registry's order. If the service info can't be read, or the registry publishes no rules (registries older than cloud-registry 1.0.0rc2), the edit form says so, takes any environment and any http or https service URL, and leaves the checks to the registry, which reports what it refuses when the form is sent. The app follows who may add service types (custom.access_control.service_types) and who is an admin through GET /me; the service info page shows all of the rules, and the service types page offers adding types to users other than admins only if they may have added unused types (custom.access_control.max_unused_service_types isn't 0), and names the limit in its dialog. There is nothing to set for any of these in the app: change them in the registry, and the app follows without a restart.

The registration form offers to import a service's service info, and to keep the entry in sync with it (see Importing from service info). There is nothing to set for this in the app either: the registry's settings (custom.endpoints.services.service_info, see its service info import and sync) say whether it syncs and how often, which the app reads from the service info (registrationRules.serviceInfoSync) and shows, also on the service info page. If the registry doesn't sync, the app hides sync (the option in the form, the labels and the controls of Syncing services) but keeps the import. With registries that don't publish this rule, it offers neither. Only publicly available service info can be imported or synced, as no tokens are sent: we strongly recommend that the operators of services make their service-info endpoints public, also as they tell people how to get access.

The create form (from Cloud Components) reads the environments from the service info itself: it offers those that the registry publishes, and takes any text if they allow any ([]); with older registries, it offers the four default values.

The settings NEXT_PUBLIC_SERVICE_ENVIRONMENTS and NEXT_PUBLIC_SERVICE_URL_SCHEMES of earlier versions are no longer read: if they are set, the app ignores them and logs a warning when it starts (see Upgrading).

Admin mode needs no settings in the app either; see Admins and admin mode.

Access dialog

NEXT_PUBLIC_ACCESS_PAGE_SIZE (default: 5) sets the entries per page of both tables of the Manage access dialog (see Managing access): the users and groups with a role, and the open and expired invitations. It must be a whole number of at least 1. With the default, both tabs fit a window of 1366 x 768 pixels without scrolling; with higher values, the dialog may scroll in small windows.

NEXT_PUBLIC_INVITATION_LABEL_REQUIRED (default: true) sets whether the form for new invitations requires a label, the text that says who an invitation is for (see Inviting by link). Set it to false to make the label optional; other values than true and false stop the app. The registry doesn't require labels, and renewing an invitation without a label doesn't ask for one, whichever the setting is. Labels may name people, so consider how long the registry stores them when you decide. It keeps a label as long as its invitation: with the registry's defaults, 37 days for an invitation that expires unaccepted (7 days until it expires, and 30 after that), unless an owner removes it earlier; and for an accepted one, which the app doesn't list, until it expires or the role of the user who accepted it is removed, whichever comes first. Each invitation also keeps the identifier of its creator for that time, and database backups keep all this as long as you keep them. See the registry's invitations. cloud-registry 1.0.0rc1 has no labels and refuses them: if the app meets it during an upgrade, it creates the link without the label and says so. Don't run that pairing, which gives roles to the wrong user.