-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Advanced flow #52
Advanced flow #52
Conversation
Plain JSON request doesn't seems to satisfy the eudi wallet requirements but I think that openid4vp Will be used also for other Networks and use cases The wallet that send a plain JSON request to an RP that doesn't support it should obtain a 400 http error with the error identifier and an error_description |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A more accurate revision Is needed, there are some details to be further explored and consolidated but I like the main line, in particular the way the nonce is provided. At a first glance!
@@ -215,6 +215,53 @@ Figure: Cross Device Flow | |||
|
|||
(3) The Wallet prepares the Verifiable Presentation(s) of the Verifiable Credential(s) that the End-User has consented to. It then sends to the Verifier an Authorization Response where the Verifiable Presentation(s) are contained in the `vp_token` parameter. | |||
|
|||
## Advanced Flow with Wallet Capabilities Discovery {#adv_flow} | |||
|
|||
Below is a diagram of a flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device as the device the Wallet resides on. In this case, the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular wallet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Below is a diagram of a flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device as the device the Wallet resides on. In this case, the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular wallet. | |
Below is a diagram of a flow where the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of Wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular Wallet. This example uses cross-device flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device as the device the Wallet resides on. |
I would emphasize the wallet capability selection part as opposed to starting with cross-device description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"different device as the device the Wallet resides on" -> "different device than the device that the Wallet resides on" maybe reads more clearly (or maybe it's just me). So:
Below is a diagram of a flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device as the device the Wallet resides on. In this case, the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular wallet. | |
Below is a diagram of a flow where the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of Wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular Wallet. This example uses cross-device flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device than the device that the Wallet resides on. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a mistake, as the flow obviously is same device.
The sentence (and with that the order of things) was copied from the other flows. It just spells out the fact that this is a same device flow.
Changed the text to refer to the same device flow instead of duplicating text.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please check
{ | ||
"presentation_request_uri": "verifier.example.com/presentation_request", | ||
"context": "register_kyc" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could these kind of small examples be in the text and not as a separate file..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this file even used? looks like it's inline already at https://github.com/openid/OpenID4VP/pull/52/files?diff=unified&w=0#diff-3118c9756a1d7b361bb53af8bd9d65666476a27cfeeced56c47a5dccc38eac55R294
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is inline, I just used to file to format the example - can remove it once we merge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you
@@ -215,6 +215,53 @@ Figure: Cross Device Flow | |||
|
|||
(3) The Wallet prepares the Verifiable Presentation(s) of the Verifiable Credential(s) that the End-User has consented to. It then sends to the Verifier an Authorization Response where the Verifiable Presentation(s) are contained in the `vp_token` parameter. | |||
|
|||
## Advanced Flow with Wallet Capabilities Discovery {#adv_flow} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## Advanced Flow with Wallet Capabilities Discovery {#adv_flow} | |
## Cross Device Flow with Wallet Capabilities Discovery {#adv_flow} |
Not sure I am a big fan of "advance flow" term - feels too abstract.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'd tend to not use comparative terms like advanced or High or anything that might produce a relation or reference to something lower or feature-less
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the way this section is written right now does not exactly convey why this is an "advanced" flow. maybe i am misunderstanding something but I would expect more focus on the new ability for the wallet to communicate its capabilities/endpoint/attestation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Advanced is the title of the PR, now it seems it will be a discovery (pre-step). Changed title and first sentence.
@@ -215,6 +215,53 @@ Figure: Cross Device Flow | |||
|
|||
(3) The Wallet prepares the Verifiable Presentation(s) of the Verifiable Credential(s) that the End-User has consented to. It then sends to the Verifier an Authorization Response where the Verifiable Presentation(s) are contained in the `vp_token` parameter. | |||
|
|||
## Advanced Flow with Wallet Capabilities Discovery {#adv_flow} | |||
|
|||
Below is a diagram of a flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device as the device the Wallet resides on. In this case, the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular wallet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Below is a diagram of a flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device as the device the Wallet resides on. In this case, the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular wallet. | |
Below is a diagram of a flow where the Verifier starts the flow by discovering the Wallet's capabilities through an additional message exchange. This is especially useful, if the Verifier starts the process using a URL serving as alias for a group of Wallets (e.g. a custom scheme) but would like to tailor the presentation request to the particular Wallet. This example uses cross-device flow where the End-User presents a Credential to a Verifier interacting with the End-User on a different device as the device the Wallet resides on. |
I would emphasize the wallet capability selection part as opposed to starting with cross-device description.
Here are the elements that come to mind:
I would like to simplify and at the same time give more guidance to the implementers, then I would remove This is the flow that I have in mind: |
WDYT about changinc the name from "Advanced flow" to "Wallet |
| | (Presentation Request URI) | | ||
| |-------------------------------------------------->| | ||
| | | | ||
| | (2) Request the Request Object | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think (2) is mainly a "Discovery Response", that also happens to trigger request object from the verifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| | (2) Request the Request Object | | |
| | (2) Discovery Response | | |
| |(Wallet's endpoint, capabilities, Attestation, etc)| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is discovery, but the result is a request object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this reminds me the italian flow where we have mixed the provisioning of the wia with DPoP to the request_uri endpoint.
We are looking for a better specialization of the endpoints, then the proposed, alternative, flow was provided in this comment: #52 (comment)
| |<--------------------------------------------------| | ||
~~~ | ||
!--- | ||
Figure: Cross Device Flow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Figure: Cross Device Flow | |
Figure: Wallet Discovery Flow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to "Same Device Flow with Wallet Capabilities Discovery"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to cover both cross device and same device within this PR
an alternative flow was provided aiming to satisfy this: #52 (comment)
@@ -228,6 +275,84 @@ OpenID for Verifiable Presentations extends existing OAuth 2.0 mechanisms as fol | |||
|
|||
Presentation of Verifiable Credentials using OpenID for Verifiable Presentations can be combined with the user authentication using [@SIOPv2], and the issuance of OAuth 2.0 Access Tokens. | |||
|
|||
# Discovery Request | |||
|
|||
The Discovery Request allows Verifers to discover the Wallet's capabilities before they create the actual presentation request. It also allows the Wallet to authenticate towards the Verifier and to provide the Verifier with additional data used in the creation of the request signature and to encrypt the request at the application layer (if needed). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Discovery Request allows Verifers to discover the Wallet's capabilities before they create the actual presentation request. It also allows the Wallet to authenticate towards the Verifier and to provide the Verifier with additional data used in the creation of the request signature and to encrypt the request at the application layer (if needed). | |
The Discovery Request allows Verifeirs to discover the information about the Wallet before creating the actual presentation request. It allows the Wallet to optionally authenticate towards the Verifier and to provide with additional data such as its endpoint and capabilities. This enables the Verifier to sign the request using the algorithm that the Wallet is guaranteed to support and if needed encrypt the request at the application layer. |
in my mind, wallet's endpoint, wallet's capabilities, and wallet attestation are three different things, and I am not sure "wallet capabilities" can be used to express them all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume that the wallet instance attestation contains the wallet's capabilities, materially defined with:
- cnf.jwk (any other cnf.*)
- NiST's AAL (the equivalence of the italian
attested_security_contexts
) - Authorization Server metadata
- other wallet instance metadata, as client_metadata when a wallet instance acts like a Verifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sakurann those three things are differentiated in the current text. wallet capabilities is in the first sentence, authentication in the second sentence
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peppelinux I assume the capabilities are conveyed using wallet metadata. I agree, there can be other ways. Let's discuss how we can support them.
`presentation_request_uri`: | ||
: A string containing an HTTPS URL pointing to a resource under the control of the Verifier where the Wallet is supposed to obtain the presentation request object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think presentation_request_uri
parameter name could be more explicit and differentiate it more clearly from request_uri
in rfc9101..? something like discovery_and_request_uri
(yes, I know i am not brilliant at names)?
I would also borrow some language from https://www.rfc-editor.org/rfc/rfc9101#section-5-2.4 like
`presentation_request_uri`: | |
: A string containing an HTTPS URL pointing to a resource under the control of the Verifier where the Wallet is supposed to obtain the presentation request object. | |
`presentation_request_uri`: | |
: The absolute URI, as defined by [RFC 3986](https://www.rfc-editor.org/rfc/rfc9101#RFC3986) [[RFC3986](https://www.rfc-editor.org/rfc/rfc9101#RFC3986)], that receives data from the Wallet such as endpoint, capabilities and attestation and returns the [Request Object](https://www.rfc-editor.org/rfc/rfc9101#name-request-object) containing the authorization request parameters defined in [Section 5](https://openid.bitbucket.io/connect/openid-4-verifiable-presentations-1_0.html#section-5). |
not sure we need If this parameter is present in the authorization request, request MUST NOT be present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not in favor of discovery AND request, since I assume that there might be cases where a wallet solution doesn't support the discovery feature then the request_uri endpoint should be untouched
I assume, according to my implementations, that the RP that can't assert the wallet capabilities should attests to the wallet instance the lowest level of security, if supported for the requirements of the LoA, and using a standard/defined/wellknown and common capabilities for the wallet ecosystems
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea in the PR is to have a new endpoint (the presentation endpoint) that bundles discovery and request creation. We could also split this into discovery and request_uri. However I would like to understand the consequences. What directly comes to mind is that the state must be kept at the verifier between the two requests whereas the current design allows the verifier to create the request and directly release it to the wallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Sakurann I suggest to call it fetch_presentation_request_uri
(see my comment further up) as the current name is not correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm for discovery_response_uri
where the HTTP response could be 302 Found with the discovery_state that binds the discovery to the request issuance
then we have divided the endpoints by using the request_uri endpoint with the sole addition of the discovery_state that allows the RP to do its lookups. This value could be also encrypted (depending by what would cost more in an infrastructure: CPU or Storage!)
`context`: | ||
: A string identifying the context of the discovery request from the perspective of the Verifier. The value is opqaue to the Wallet, it MUST pass this value to the Presentation Endpoint Request (see below). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is best to avoid using a term context
in anything issuer-holder-verifier model related... (because it has a very specific meaning in w3c vcdm)
`context`: | |
: A string identifying the context of the discovery request from the perspective of the Verifier. The value is opqaue to the Wallet, it MUST pass this value to the Presentation Endpoint Request (see below). | |
`verifier_state`: | |
: A value opaque to the Wallet used by the Verifier to maintain state between discovery request and response. When received, the Wallet MUST pass this value to the Presentation Endpoint. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I intentionally did not designate it as state as it is intended to be used to label the context ("entrance to east wing") and not carry a certain state of a certain transaction. This allows to use the same discovery request for multiple transactions (print it out and put it onto the wall).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is good to use something distinct from state
(and I agree with Torsten's arguments). context
feels ok to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fully agree with Kristina, context
is something too much related to other specs and schemas.
I propose discovery_state
with the will to keep the words always on the same direction, the good semantic help us to reduce the brain stress
```JSON | ||
{ | ||
"presentation_request_uri": "verifier.example.com/presentation_request", | ||
"context": "register_kyc" | ||
} | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to note that parameter names might change based on the comments above.
|
||
Note: the Discovery Request intentionally does not use OAuth parameters, such as a `client_id`. The idea is to allow the Verifier to select the Client Identifier it wants to use for interacting with the Wallet after it has determined the trust mechanisms and domains the wallet supports. | ||
|
||
## Discovery Endpoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this section needs to be in the Verifier Metadata section https://openid.bitbucket.io/connect/openid-4-verifiable-presentations-1_0.html#name-wallet-metadata-authorizati and not here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This endpoint is not the typical static "get some metadata" endpoint. It is part of the application logic of the wallet. I therefore added it here. I think this is the best solution for readability and understandability.
Co-authored-by: Giuseppe De Marco <giuseppe.demarco@teamdigitale.governo.it>
…nto advanced_flow
I would like to avoid parameter names causing the impression this parameter should be transaction specific. My idea is to allow for static values so this request could be printed out and put on a wall. The context shall then identify the place where the verifier wants to use the VP. I changed the name to
protected is pretty generic and holds true for a lot of HTTPS resources
I added text saying metadata MAY be obtained from the AS metadata, but they MAY also be obtained by other means, e.g. as part of the wallet attestation |
@peppelinux @paulbastian @David-Chadwick @danielfett It seems the most significant issue right now is the question whether the wallet should send data to the verifier before the verifier is authenticated. I see the following options: Option 1: sign the discovery request: that is feasible from a technical standpoint. However, what scheme, what trust framework, and which key should the verifier use? The design assume the verifier will have the require data provided in the presentation request. This allows multi homing verifiers, those connected to a US, a EU, and a JP trust framework. Option 2: leave the protocol as is and add privacy considerations recommending a user gesture before the presentation request is sent to the verifier (e.g. the unlock of the wallet). That would at least prevent silent finger printing. Option 3: send minimal data to the presentation endpoint, e.g. static profile data. Wallet authentication might happen at the direct post. Please let me know what you think. |
at least
That's good. Because we assume that a specific wallet instance installed on a specific hardware may support a subset of algs supported by wallet solution. Therefore, the Wallet Solution may issue a specific Wallet Instance Attestation containing the tailored capabilities regarding a specific wallet instance.
I'm in favor of this. The issue of selecting the trust framework is common to all the signed attestations defines in the OpenID4VC suite. Then I would not see this issue for this flow in particular and I would suggest to keep this out of the scope of this PR.
Too weak from my perspective, since users must be "protected" by their wallet instance.
I would say that this would be too late for the RP, because it should not sign nothing or evaluate nothing before having attested the reliability of the wallet instance, considering also that the wallet capabilities may be provided within the wallet instance attestation, that's the scope of the current PR (Providing the wallet instance attestation before the issuance of RP's signed request). |
@tlodderstedt
|
@@ -126,7 +126,9 @@ This specification supports any Credential format used in the Issuer-Holder-Veri | |||
|
|||
Implementations can use any pre-existing OAuth 2.0 Grant Type and Response Type in conjunction with this specification to support different deployment architectures. | |||
|
|||
OpenID for Verifiable Presentations supports scenarios where the Authorization Request is sent both when the Verifier is interacting with the End-User using the device that is the same or different from the device on which requested Credential(s) are stored. | |||
OpenID for Verifiable Presentations supports scenarios where the Authorization Request is sent both when the Verifier is interacting with the End-User using the device that is the same or different from the device on which requested Credential(s) are stored. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpenID for Verifiable Presentations supports scenarios where the Authorization Request is sent both when the Verifier is interacting with the End-User using the device that is the same or different from the device on which requested Credential(s) are stored. | |
OpenID for Verifiable Presentations supports the scenario in which the Verifier sends an Authorization Request to an End-User using either the same or different device from which the requested Credential(s) are stored. |
how's this?
@David-Chadwick what is your opinion on the three options I proposed? |
@tlodderstedt My opinion is that none of the solutions are optimum because they are not addressing the critical issue, which is "is the verifier trusted". So none of your solutions are what is actually needed. I gave you a much longer answer above explaining why authenticating the verifier is not sufficient, because an authenticated crook is still a crook. |
Option 1 looks pretty ugly to me and we have 2 steps of Verifier authentication. |
Hi all, in the WG call yesterday we felt it is best to go one step back and decide whether we want to fulfill the following requirement. Should the protocol allow the verifier to pick client id scheme and credentials based on the data received from the wallet in the presentation request (step 4 in the sequence diagram)? This requirement determines whether authentication (and further steps) can be done in the initial discovery request or not. Please share your opinion. |
My opinion is that the discovery request message should provide enough information for the user's device to determine if the verifier's asserted name/id can be trusted or not, based on information provided in the discovery request message (which does not need to be authenticated). |
@David-Chadwick would you assume the verifier provide different identifers? I'm asking since the client could use different identifiers in different trust frameworks. |
On the Thurs call Torsten suggested that wallet authentication/attestation wasn't need in the presentation flow (which I think I agree with) but that some kind of attestation might be necessary with SIOP for user authentication. That suggests that whatever attestation is needed there should be added in SIOP (maybe part of the id token) but not be part of this work/design. |
@tlodderstedt The verifier should know what trust frameworks it is registered in (at least this is a reasonable assumption to make, because there will be some rules that the verifier will have to conform to in order to be recognised as trusted by each framework). So the verifier can send its registered id/names in the discovery request message, as well as the IDs of the trust frameworks (which will need to be globally unique, so URLs could be mandated for these). |
@bc-pi following the friday call with @paulbastian and Franceco Marino I bring here the points about the requirement, from the RP perspective, of obtaining the wallet instance attestation and capabilities before issuing the request object
|
Co-authored-by: Brian Campbell <71398439+bc-pi@users.noreply.github.com>
Following the call last wednesday 25th, in some of the proposals there was a need to communicate capabilities or features by at least one of the participants in an exchange:
With independence of which option satisfies privacy or functional concerns, in both cases the specification of capabilities / features must be advertised by one or both participants. Is there any previous attempt to describe such a thing? I'm verifier X, registered in Y and Z trust framework using W means, and offer the following A, B, C, exchanges using these methods, algorithms, credential formats, etc. |
Hi all, I filed a new PR with an alternative design for the advanced flow. It is less sophisticated but simpler and more privacy preserving. I hope it can be the basis of a consensus. Have a look at PR #59. @peppelinux @paulbastian @David-Chadwick @danielfett @Sakurann |
In general I'm supportive of the flow described in #59. Personally, I think we should also include the approach that was described in #65 to allow wallets to detect phishing attacks. |
@tlodderstedt may we close this PR since it is overseeded by #59? PR 59 references this PR as well |
Closing this PR as the WG is pursuing a different design proposed in PR #59 |
This is the first revision of the advanced flow (issue #45). Based on the feedback on the issue, I called the wallet request
Discovery Request
. The verifier may require the wallet to authenticate. It will do so be responding with a HTTP status code 401, the response also provides a nonce to be included in the proof of possession.Open Topic: Do we want to support plain JSON presentation requests?