# Discovery - Security for Scalable Registration, Authentication, and Authorization v3.0.0-ballot

* [**Table of Contents**](toc.md)
* **Discovery**

## Discovery

| |
| :--- |
| *Page standards status:*[Trial-use](http://hl7.org/fhir/R4/versions.html#std-process) |

The requirements in this section are applicable to both consumer-facing and B2B apps and the servers that support them. The client and the server **SHALL** conform to the underlying server metadata profile in [UDAP Server Metadata](https://www.udap.org/udap-server-metadata-stu1.html).

### Discovery of Endpoints

A FHIR Server **SHALL** make its Authorization Server’s authorization, token, and registration endpoints, and associated metadata available for discovery by client applications. Servers **SHALL** respond to `GET` requests to the following metadata URL by unregistered client applications and without requiring client authentication, where {baseURL} represents the base FHIR URL for the FHIR server: {baseURL}/.well-known/udap

The discovery workflow is summarized in the following diagram: 

UDAP metadata **SHALL** be structured as a JSON object as per Section 1 of [UDAP Server Metadata](https://www.udap.org/udap-server-metadata-stu1.html#section-1) and discussed further in [Section 2.2](discovery.md#required-udap-metadata).

If a server returns a `404 Not Found` response to a `GET` request to the UDAP metadata endpoint, the client application **SHOULD** conclude that the server does not support UDAP workflows.

### Required UDAP Metadata

The metadata returned from the UDAP metadata endpoint defined above **SHALL** represent the server’s capabilities with respect to the UDAP workflows described in this guide. If no UDAP workflows are supported, the server **SHALL** return a `404 Not Found` response to the metadata request. For elements that are represented by JSON arrays, clients **SHALL** interpret an empty array value to mean that the corresponding capability is NOT supported by the server.

| | | |
| :--- | :--- | :--- |
| `udap_versions_supported` | required | A fixed array with one string element:`["1"]` |
| `udap_profiles_supported` | required | An array of two or more strings identifying the core UDAP profiles supported by the Authorization Server. The array**SHALL**include:`"udap_dcr"`for UDAP Dynamic Client Registration, and`"udap_authn"`for UDAP JWT-Based Client Authentication.If the`grant_types_supported`parameter includes the string`"client_credentials"`, then the array**SHALL**also include:`"udap_authz"`for UDAP Client Authorization Grants using JSON Web Tokens to indicate support for Authorization Extension Objects.If the server supports the user authentication workflow described in[Section 6](user.md#tiered-oauth-for-user-authentication), then the array**SHALL**also include:`"udap_to"`for UDAP Tiered OAuth for User Authentication. |
| `udap_authorization_extensions_supported` | required | An array of zero or more recognized key names for Authorization Extension Objects supported by the Authorization Server. If the Authorization Server supports the B2B Authorization Extension Object defined in[Section 5.2.1.1](b2b.md#b2b-authorization-extension-object), then the following key name**SHALL**be included:`["hl7-b2b"]` |
| `udap_authorization_extensions_required` | conditional | An array of zero or more recognized key names for Authorization Extension Objects required by the Authorization Server in every token request. The array**SHALL NOT**include key names that are not also elements of the`udap_authorization_extensions_supported`array. This metadata parameter**SHALL**be present if the value of the`udap_authorization_extensions_supported`parameter is not an empty array. If the Authorization Server requires the B2B Authorization Extension Object defined in[Section 5.2.1.1](b2b.md#b2b-authorization-extension-object)in every token request, then the following key name**SHALL**be included:`["hl7-b2b"]` |
| `udap_certifications_supported` | required | An array of zero or more certification URIs supported by the Authorization Server, e.g.:`["https://www.example.com/udap/profiles/example-certification"]` |
| `udap_certifications_required` | conditional | An array of zero or more certification URIs required by the Authorization Server. The array**SHALL NOT**include certification URIs that are not also elements of the`udap_certifications_supported`array. This metadata parameter**SHALL**be present if the value of the`udap_certifications_supported`parameter is not an empty array. Example:`["https://www.example.com/udap/profiles/example-certification"]` |
| `grant_types_supported` | required | An array of one or more grant types supported by the Authorization Server, e.g.:`["authorization_code", "refresh_token",  "client_credentials"]`The`"refresh_token"`grant type**SHALL**only be included if the`"authorization_code"`grant type is also included. |
| `scopes_supported` | required | An array of one or more strings containing scopes supported by the Authorization Server. The server**MAY**grant different subsets of these scopes for different client types or entities. Example for a server that also supports SMART App Launch v1 scopes:`["openid", "launch/patient", "system/Patient.read", "system/AllergyIntolerance.read", "system/Procedures.read"]` |
| `authorization_endpoint` | conditional | A string containing the absolute URL of the Authorization Server's authorization endpoint. This parameter**SHALL**be present if the value of the`grant_types_supported`parameter includes the string`"authorization_code"` |
| `token_endpoint` | required | A string containing the absolute URL of the Authorization Server's token endpoint for UDAP JWT-Based Client Authentication. |
| `token_endpoint_auth_methods_supported` | required | Fixed array with one value:`["private_key_jwt"]` |
| `token_endpoint_auth_signing_alg_values_supported` | required | Array of strings identifying one or more signature algorithms supported by the Authorization Server for validation of signed JWTs submitted to the token endpoint for client authentication. For example:`["RS256", "ES384"]` |
| `registration_endpoint` | required | A string containing the absolute URL of the Authorization Server's registration endpoint. |
| `registration_endpoint_jwt_signing_alg_values_supported` | required | Array of strings identifying one or more signature algorithms supported by the Authorization Server for validation of signed software statements, certifications, and endorsements submitted to the registration endpoint. For example:`["RS256", "ES384"]` |
| `signed_metadata` | required | A string containing a JWT listing the server's endpoints, as defined in[Section 2.3](#signed-metadata-elements)below. |

FHIR servers with the same `registration_endpoint` URL belong to the same logical group. A registration for any FHIR server in this logical group registers the client application for all endpoints in that group.

The above paragraph is informational and reflects deployment models that may be encountered in the real world. This guide does not currently expect or require client applications to track registration endpoints or logical groups when determining whether or not registration is necessary, nor does it expect registration endpoint URLs published by servers to be static. Implementers should be aware of the possible side effects when different registration parameters are requested for two FHIR servers in the same logical group, i.e. the second registration at the same registration endpoint URL will modify the first registration as discussed in [Section 3.4](registration.md#modifying-and-cancelling-registrations) of this guide. Implementer feedback is requested to determine if additional client and/or server requirements relating to this topic should be added in the future.

A FHIR Server **MAY** include additional metadata elements in its metadata response as described in [UDAP Server Metadata](https://www.udap.org/udap-server-metadata-stu1.html). However, a conforming client application might not support additional metadata elements.

### Signed metadata elements

A server’s UDAP metadata **SHALL** include the `signed_metadata` element. The value of this element is a JWT constructed as described in [Section 7.1](general.md#json-web-token-jwt-requirements) and containing the claims in the table below. This JWT **SHALL** be signed using the [RS256](general.md#signature-algorithm-identifiers) signature algorithm. Metadata values conveyed in the signed metadata **SHALL** take precedence over the corresponding values conveyed using plain JSON elements.

| | | |
| :--- | :--- | :--- |
| `iss` | required | Issuer of the JWT -- unique identifying server URI. This**SHALL**match the value of a uniformResourceIdentifier entry in the Subject Alternative Name extension of the server's certificate included in the`x5c`JWT header, and**SHALL**be equal to the server's {baseURL} |
| `sub` | required | Same as`iss`. |
| `exp` | required | Expiration time integer for this JWT, expressed in seconds since the "Epoch" (1970-01-01T00:00:00Z UTC). The`exp`time**SHALL**be no more than 1 year after the value of the`iat`claim. |
| `iat` | required | Issued time integer for this JWT, expressed in seconds since the "Epoch" |
| `jti` | required | A nonce string value that uniquely identifies this JWT. See[Section 7.1.4](general.md#jwt-claims)for additional requirements regarding reuse of values. |
| `authorization_endpoint` | conditional | A string containing the absolute URL of the server's authorization endpoint,**REQUIRED**if the`authorization_endpoint`parameter is included in the unsigned metadata |
| `token_endpoint` | required | A string containing the absolute URL of the server's token endpoint |
| `registration_endpoint` | required | A string containing the absolute URL of the server's registration endpoint |

The client **SHALL** validate the signed metadata returned by the server as per Section 3 of [UDAP Server Metadata](https://www.udap.org/udap-server-metadata-stu1.html). If the signed metadata fails validation for any reason, the client **SHALL NOT** proceed with the workflows in this guide.

Note: The use of the `signed_metadata` parameter in this guide is intended to align with [Section 2.1 of RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414#section-2.1). However, the requirements specified in this section are stricter than the corresponding requirements in RFC 8414.

### Multiple Trust Communities

A server that participates in more than one trust community may be issued different certificates from each community. However, the serialization method used to sign server metadata in the previous section of this guide requires the server to select only one certificate for use in assembling the signed JWT returned for the `signed_metadata` element. This can lead to scenarios where a client application might not trust the certificate that was selected by the server, but would have trusted one of the server’s other certificates for a different trust community.

To address this, a client application **SHOULD** add the optional query parameter `community` to the metadata request URL described in [Section 2.1](discovery.md#discovery-of-endpoints) to indicate that it trusts certificates issued by the community identified by the parameter value. The value of the parameter **SHALL** be a URI as determined by the trust community for this purpose.

Servers **SHALL** support the `community` parameter. IF a client includes this parameter in its metadata request and the server recognizes the community URI, the server **SHALL** select a certificate intended for use within the identified trust community, if it has been issued such a certificate, and use that certificate when generating the signed JWT returned for the `signed_metadata` element. If a server supports different UDAP capabilities for different communities, it **MAY** also return different values for other metadata elements described in [Section 2.2](discovery.md#required-udap-metadata) as appropriate for the identified community. If the server does not recognize the community URI or does not have a suitable certificate for the identified community, it **MAY** return a `204 No Content` response to the metadata request to indicate that no UDAP workflows are supported by server in the context of that community, or it **MAY** return its default metadata, i.e. the metadata that it would have returned if the `community` parameter was not included in the request.

Note: The authors recommend that the client be prepared to handle server metadata signed with a key for a different trust community than expected, regardless if the community parameter was used. If the client cannot validate the server’s signed metadata because the server’s certificate is from a different community that is not trusted by the client, then the client will terminate the workflow as per the validation requirements in the previous section.

