# README

UHC-Logo

Go to main

OpenID Utils

This package contains funtions, structs and methods to implement OIDC and FAPI.

OIDC (OpenID Connect)

OpenID is an open standard and decentralized authentication protocol promoted by the non-profit OpenID Foundation. It allows users to be authenticated by co-operating sites (known as relying parties, or RP) using a third-party OpenID provider service (OP).

OIDC is an identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the End-User. Specifically, a system entity called an OpenID Provider (OP) can issue JSON-formatted identity tokens and verified claims to OIDC relying parties (RP) via a RESTful HTTP API (the OP is the an identity service). The OP establishes trust with other applications and services while using a single digital identity (it can be a DID with a universal health identifier for training and health).

Federated identity is a way to use an account from one identity service (OP) to create an account and log in to a different site. There are two main players in a federated identity system: an OpenID Provider (OP) and a Service Provider (SP), which is a relaying party (RP, e.g.: an API service distinct to the OP).

OIDC Issuer Discovery

OIDC Issuer discovery is the process of determining the location of the OpenID Provider. It is optional in case of a Relying Party (e.g.: a client app) can know the OP's Issuer location through an out-of-band mechanism. For example, a DIDComm OOB message encoded in a QR code can be scanned by a client app to get the configuration information of an OIDC Issuer.

When a client app have to retrieve online the configuration information of an OIDC Issuer, it is required to be accesible in the Issuer's well-known location, e.g.: https://identity.organization-name.example.com/.well-known/openid-configuration. This discovery document has the "issuer" endpoint, which is the OICD Issuer URL (https URL scheme with no query or fragment component, e.g.: https://identity.organization-name.example.com/). Both access tokens and responses issued will contain the Issuer URL in the "iss" payload's field, and all the requests and access tokens accepted by the Issuer (FAPI Security Profile 1.0 - Advanced) will contain at least this Issuer URL in the audience field ("aud").

Financial-grade API (FAPI)

Financial-grade API (FAPI) is an industry-led specification developed by the OpenID Foundation.

While the FAPI 2.0 Security Profile was initially developed with a focus on financial applications, it is designed to be universally applicable for protecting APIs exposing high-value and sensitive (personal and other) data, for example, in e-health and e-government applications.

FAPI utilizes both JWT-secured authorisation request (JAR) and JWT-secured authorisation response (JARM).

JWT-secured authorisation request (JAR)

When using the HTTP protocol and the HTTP POST method, the parameters of the HTTP request are serialized using Form Serialization (OICD Core - Section 13.2).

The HTTP header Content-type is application/x-www-form-urlencoded.

Although different parameters are required as per OAuth 2.0, OpenID and JAR specifications, FAPI ignore all except the "request" parameter, which in FAPI it is a compact JWS containing the Request Object as payload.

The parameters for the HTTP request are explained below:

  • "request": the JWT data container, named "Request Object", in compact JWT serialization.

  • "client_id": duplicated from the Request Object's payload (required by Section 5 of JAR, but ignored by FAPI and UHC).

Additionally, if the client app is not using pushed authentication request (PAR), the client app can send duplicates of the "response_type" and "scope" parameters/values using the OAuth 2.0 request syntax as required by Section 6.1 of the OpenID Connect specification, but they are ignored by FAPI and UHC specifications.

JWT-secured authorisation response (JARM)

The JWT data container is named "Response Document". The Response Document can be sent in an HTTP response in two different ways, depending on the "response_type" property specified in the JAR:

  • As a Redirect URL, with the Response Document in compact JWT as the "response" parameter.

  • As a Form Post Response, where the OP returns an HTML web page containing an HTML form with the Response Document in compact JWT as the "response" parameter in the HTML form. The HTML web page contains a script to cause the auto-submission of the form the Client software application, so the Client will be able to process the message without regard for the mechanism by which the form submission was initiated.

UHC messaging encapsulation

UHC extends OIDC and FAPI with both DIDComm and JSON:API specificactions and uses Post-Quantum Computing (PQC) algorithms instead of the traditional non-PQC resistant ones. See DIDComm Utils.

# Functions

