SMART Flint · v0.1 foundation

Gateway, direct & handoff

Choose a FHIR transport and a single owner for the upstream credential lifecycle.

SMART Flint separates authorization and credential lifecycle from FHIR transport. You choose a mode in installation policy and when starting an activation. The application can still use its preferred FHIR library in every mode.

Decision Gateway Direct Handoff
FHIR base URL Activation-specific SMART Flint endpoint Original upstream FHIR endpoint Original upstream FHIR endpoint
FHIR bearer credential SMART Flint activation session credential Original upstream access token Original upstream access token
Upstream renewal owner SMART Flint SMART Flint Application after explicit transfer
Gateway request audit and normalization Applies Bypassed Bypassed
Original-token export policy Not needed for routine FHIR reads Must permit export Must permit compatible transfer

Gateway: managed FHIR access

The request travels from your application to SMART Flint, then to the approved EHR. SMART Flint holds upstream credentials and obtains renewed access when supported. Its activation-specific credential is distinct from the original EHR token.

const connection = await session.getFHIRConnection({ route: 'gateway' });

Use connection.baseUrl and await connection.credentials.getAuthorizationHeader() in an ordinary HTTP or FHIR client. Supported gateway interactions are metadata, JSON resource reads, version reads, and searches, including controlled pagination. The optional display-whitespace normalization profile is explicit installation behavior, not general FHIR-version conversion.

Gateway-specific policy and audit behavior apply to requests that actually pass through it. A gateway deployment does not automatically observe traffic sent directly to an EHR.

Direct: upstream transport, managed renewal

The application talks to the original FHIR server. SMART Flint supplies current upstream access credentials and remains the renewal owner.

const connection = await session.getFHIRConnection({ route: 'direct' });

Configure your FHIR client’s asynchronous authorization hook to call the credential provider whenever a request needs current credentials. Do not capture one token permanently and expect it to survive expiration. Direct browser access also requires the upstream server’s CORS policy to allow the application’s origin.

Installation policy controls token export. Disabling export prevents later retrieval even for an existing direct session. Credentials already exported remain subject to upstream expiration and revocation; closing the local SMART Flint activation does not guarantee their upstream invalidation.

Original credentials are an explicit envelope

The original-token interface preserves the upstream access-token value exactly. It returns metadata alongside the token response:

const original = await session.credentials.original();
// original.tokenResponse
// original.refreshOwner
// original.refreshTokenWithheld

The corresponding HTTP endpoint is GET /api/activations/:id/credentials/original, authenticated using the activation’s session credential. Refresh tokens are withheld while SMART Flint owns renewal. This is sensitive credential material: keep it out of URLs, analytics, logs, local storage, and error reports.

Handoff: transfer renewal ownership once

const transferred = await session.credentials.handoff();

The explicit handoff interface transfers supported credential responsibility once and returns the current refresh credential when one exists. Its HTTP endpoint is POST /api/activations/:id/credentials/handoff. Maintain exactly one refresh-token owner per grant, especially where the upstream server rotates refresh tokens.

Handoff does not export a confidential registration’s client secret or private key. Independent refresh may still require compatible client authentication on a trusted backend. A browser or public native application cannot satisfy a confidential-client requirement by embedding a static secret. Sender-constrained grants require a compatible proof adapter and are rejected by the current release.

Keep sessions and patients separate

An activation belongs to one configured connection and context. Do not store a single global current patient, connection, or token for all users or tabs. The browser SDK stores short-lived PKCE transaction material in per-tab session storage; keep activation session credentials in memory or a protected application backend.

session.close() closes local SMART Flint access. Retain a separate policy for any exported EHR tokens and upstream revocation. Refreshing upstream credentials does not extend the local activation beyond its maximum eight-hour lifetime.

Source references: SDK, security model, and architecture.