Musings on healthcare IT, FHIR, EHR systems, and digital health innovation

🔥 FHIR in the hole!
Back to posts

Software Statements for the Medicare App Library

Original on LinkedIn

Why this is worth CMS’s attention

CMS Health Tech Ecosystem has dozens of Aligned Networks and a growing App Library of vetted patient-facing apps. When an app shows up at a network, how can that server tell it is a real CMS-listed app, validate its identity, and learn what policies should apply? Right now there is no shared answer, so every network embarks on a path toward inventing one: a custom portal, a certificate authority, a trust-community scheme, a registration protocol. Reading wide consensus might take a year of working-group effort and, in the meantime, a different onboarding process for every network an app wants to reach.

CMS will not make all this complexity go away. A network still runs its own registration, manages client IDs, and sets policy. What can go away is the manual re-vetting, app identification, and key collection that duplicate work CMS already conducts.

CMS already makes a trust decision by publishing apps in its App Library. This proposal asks CMS to write that decision down as a signed, verifiable artifact. A developer can carry it to a network, or a portal or API can fetch it on demand. It is a building block the rest of the ecosystem can leverage, reducing work that every network would otherwise redo for every app.

Throughout this post “network” is shorthand for a CMS Aligned Network together with the data holders participating in it: the endpoints an app actually registers with and reads data from. The same artifact is equally usable by a data holder that belongs to no Aligned Network and simply chooses to accept a CMS-signed statement.

TL;DR

For every active Medicare App Library listing, CMS should sign and publish a short-lived JWT (a software statement) recording the app’s identity, its key location, its Library status, and the data it is eligible to request, so that any CMS Aligned Network can automate app registration instead of re-vetting.

What CMS already has… (and one gap)

CMS has built almost all of the trust machinery already. App Library admission requires identity verification, FHIR R4, SMART on FHIR, integration with a CMS Aligned Network, and independent review by a recognized vetting partner. Blue Button’s CMS Aligned Network flow already authenticates apps asymmetrically: the app must be listed in the Library and must register a JWK Set URL, and its token-request JWT carries a kid resolvable at that URL.

What is missing is a way to carry that trust. Today the result of CMS’s review lives in a webpage and in a JWKS URL emailed (!) to the Blue Button team. Every other network that wants to accept the same app starts over: confirm it is really listed, collect its keys, decide what it may request. The review happened once, but the result is not portable.

Now… in a world where CMS takes this one incremental step

CMS signs the decision and publishes it. For each active app, CMS exposes a path like:

/app-library/apps/{cms_app_id}/software-statement.jwt

A CMS Aligned Network fetches it, verifies the CMS signature against CMS’s published key, and reads everything it needs to register the app. No email, no ticket, no independent re-vetting. The statement is short-lived (e.g. 24 hours); CMS stops re-issuing it the moment an app is suspended or delisted, so a stale statement cannot keep a removed app alive.

A statement looks something like this:

{
  "iss": "https://library.medicare.gov",
  "sub": "https://library.medicare.gov/app-library/apps/{cms_app_id}",
  "aud": "https://framework.cms.gov/aligned-networks",
  "iat": 1748300000,
  "exp": 1748386400,
  "software_id": "https://library.medicare.gov/app-library/apps/{cms_app_id}",
  "client_name": "Example Patient App",
  "client_uri": "https://app.example",
  "policy_uri": "https://app.example/privacy",
  "contacts": ["support@app.example"],
  "grant_types": ["client_credentials"],
  "token_endpoint_auth_method": "private_key_jwt",
  "jwks_uri": "https://app.example/.well-known/jwks.json",
  "extensions": {
    "cms_app": {
      "version": "1",
      "library_status": "active",
      "app_class": "patient-access-app"
    }
  }
}

Three things carry the weight:

  • software_id: a link back to this software’s library entry, so authorization servers can correlate registrations and stay up to date on library status
  • jwks_uri: the app’s key location, which CMS verified the app controls (a CMS nonce published at a .well-known path) and monitors thereafter. The app rotates its own keys at that URL with no CMS involvement; nothing in the statement freezes.
  • library_status: active, suspended, delisted. A network checks one field instead of re-confirming a listing.

A network consumes the statement however suits it: ingest a CMS feed of all active statements and pre-provision in bulk; accept the statement at an RFC 7591 /register endpoint as the software_statement; or have a portal pre-fill its manual form from it. Same artifact, three doors.

Runtime does not change. Apps still authenticate with private_key_jwt and a kid, exactly as cms_smart already does. The statement governs registration, not the token call.

