Skip to content

kastoria-smart-launch-api

A SMART on FHIR EHR Launch API service that brokers launches from an EHR into the viewer. The API acts as a SMART client, exposing the /launch, /callback, and /error endpoints under /smart/, and optionally mints the viewer JWT that scopes per-study access. It sits behind a kastoria-proxy or kastoria-proxy-mtls reverse proxy.

Runtime details

Property Value
Runtime base image kastoria-core (final stage), itself node:24-alpine
Exposed port 4000
Container user node (non-root)
Entrypoint node --import /app/smart-launch-api/src/instrumentation.js /app/smart-launch-api/src/server.js
Health check GET http://localhost:4000/health (every 30s, 5s timeout, 30s start period, 3 retries)
Stop signal SIGTERM

node_modules for npm/npx are stripped from the runtime image.

OCI labels

Label Value
org.opencontainers.image.title Smart Launch API
org.opencontainers.image.description SMART on FHIR launch API for Kastoria Health
org.opencontainers.image.licenses Proprietary
org.opencontainers.image.url https://github.com/merkalis-io/kastoria-health
org.opencontainers.image.documentation https://github.com/merkalis-io/kastoria-health
io.kastoria.health-endpoint /health

The org.opencontainers.image.version, org.opencontainers.image.revision, org.opencontainers.image.created, org.opencontainers.image.source, io.kastoria.base-image, and io.kastoria.service labels are injected at build time by the CI/CD pipeline.

Pull and verify

Promoted images are published to the Distribution Registry under the customer namespace:

docker pull acrmerkalisdist0c66.azurecr.io/<customer>/kastoria-smart-launch-api:<release-tag>
notation verify acrmerkalisdist0c66.azurecr.io/<customer>/kastoria-smart-launch-api:<release-tag>

See the Distribution Registry guide for authentication and trust setup.

Environment variables

Variable Secret Required Default Description
NODE_ENV No No production Environment; startup fails if unset.
HOST No No 0.0.0.0 Bind address; startup fails if unset.
OHIF_VIEWER_URL No Yes — OHIF viewer base URL for the SMART Launch redirect; startup fails if unset.
KASTORIA_CONFIG_JSON[1] Yes one of these — Storage configuration as an inline JSON string.
KASTORIA_CONFIG_FILE[1] No one of these — Path to a storage configuration JSON file.
PORT[2] No No 4000 HTTP port.
HTTP_PROTOCOL No No https Scheme used when deriving the redirect base URL from the request. Ignored when REDIRECT_HOST is set.
REDIRECT_HOST No No — Base URL (scheme and host) the service advertises in redirects. Set it behind a proxy or inside a container.
JWT_SIGNING_KEY[3,4] Yes No feature off RSA private key for signing the viewer JWT. Feature is off when unset. Accepts real newlines or escaped \n.
JWT_TTL_SECONDS[4] No No 3600 Viewer JWT expiry in seconds; must be a positive integer, or startup fails.
JWT_ISSUER[4] No No kastoria-smart-launch iss claim of the viewer JWT.
JWT_AUDIENCE[4] No No kastoria-health aud claim of the viewer JWT.
SHUTDOWN_HARD_TIMEOUT_MS No No 10000 Hard deadline in ms for graceful shutdown.
OTEL_ENABLED[5] No No false Set to true to enable OpenTelemetry export.
OTEL_EXPORTER_OTLP_ENDPOINT[5] No No — OTLP collector endpoint, e.g. http://otel-gateway:4317.
OTEL_DEBUG[5] No No — Set to true for verbose OTel diagnostic logging.

Per-EHR clientId and state secret are stored in the Admin Console and read from shared storage, so changing one needs no restart.

Deploying to an Azure Container Apps Environment

[1] At least one of KASTORIA_CONFIG_JSON / KASTORIA_CONFIG_FILE is required for storage initialization. If both are set the value of KASTORIA_CONFIG_JSON is used. See Configuration for the document's contents.

[2] The selected value for PORT must match the environment's ingress Target port for the container app.

[3] If JWT_SIGNING_KEY is not set (or set to an empty string), JWT token minting (JWT Authorization) is disabled.

[4] The viewer JWT minted here is verified by kastoria-health; see JWT Authorization. The values of JWT_ISSUER and JWT_AUDIENCE are copied verbatim into the JWT token's iss and aud fields, respectively, and the exp field is set to now + JWT_TTL_SECONDS.

[5] If OTEL_ENABLED is not explicitly set to true, OpenTelemetry metric/trace/logging is disabled.

Available versions

  • v0.10.0
  • v0.9.1 — deprecated for security reasons (CVE-2026-101916); use v0.10.0