CheckAudience checks both the received audience(s) contains URLs ("http://" is allows only for localhost and "https" is required for other URLs) and the audience claim list contains the expected audience (but only it "expected" is not an empty string).
CheckBearerHeaderDataJWT returns DataJWT (can be nil) and error message (can be empty) after checking: - mandatory fields exist in the Access Token header ("alg", "jwk", "typ") and are supported.
CheckBearerPayloadDataJWT checks the mandatory fields exist and additionally match with the provided ones (optional): - "aud": Audience of the JWT, in UHC it is the "software_id" (app URL) for the "client_id" (profile role) - "iss": Issuer organization's identity DID.
CheckCodeChallengeLength checks the "code_challenge" is between 43 and 128 characters as per the OpenID specification (it is the SHA-256 hash result of a random challenge generated by the client application, base64url encoded).
CheckCompactAccessToken returns DataJWT (can be nil) and error message (can be empty) after checking: - mandatory fields exist in the DPoP header ("alg", "kid", "typ") and are supported.
CheckCompactDPoP returns DataJWT (can be nil) and error message (can be empty) after checking: - mandatory fields exist in the DPoP header ("alg", "jwk", "typ") and are supported.
CheckDataAccessToken returns DataJWT (can be nil) and error message (can be empty) after checking: - mandatory fields exist in the Access Token header ("alg", "jwk", "typ") and are supported.
CheckDataDPoP returns DataJWT (can be nil) and error message (can be empty) after checking: - mandatory fields exist in the DPoP header ("alg", "jwk", "typ") and are supported.
CheckDPoPTokenHeaderDataJWT checks that the mandatory fields exist ("alg", "jwk", "typ") and are supported.
CheckDPoPTokenPayloadDataJWT checks that the mandatory fields exist ("htm", "htu", "iat", "jti" and additionally: - the "ath" value which is the SHA-256 [SHS] hash of the ASCII encoding of the access token.
CheckIssuerDidKidURI checks the "iss" URI is a DID with a keyID fragment (#).
CheckRequiredScopes generates an slice (array) with each of the matched scopes and returns true if the length of the resulting slice is equal to the length of the required scopes slice.
CheckTimeValidation cheks both: - the "nbf" field is no longer than 60 minutes in the past.
CreateResponseRedirectedUrlQueryJARM returns a HTTP Redirect URL with an OpenID Response Object in compact JWT format (JWS/JWE) concatenated to the redirect URI as "<redirect_URI>?response=<the_compact_JWT>" where the JARM Response Object contains the data in the payload.
CreateResponseRedirectUrlFragmentJARM returns a HTTP Redirect URL with an OpenID Response Object in compact JWT format (JWS/JWE) concatenated to the redirect URI as "<redirect_URI>#response=<the_compact_JWT>" where the JARM Response Object contains the data in the payload.
GetAudiences converts audience claim to string slice, with compatibility not only for comma separated but for comma-space and space too.
GetScopesList converts scope claim to string slice, with compatibility not only for space separated but for comma and comma-space too.
ParseAudiences joins the slice into a whitespace-separated string.
ParseScopes joins the slice into a whitespace-separated string.
ResponseDocumentByResponseType writes an HTTP JARM Response based on the ResponseType sent in the Request - code: it returns a Redirect URI concatenated with fragment ("#") - token: it returns a Redirect URI concatenated with a query ("?") - didcomm-uhc+json: returns a DIDComm v2 message signed and optionally encrypted based on the Registered Client App.

# Constants

AccessTokenHeaderType definition: https://datatracker.ietf.org/doc/html/rfc9068#section-2 The "typ" value used SHOULD be "at+jwt", preventing OpenID Connect ID Tokens from being accepted as access tokens.
No description provided by the author
No description provided by the author

# Variables

It returns the standardized OpenID properties.
It returns the standardized OAuth2 properties.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
due to a temporary overloading or maintenance of the server.
No description provided by the author
No description provided by the author
TODO: review audience.
No description provided by the author
https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseExample https://github.com/joncalhoun/form.
https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html#FormPostResponseExample https://github.com/joncalhoun/form.

# Structs

OpenidHeadersAccessToken structure.
AccessTokenPayload structure.
No description provided by the author
No description provided by the author
DescriptorMapping has - 'id' property.
DPoPHeader structure.
DPoPPayload structure.
JARHeader only contains data that can be sent by bluetooth: - decoded "Bearer" Access Token (to check scopes).
JWTCredClaims is JWT Claims extension by Verifiable CredentialAries (with custom "vc" claim).
using snake_case because of JWT standard claims: https://www.iana.org/assignments/jwt/jwt.xhtml#claims.
OpenidClientAppConfig TODO: ClientID will be always the ReverseDNS?.
see https://www.iana.org/assignments/jose/jose.xhtml.
see https://pkg.go.dev/go.step.sm/crypto and https://www.iana.org/assignments/jwt/jwt.xhtml urn:ietf:params:oauth:token-type:jwt and IANA "application/jwt" OpenidPayload represents public claim values (as specified in RFC 7519).
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata - issuer: REQUIRED.
No description provided by the author
PresentationDefinition properties are for use at the top-level of a Presentation Definition.
The PresentationInputConstraintsFields object MAY contain - MUST contain a path property.
The PresentationInputConstraints object MAY contain - fields property: SHALL be processed forward from 0-index, so if a Verifier desires to reduce processing by checking the most defining characteristics of a credential (e.g the type or schema of a credential) implementers SHOULD order these field checks before all others to ensure earliest termination of evaluation.
PresentationInputDescriptor fields are required for submission, unless otherwise specified by a Feature.
No description provided by the author
No description provided by the author
No description provided by the author
PresentationSubmission are objects embedded within target Claim negotiation formats that express how the inputs presented as proofs to a Verifier are provided in accordance with the requirements specified in a Presentation Definition.
The credential endpoint issues an approved credential to the end user by presenting a valid access token that represents this approval.
No description provided by the author
No description provided by the author
* Step 3.A: * App exchanges authorization code for access token * After obtaining an authorization code, the app trades the code for an access token via HttpHeaders POST to the EHR authorization server’s token endpoint URL, using content-type application/x-www-form-urlencoded, as described in section 4.1.3 of RFC6749.
No description provided by the author
* Step 3.B: * Confidential app in a registered device uses Asymmetric Authentication * and sends a NestedJWT instead of doing the Authorize Code flow (skip steps from 1 to 3.A) */.
* Step 1: * At launch time, the app constructs a request for authorization by supplying the following parameters to the EHR’s “authorize” endpoint.
No description provided by the author
No description provided by the author
* Step 4: * The EHR authorization server SHALL return a JSON object that includes an access token or a message indicating that the authorization request has been denied.
* Step 2: * When the EHR decides grant access it is communicated to the app returning an authorization code (or, if denying access, an error response).
using snake_case because of JWT standard claims: https://www.iana.org/assignments/jwt/jwt.xhtml#claims.

# Type aliases

Claims defines JSON Web Token Claims (https://tools.ietf.org/html/rfc7519#section-4).