Security note: Because the CMS statement is bound to the app’s verified jwks_uri, it is only useful to someone who controls the corresponding private keys; an attacker copying the statement still cannot authenticate. To prevent unauthorized “junk” registrations, networks can require the client to present a short-lived, self-signed JWT in the Authorization header. By verifying this token against the keys retrieved from the CMS-approved jwks_uri, the network confirms key ownership at registration time without departing from standard RFC 7591 structures.

What it removes

The statement does not replace a network’s registration; it removes the manual work inside it. Instead of confirming the listing, collecting keys, and deciding what the app may request, a network reads those facts from a CMS-signed artifact: verify one signature, read four fields. The vetting review, the key-collection email, the ticket… all that can melt away. A developer carries the statement to whatever network or portal they are registering with; a portal or API discovers it when it needs it.

It is deliberately not a certificate authority. CMS does not need to issue x509 certs, apps do not buy or manage certs, and there is no CRL or OCSP to operate. The statement is one signed JWT: a format CMS’s own services already produce and verify. That is what makes it fast: it asks CMS to publish what it already knows, in a format it already uses, not to stand up new infrastructure.

What CMS would need to do

  • Verify and record an app’s jwks_uri at admission (HTTPS-origin challenge); monitor it afterward.
  • Sign and publish one statement per active app, re-issued on a short cycle, and publish CMS’s signing key at a well-known location.

This reuses the App Library’s existing review workflow and a standard JWT signing path. It is a small, self-contained feature — the kind of thing that can be prototyped and put in front of networks quickly.

References

CMS, “Submit your app to the Medicare App Library.” https://www.cms.gov/priorities/health-technology-ecosystem/overview/medicare-app-library/submit-your-app

CMS Blue Button API, “CMS Aligned Networks Developer Documentation.” https://bluebutton.cms.gov/cms-aligned-networks-documentation/

Conversation on LinkedIn

