Skip to content

ADR 0010: External Integration Architecture

  • Status: Accepted
  • Date: 2026-07-14
  • Supersedes: ADR 0007

Context

MedTracker serves first-party applications, local automation, hosted MCP clients, and external healthcare applications. These clients require different payloads, compatibility guarantees, credentials, and consent boundaries.

ADR 0007 established separate product and FHIR surfaces, but it was written across the delivery of SMART on FHIR. It consequently describes SMART support as both deferred and implemented. The shipped architecture now includes a registered-client SMART App Launch flow, so one current decision must replace that contradictory record.

Decision

MedTracker keeps separate integration contracts by audience. No single API is the canonical interface for every client.

Audience Contract Surface
First-party mobile applications MedTracker product API with portable IDs, household routes, session exchange, sync, and export/import /api/v1
First-party CLI and local automation MedTracker product API using API sessions or API app tokens /api/v1
Hosted MCP clients Read-only Streamable HTTP MCP using MedTracker bearer credentials /mcp
Registered third-party healthcare applications SMART App Launch 2.x standalone authorization and FHIR R4 read/search resources /authorize, /token, /revoke, and /api/fhir/R4
Browser and operator workflows Rails web UI and explicitly supported administration endpoints Web routes and /api/v1 admin routes

First-party clients use /api/v1 for MedTracker-specific workflows. FHIR is not the product synchronization API and does not replace sync batches, tombstones, encrypted portable data, household administration, or capability negotiation.

External healthcare applications use FHIR R4. They must not depend on MedTracker product payloads unless MedTracker explicitly supports them as a first-party or trusted product client.

First-party authorization

MedTracker owns the authorization context for /api/v1 and /mcp.

  • API sessions are minted after a valid MedTracker password login or external OIDC identity exchange.
  • API app tokens are created from an authenticated MedTracker profile session.
  • Each credential is bound to an account, household, membership, and membership permissions version.
  • Person access is evaluated from active grants and Pundit policy scopes.
  • Locked accounts, inactive users, revoked memberships, stale permissions, and cross-household requests fail closed.
  • The hosted MCP surface uses the same bearer boundary and remains read-only.

The external identity provider owns primary authentication, MFA, recovery, and passkeys as recorded in ADR 0005. MedTracker still owns its API session, household, grant, revocation, and audit behavior.

SMART on FHIR authorization

MedTracker supports SMART App Launch 2.x standalone launch for registered third-party healthcare applications.

The discovery document is published at /api/fhir/R4/.well-known/smart-configuration. The FHIR R4 capability statement advertises the authorization, token, and revocation endpoints.

Authorization uses the code flow. Public clients use PKCE with S256. Confidential clients also authenticate with their registered client secret. Redirect URIs are registered in advance, must use HTTPS, and are compared exactly. Authorization codes are short-lived, single-use, and bound to the client, redirect URI, and verifier.

The consent decision binds the OAuth grant to:

  • the registered application;
  • the signed-in account;
  • one active household membership and its permissions version;
  • one person context; and
  • the approved SMART scopes.

FHIR reads must pass both the SMART resource scope and the MedTracker policy scope. A scope cannot expand household or person access. Changed or revoked memberships, locked accounts, inactive users, expired grants, and revoked grants fail closed before FHIR data is returned.

Supported scopes are read-only SMART v2 patient and user scopes, including patient/*.rs, user/*.rs, and supported resource-specific forms. Access tokens expire after 15 minutes. Refresh tokens expire after 30 days and rotate on use. Revocation invalidates the complete grant.

Authorization codes, access tokens, and refresh tokens are never stored in plaintext. Token digests and PHI-free consent and revocation evidence are stored without FHIR payloads or raw credentials.

Deliberate boundaries

Only the shipped contract is advertised:

  • standalone launch is supported; EHR launch is not supported;
  • read scopes are supported; FHIR write scopes are not supported;
  • Dynamic client registration is not supported;
  • bulk-data export is not part of the SMART contract;
  • OpenID Connect identity scopes are not part of the SMART contract; and
  • /api/v1 credentials do not become SMART grants, and SMART grants do not authorize /api/v1 product operations.

Registered-client onboarding is therefore an explicit trust and operational process. Expanding any boundary above requires a new decision or an amendment that covers consent, tenant isolation, revocation, audit, and compatibility.

Consequences

Positive

  • Client teams have an unambiguous endpoint and credential choice.
  • Product sync can evolve without forcing MedTracker concepts into FHIR.
  • Third-party healthcare access uses standard discovery, consent, scopes, and FHIR payloads.
  • SMART scope checks cannot bypass MedTracker household and person policy.
  • Discovery metadata can remain truthful about the supported launch mode.

Negative

  • MedTracker maintains separate product, MCP, and FHIR documentation surfaces.
  • Clients that need both product workflows and FHIR reads require separate credentials and an explicit onboarding decision.
  • Registered SMART applications require operational client management until a deliberately designed registration workflow exists.