Skip to main content

cms-hte-ial2-reader

Reads IAL2 token, verifies digital signature and returns FHIR Patient resource

Accepts a signed JWT (ID Token) from a Credential Service Provider (CSP), verifies the signature via JWKS, extracts demographics, and returns a FHIR R4 Patient resource. Transparently accepts three token shapes, with no caller-facing difference in usage:

  • CMS-Aligned Networks CSP Payload Specification V7.1 -- flat claims.
  • TEFCA IAS SOP v3.0 -- flat claims with a different field-name vocabulary (e.g. regionality instead of region); a token missing the identity_assurance_level claim is treated as implicit IAL2 if it looks TEFCA-shaped, since the SOP guarantees IAL2 proofing as a precondition of the CSP issuing the token at all.
  • Unified Identity Token Payload (OIDC4IDA-style) -- the CMS-Aligned Networks / TEFCA working group's in-progress target format, nesting verified attributes in a verified_claims.{verification,claims} envelope. This is a discussion draft, not a finalized spec.

Usage

from cmshteial2reader import IAL2Extractor, TokenVerifier

verifier = TokenVerifier(
    jwks_uri="https://idp.example.com/.well-known/jwks.json",
    audience="my-client-id",
)
extractor = IAL2Extractor(verifier=verifier)
patient = await extractor.extract(token_string)
# patient is a FHIR R4 Patient resource dict

To accept tokens from any issuer on an explicit allow list (rather than a single pinned issuer), use MultiIssuerTokenVerifier in place of TokenVerifier:

from cmshteial2reader import IAL2Extractor, MultiIssuerTokenVerifier

verifier = MultiIssuerTokenVerifier.from_env(audience="my-client-id")
extractor = IAL2Extractor(verifier=verifier)
patient = await extractor.extract(token_string)

MultiIssuerTokenVerifier.from_env reads its whitelist of trusted JWKS URLs from the IAL2_ALLOWED_JWKS_URLS environment variable (comma-separated).

Assurance-level enforcement

IAL2Extractor requires the token's identity_assurance_level claim to be at least IAL2 (accepting values like "ial2", "IAL2", or "2") -- a token missing the claim, or asserting a lower level (e.g. "ial1"), raises InsufficientAssuranceLevelError (a subclass of TokenVerificationError, so existing callers that only catch the latter still catch this). This applies to both extract() and extract_claims(). To require a higher level, pass minimum_assurance_level to the constructor:

extractor = IAL2Extractor(verifier=verifier, minimum_assurance_level=3)

A TEFCA-dialect token (one with no identity_assurance_level claim but recognizable TEFCA-only fields such as regionality/historical_address/ ssn_last_four_digits) is only treated as implicit IAL2 -- never a higher level, since that's all the SOP guarantees -- and only after the token has already passed signature verification (and, for MultiIssuerTokenVerifier, issuer whitelisting). Raising minimum_assurance_level above 2 will reject TEFCA-dialect tokens, since they can't assert anything higher.

CMS Blue Button cms_smart extension

CMS Aligned Networks convey a patient's IAL2-verified identity by nesting a CSP-issued ID token inside the outer auth token's claims, under extensions.cms_smart.id_token (see https://bluebutton.cms.gov/cms-aligned-networks-documentation/). Callers that receive an already-verified outer JWT (e.g. from their own auth middleware) can pull out the nested token with extract_cms_smart_id_token and pass it to IAL2Extractor.extract:

from cmshteial2reader import IAL2Extractor, MultiIssuerTokenVerifier, extract_cms_smart_id_token

id_token = extract_cms_smart_id_token(outer_jwt_claims)
if id_token is not None:
    verifier = MultiIssuerTokenVerifier.from_env(audience="my-client-id")
    extractor = IAL2Extractor(verifier=verifier)
    patient = await extractor.extract(id_token)

extract_cms_smart_id_token only reads the id_token claim -- it does not verify anything, and it does not inspect or enforce purpose_of_use or version. The outer JWT must already be signature-verified by the caller, the nested id_token still needs its own verification via IAL2Extractor/TokenVerifier, and a caller that needs to gate on purpose-of-use must check claims["extensions"]["cms_smart"] itself.

Quickstart

  • make init to set up the local dev environment.
  • make up to start the Docker dev stack.
  • make tests to run tests in the dev container.

Common Tasks

  • make shell to open a shell in the dev container.
  • make run-pre-commit to run linting and formatting hooks.
  • make build to build the package artifacts.

Publishing

  • Set a token: export TWINE_PASSWORD=pypi-xxx
  • make package to publish to PyPI or make testpackage for TestPyPI.

Project Metadata

Metadata

Release files for cms-hte-ial2-reader 0.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cms-hte-ial2-reader 0.0.4
File Size Uploaded
cms_hte_ial2_reader-0.0.4.tar.gz 33.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cms-hte-ial2-reader 0.0.4
File Interpreter ABI Platform
cms_hte_ial2_reader-0.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 58.6 kB

Release files / cms_hte_ial2_reader-0.0.4.tar.gz

Download URL cms_hte_ial2_reader-0.0.4.tar.gz
Size 33.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c8283650dc4d684b687d5f5f4d5610fae862845326330fa239a1cf995c4f8802
BLAKE2b-256 checksum
How to use checksums
f89900857e74fc24114f98a957f2924d7cabf129743fdfaa7bfc817185a1daa6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / cms_hte_ial2_reader-0.0.4-py3-none-any.whl

Download URL cms_hte_ial2_reader-0.0.4-py3-none-any.whl
Size 25.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dace0f1b468afff5b9ccb023820d64c83ab3d14b614735855929967f178dcf36
BLAKE2b-256 checksum
How to use checksums
4460c0be942502223faaa8272f222ed2b2d54b0531dbd151ec055159e9ba9cd4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

0.0.5

2 release files

This release

0.0.4 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page