20 comments · 39 reactionsReply on LinkedIn
  • Imran QureshiMay 26, 2026 · edited

    CTO & Chief AI Officer @ b.well Connected Health

    Interesting idea. CIMD standard already handles most of this: https://client.dev/. I think all we need is the list of apps registered in the CMS Provider Directory that are "trusted" by CMS. The networks can retrieve the rest of the info from CIMD of the app developer.

    3 reactions

    • Josh Mandel, MDAuthorMay 26, 2026 · edited

      Imran Qureshi Yes agree! This comes down to 1) predictable publication format, 2) how is it signed, 3) what metadata is included? On my view you can't really have an app decide on its own name, logo, url, etc (those need to be locked down). The software statement uses this same data model as OIDC / CIMD, but puts a CMS signature around


      Like, this guidance from CIMD is... not a basket in which you want to place many eggs:

      > Authorization servers that wish to make use of the logo_uri property within client metadata document SHOULD prefetch the file at logo_uri and cache it for the cache duration of the client metadata document. This allows for moderation tools to verify the file contents (e.g., preventing usage of logos that look like other logos), as well as preventing the logo from being dynamically changed to confuse an end- user.

    • Imran QureshiMay 26, 2026 · edited

      CTO & Chief AI Officer @ b.well Connected Health

      Josh Mandel, MD So if the app wants to change anything they have to go through an approval process with CMS which adds cost to CMS and time delay. That's why letting the app vendor control their own config via CIMD makes more sense. Same as how well-known-configuration allows a service to control its keys rather than having to store its public key in some other store.

      1 reaction

    • Josh Mandel, MDAuthorMay 26, 2026

      Sure thing: you let them self-assert everything that's not security sensitive. The rest goes through one gate (CMS) instead of 35 (each network).

    • Imran QureshiMay 26, 2026

      CTO & Chief AI Officer @ b.well Connected Health

      Josh Mandel, MD Yep, the only thing that CMS would control is whether the app vendor is trusted (i.e., the app is in the CMS approved apps list). Everything else the app vendor can self-assert via CIMD or similar mechanism that they can control and update themselves.

    • Josh Mandel, MDAuthorMay 26, 2026

      CMS Library will already list human readable app names URLs logos etc -- that stuff can all be signed over by CMS. The rest are operational details (like keys and API endpoints) that apps can/should self assert.

  • Josh Mandel, MDAuthorMay 26, 2026

    On how this relates to UDAP, TEFCA, and FAST...

    (For readers new to these: they're existing efforts for health apps and data holders to trust each other. UDAP gives each app an x509 certificate from a certificate authority; TEFCA is the national framework linking big networks; FAST is an infrastructure accelerator whose security work underpins much of TEFCA's FHIR roadmap.)

    This solves narrower problem: an app CMS already vetted, connecting inside the CMS ecosystem. For that, one CMS-signed JWT is enough, and it ships fast because CMS already signs JWTs and already runs the review. The tradeoffs of going lighter are fine for this scope and wouldn't be for a general framework. A network can accept these statements and UDAP x509 apps.

    The cms_app block is close to a UDAP certification and could later be expressed as one; v1 keeps it a plain claim set to stay minimal. The cost this avoids is obtaining and maintaining CA-issued certificates. And the proposal relies on jwks_uri because CMS Blue Button and SMART Backend Services already do; this builds on the deployed baseline and can be hardened iteratively.

    6 reactions

  • William LaolagiMay 26, 2026

    Interoperability specialist serving the state of California in Riverside and San Bernardino counties

    I need this to happen

  • Sangeet AgarwalMay 26, 2026

    Principal Software Developer | Architecting Specification-Driven Systems | .NET, React, AI

    This is interesting, one could generalize - when any trusted authority has vetted an entity then express that as a signed portable claim set / statement. Relying party in the chain then consume that decision without having to re-derive that trust, frees the network from emails & pdfs, scope though must be bounded, which you have already addressed.

  • Jacob ReiderMay 26, 2026

    Health > Care

    Seems easy enough .. hey Zac Jiwa .. can you get this up and running by June 1? Por favor?

    3 reactions

  • Josh Mandel, MDAuthorMay 27, 2026 · edited

    Imran Qureshi (summing up here because LI makes comment threads so hard): Agreed on the main point. Apps should be able to self-assert most of their config themselves. CIMD is a good mechanism for that... and for networks that use dynamic registration, apps can just populate these self-asserted details in their dynreg request. The two are ~equivalent from a trust perspective. The approach I'm proposing for a CMS signature is deliberately narrow: just the handful of identity details CMS already publishes in the Library (app name, URLs, logo, etc.). Keys, API endpoints, and other operational details are exactly the things apps can and should self-assert.

    And to be clear, this doesn't prevent apps from publishing their own updates independently of CMS. The CMS-signed statement is just *one more piece of information* the ecosystem can choose to rely on, not a gate on anything.

    On the update-cost concern: realistically, when your app changes its name, updating that with the CMS Library is the right thing to do anyway, and it's one update instead of 35 across every network.

    1 reaction

    • Bret Heale, PhDMay 29, 2026

      Solutions Architect, Precision Medicine, Biomedical Informatics

      Josh Mandel, MD can't wait till the CapabilityStatement enables machine to machine dynamic adjustments to interactions for seamless reconfiguring....but first the CapabilityStatement needs to be accurate...

  • Fredrik LindénMay 27, 2026

    Cofounder of MyData.org Not for profit - Digital Government Transformation and Senior Consultant.

    Is this a good idea for global interoperability? George J Padayatti Vadim Peretokin Lal Chandran

    1 reaction

  • Founder, Stratevora Technologies | Enterprise AI Strategy & Governance | Board Director & Advisor | Speaker | Co-Author, Saving Rural Hospitals.

    A simple administrative tweak at the top can spark more software innovation than millions of dollars in federal grants.

    1 reaction

  • Alan ViarsMay 27, 2026

    Helping the government sort out identity and health data issues one line at a time.

    Josh Mandel, MD I wholeheartedly agree with this approach!

    1 reaction

  • Healthcare AI & Data Solutions Leader | CDMP, CPMAI, PMP

    Thanks for posting this Josh. Brings back memories of NATE and the work we attempted to do ten years ago to reduce friction in trusting independently vetted consumer controlled apps.

    2 reactions

  • Gerard ReederMay 29, 2026

    Founder & CEO, XHealth Nexus | Patient-Authorized Longitudinal Health Data Platform | Former SSA-NHIN Public-Private Partnership Lead

    Excellent framing. The point that “the review happened once, but the result is not portable” feels especially important as interoperability workflows continue scaling across networks.
    Reducing repeated onboarding, trust validation, and operational friction could significantly accelerate real-world adoption inside the CMS ecosystem.

  • Alan ViarsMay 30, 2026

    Helping the government sort out identity and health data issues one line at a time.

    The notion of signing software statements as JWTs is a good idea! About 10 years ago, when Blue Button 2.0 was still in development, Mark Scrimshire and I encouraged CMS to do something similar. something similar, but it didn't get any buy in. I'm glad you are surfacing it again. https://github.com/TransparentHealth/poet. This creates a path for Dynamic client registration protocol to work at scale in healthcare.

    1 reaction

  • Alan ViarsMay 30, 2026 · edited

    Helping the government sort out identity and health data issues one line at a time.

    In general, I think there should be a lot more publishing of machine-readable documents for discovery in healthcare. Things that go in "http://example.com/.well-known" are another example of a similar design pattern. See https://datatracker.ietf.org/doc/html/rfc8615 for reference. Discovery documents can be JSON or signed artifacts as you describe for Medicare Apps. Provider directories could/should work in a similar way IMHO.

    1 reaction