Overview
Bring Your Own Identity (BYOI) lets your application authenticate the patient at Authenticator Assurance Level 2 (AAL2)
and perform identity proofing with your own supported Credential Service Provider (CSP).
In the standard TEFCA IAS flow, Fasten sends the patient to a CSP such as CLEAR or ID.me and receives
the verified ID Token directly. In BYOI mode, your application owns that CSP experience. Your backend sends a stable
patient_id to Fasten’s Identity service and receives a short-lived request_uri that can be passed into Fasten Stitch so
the patient can complete consent and provider selection.
Fasten uses the patient_id as the subject of a short-lived, Fasten-signed client assertion JWT and sends that JWT to your
registered Token Exchange endpoint. Your backend validates the assertion, uses the patient’s active CSP authorization
grant to obtain a fresh CSP ID Token, and returns the ID Token to Fasten. Fasten can repeat this exchange when another CSP
ID Token is required during a long-running or later data collection request.
BYOI is intended for organizations that have completed TEFCA subparticipant onboarding and have a CSP configured to issue
ID Tokens with the organization’s HCID in the aud claim. If you do not have that setup yet, use the standard
TEFCA IAS flow.
How It Works
- Your application authenticates the patient (AAL2) - The patient logs into their account within your product.
- Your application starts identity proofing - Your product verifies their identity with your CSP.
- Your backend stores the CSP authorization grant - Keep the patient’s CSP ID Token and refresh token on your backend.
- Your backend creates a Pushed Authorization Request - Call Fasten’s Identity service with your stable
patient_id.
- Fasten calls your preregistered Token Exchange endpoint - Fasten sends a signed client assertion whose
sub is the patient_id.
- Your endpoint validates the assertion and exchanges the active CSP grant for a fresh CSP ID Token.
- Fasten validates the CSP ID Token - The signature, issuer, expiration, audience, CSP, and environment must be valid.
- Fasten returns a
request_uri - The value is single-use, short-lived, and tied to your Fasten client.
- Your frontend launches Stitch - You pass the
request_uri into the Fasten SDK.
- Fasten collects patient consent - The patient reviews your application and authorizes access.
- The patient selects providers - Fasten searches the TEFCA network and guides the patient through selecting the healthcare organizations they want to share.
- Fasten repeats the Token Exchange when necessary - Fasten may require a newly minted CSP ID Token to retrieve records from the TEFCA Network.
The initial exchange establishes the patient’s CSP identity. Every CSP ID Token returned by a later exchange must contain
the same CSP iss and sub values. Within your organization, each patient_id must always identify the same patient and
must not be reassigned.
Supported CSPs
The idp value in your Token Exchange response identifies the CSP that issued the returned ID Token.
| CSP | idp value |
|---|
| CLEAR | clear_csp |
| ID.me | idme_csp |
| Persona | persona_csp |
The CSP must issue an unexpired OpenID Connect ID Token that Fasten can verify. The token audience must include your organization’s pre-configured HCID.
Use test credentials with synthetic CSP users and live credentials with real patient identities. Test mode rejects
non-synthetic email addresses.
Prerequisites
Before you build the BYOI flow, make sure you have:
- Registered as a TEFCA subparticipant under Fasten with our QHIN.
- Authenticated the patient at AAL2 before submitting a Pushed Authorization Request.
- An authorized CSP that can complete IAL2 identity proofing.
- A CSP integration that can issue ID Tokens with
aud set to your organization’s HCID.
- Provided your organization’s HCID to Fasten.
- Provided your HTTPS Token Exchange endpoint to Fasten.
- TEFCA IAS enabled for the Fasten API mode you are using.
- Generated a
public_* ID and matching private_* key from the Fasten Developer Portal.
Keep your private_* key and CSP credentials on your backend only.
Stable Patient Identifier
The patient_id is your stable, opaque identifier for the patient. Fasten places it in the sub claim of every client
assertion sent to your Token Exchange endpoint, allowing your backend to locate the correct CSP authorization grant.
The value must:
- Be stable and unique within your organization.
- Resolve to exactly one patient and one active CSP authorization grant.
- Never be reassigned to another patient.
- Be safe to use as an opaque identifier; do not put an email address, name, or other patient data in it.
Fasten enforces a one-to-one mapping between your organization’s patient_id and the patient’s Fasten identity. A PAR
request fails if a patient_id is already associated with a different patient or if that patient is already associated
with a different patient_id for your organization.
Keep the patient_id, CSP tokens, Fasten private key, and CSP refresh credentials on backend systems. Do not send CSP or
Fasten credentials to browser or mobile client code.
Developer Flow
1. Authenticate And Proof The Patient
Authenticate the patient at AAL2 and complete your CSP identity-proofing flow. Store the CSP authorization grant (ID Token
and refresh token) securely on your backend, indexed by the stable patient_id you send to Fasten. Your Token Exchange
endpoint uses this grant to obtain a new CSP ID Token whenever Fasten requests one.
You are responsible for managing the lifetime of the CSP ID Token and refresh token. If the underlying grant expires or
is revoked, the patient must authenticate again at AAL2 and complete any CSP authorization required to establish a new grant.
2. Create A Pushed Authorization Request
Call POST https://identity.fastenhealth.com/oauth2/par from your backend. Send an
application/x-www-form-urlencoded request using HTTP Basic authentication with your Fasten public ID and private key.
curl -X POST https://identity.fastenhealth.com/oauth2/par \
-u "public_test_xxxxxxxxxx:private_test_xxxxxxxxxx" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "scope=openid profile email" \
--data-urlencode "response_type=code" \
--data-urlencode "prompt=consent" \
--data-urlencode "redirect_uri=https://customer.example.com/callback" \
--data-urlencode "patient_id=patient_01JAZ6Y3G2M4Q8K1V7N9"
Parameters
| Parameter | Required | Description |
|---|
scope | Yes | Must be openid profile email. |
response_type | Yes | Must be code. |
prompt | Yes | Must be consent. |
redirect_uri | Yes | Must exactly match a redirect URI registered for your Fasten client. |
patient_id | Yes | Your stable, opaque identifier for the patient. |
After validating the PAR request, Fasten immediately calls your registered Token Exchange endpoint. PAR fails if the
exchange cannot be completed or the returned CSP ID Token does not pass validation.
Response
A successful request returns 201 Created.
{
"request_uri": "urn:ietf:params:oauth:request_uri:4c7f0f56-9302-4217-98d3-3b4d1e5f98ad",
"expires_in": 90
}
The request_uri is single-use and expires after 90 seconds.
3. Implement The Customer Token Exchange Endpoint
Your registered Token Exchange endpoint must:
- Use HTTPS.
- Accept
POST requests with application/x-www-form-urlencoded bodies.
- Validate the Fasten-signed client assertion before accessing CSP credentials.
- Use the assertion’s
sub claim to locate the expected patient and their active CSP grant.
- Return a newly issued CSP ID Token.
Fasten sends a request in the following form:
POST /exchange/token HTTP/1.1
Host: identity.customer.example.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange&
subject_token=eyJhbGciOiJSUzI1NiIsImtpZCI6...&
subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt&
requested_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token
The line breaks above are for readability. The actual request is a standard URL-encoded form body.
Validate Fasten’s Client Assertion
The subject_token carries a short-lived client assertion JWT signed by Fasten. Validate:
| Field | Requirement |
|---|
JOSE alg | Approved asymmetric signing algorithm. |
JOSE kid | Must resolve to an active key in Fasten’s JWKS. |
iss | Must be https://api.connect.fastenhealth.com. |
sub | Must be a valid patient_id issued by your system. |
aud | Exact URL of your registered Token Exchange endpoint. |
exp | Must be in the future and no more than five minutes after iat. |
iat | Must be within five minutes of the current time, allowing up to 60 seconds of clock skew. |
nbf | Must not be in the future beyond 60 seconds of clock skew. |
jti | Must be present, unique, and rejected if previously used. |
task_id | Optional. Present when Fasten requests an ID Token for an EHI Export or another background task. |
Cache each accepted jti until its assertion expires to prevent replay. Retrieve Fasten signing keys from
https://identity.fastenhealth.com/jwks.json and support normal key rotation. If an unknown kid is received, refresh
the JWKS once before rejecting the request.
An example decoded payload:
{
"iss": "https://api.connect.fastenhealth.com",
"sub": "patient_01JAZ6Y3G2M4Q8K1V7N9",
"aud": "https://identity.customer.example.com/exchange/token",
"exp": 1782298800,
"iat": 1782298500,
"nbf": 1782298440,
"jti": "7f13c12e-c359-46ab-b763-4ca479f566d8",
"task_id": "task_01JAZ78Q8G4H1MM2T5QF"
}
The task_id is context for logging and tracing purposes. It is optional, do not reference it for authorization;
validate the assertion signature, issuer, audience, lifetime, and replay status on every request.
Successful Response
Return 200 OK and Content-Type: application/json
{
"id_token": "<CSP-issued ID Token>",
"idp": "clear_csp"
}
The idp must identify the CSP that issued the ID Token. Supported values are clear_csp, idme_csp, and
persona_csp.
Error Responses
Return OAuth-compatible JSON errors with Cache-Control: no-store.
{
"error": "invalid_grant",
"error_description": "The patient CSP authorization has expired or was revoked."
}
| HTTP status | Error | Use when |
|---|
400 | invalid_request | Required form fields are missing, malformed, duplicated, or unsupported. |
400 | invalid_grant | The underlying CSP grant is expired, revoked, inactive, or not valid for the patient. |
400 | unsupported_grant_type | grant_type is not the RFC 8693 token-exchange grant. |
400 | invalid_target | The requested token type, CSP, audience, or resource is not allowed. |
401 | invalid_client | The Fasten client assertion is missing, invalid, expired, replayed, or signed by an untrusted key. |
429 | temporarily_unavailable | The endpoint is rate limiting Fasten. Include Retry-After. |
4. Pass The request_uri To Fasten Stitch
Initialize Fasten Stitch with the request_uri returned by the PAR response.
<fasten-stitch-element
public-id="public_test_xxxxxxxxxx"
identity-request-uri="urn:ietf:params:oauth:request_uri:4c7f0f56-9302-4217-98d3-3b4d1e5f98ad">
</fasten-stitch-element>
Redeem the request_uri immediately after your backend creates it. If the patient takes too long or refreshes the page, create a new PAR request and relaunch Stitch with the new value.
5. Handle Completion Events
Listen for the same Fasten Stitch events you use in other consent flows. Store the resulting org_connection_id and related metadata so your backend can request exports and support the patient later.
On-Demand Refresh
Fasten calls the same registered Token Exchange endpoint whenever it requires a fresh CSP ID Token. Each request contains
a newly generated Fasten-signed client assertion with the original patient_id in sub. For an EHI Export or another
background task, the assertion may also contain a task_id.
Your endpoint must return an ID Token for the same CSP identity established by the initial exchange. Fasten rejects a
refreshed token if its CSP iss or sub differs from the initial token, even if the token is otherwise valid.
Your EHI Export request only needs the Fasten API credentials and connection_id; you are not required to send a CSP ID Token in the
/ehi-export request. Fasten retrieves a fresh token from your Token Exchange endpoint when needed. If the endpoint cannot
return a valid token, collection fails and the patient must reauthenticate with your CSP.
Token Exchange endpoint implementations must be safe when Fasten retries a request or makes concurrent requests:
- Do not assume a request is delivered exactly once.
- Coordinate access to rotating CSP refresh tokens.
- Persist a replacement CSP refresh token before invalidating the previous stored value.
- Return the same successful result when safely possible, or perform another valid CSP exchange.
- Do not revoke the patient grant merely because a request timed out or was retried.
Fasten may retry temporary failures and rate-limited requests. Use Retry-After with 429 Too Many Requests or
503 Service Unavailable when Fasten should delay the next attempt.
Security And Operations
- Keep your Fasten private key on your backend.
- Keep the
patient_id stable and never associate it with a different person.
- Return CSP ID Tokens only from your backend Token Exchange endpoint.
- Treat the CSP ID Token as sensitive patient identity data.
- Fasten receives the verified ID Token, not the patient’s ID photos or CSP proofing session materials.
Implementation Checklist
- Complete TEFCA subparticipant and BYOI onboarding.
- Register the Token Exchange endpoint, organization HCID, and supported CSP with Fasten.
- Authenticate patients to AAL2.
- Issue stable, opaque, never-reassigned
patient_id values.
- Store each patient’s active CSP authorization grant securely on your backend.
- Implement Fasten client assertion validation and
jti replay protection using Fasten’s JWKS.
- Return the CSP ID Token and
idp in the Token Exchange response.
- Verify retry and concurrent-refresh behavior with rotating CSP refresh tokens.
- Re-verify the patient when the CSP grant expires or is revoked.
- Keep all Fasten and CSP credentials on backend systems.
Standards
For Fasten-managed identity proofing, see the TEFCA IAS Developer Guide.