Re: [GNAP] [Txauth] Three Client-Server use cases with several ASs built along "Privacy by Design" (PbD)

Justin Richer <jricher@mit.edu> Wed, 12 August 2020 16:07 UTC

Return-Path: <jricher@mit.edu>
X-Original-To: txauth@ietfa.amsl.com
Delivered-To: txauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 091633A13A3 for <txauth@ietfa.amsl.com>; Wed, 12 Aug 2020 09:07:48 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.896
X-Spam-Level:
X-Spam-Status: No, score=-1.896 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HrKg3m_ML5By for <txauth@ietfa.amsl.com>; Wed, 12 Aug 2020 09:07:45 -0700 (PDT)
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 1BCDA3A13A0 for <txauth@ietf.org>; Wed, 12 Aug 2020 09:07:44 -0700 (PDT)
Received: from [192.168.1.18] (static-71-174-62-56.bstnma.fios.verizon.net [71.174.62.56]) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 07CG7cgN025728 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 12 Aug 2020 12:07:38 -0400
From: Justin Richer <jricher@mit.edu>
Message-Id: <319DAB20-198D-48B7-B0B8-72881D234633@mit.edu>
Content-Type: multipart/alternative; boundary="Apple-Mail=_2EEF5A1C-9671-4E6D-86F3-ED2AF404E3D1"
Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.1\))
Date: Wed, 12 Aug 2020 12:07:37 -0400
In-Reply-To: <f478a8a2-026b-bb66-d3a7-8110d86e5920@free.fr>
Cc: Fabien Imbault <fabien.imbault@gmail.com>, Francis Pouatcha <fpo@adorsys.de>, GNAP Mailing List <txauth@ietf.org>
To: Denis <denis.ietf@free.fr>
References: <d2ee5da2-8e88-15c8-8646-087860463d2c@free.fr> <CAOW4vyOwQTMoo2Nmb8KNcVM5hdOW69FzZTK5XQ2fRL9CC8+SUA@mail.gmail.com> <CAM8feuT2K2xpF=VES11kihsqfGK4RCzdSCU=HCLijxLvnc=8LA@mail.gmail.com> <CAOW4vyM0jkw9qTzohzGaNwvvT6JGqcUbdqXnJFq9ahqnRPnuGQ@mail.gmail.com> <CAM8feuQfknpOFHTdV_XAc-49Vw-2jER65x4XxmARN6-Dwhyn+A@mail.gmail.com> <CAOW4vyN0gcvqAidJTMxWOAJoLwhFJyxFe6fZy9jcN8uCvyAK4g@mail.gmail.com> <CAM8feuT-N87bJ9S7VOEPUnX6kot3wjcQCHUb=0zuN9SFHo=XHg@mail.gmail.com> <7d64ec8b-2fb6-a0c7-c649-f4f4c9cc00a1@free.fr> <CAM8feuQwsde2f3tyVVQf=9X0R3=aCvApxD=eNbwWYHh7NpBm7g@mail.gmail.com> <f478a8a2-026b-bb66-d3a7-8110d86e5920@free.fr>
X-Mailer: Apple Mail (2.3608.120.23.2.1)
Archived-At: <https://mailarchive.ietf.org/arch/msg/txauth/wvAtQP0ODujIxD62A-NPEN4-cOQ>
Subject: Re: [GNAP] [Txauth] Three Client-Server use cases with several ASs built along "Privacy by Design" (PbD)
X-BeenThere: txauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: <txauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/txauth>, <mailto:txauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/txauth/>
List-Post: <mailto:txauth@ietf.org>
List-Help: <mailto:txauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/txauth>, <mailto:txauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 12 Aug 2020 16:07:48 -0000

Hi Denis,

I think this is a fascinating approach that can allow for privacy-preservation in the way that you’re after. Here’s how I would see it fitting into GNAP:

When the client makes the request, it includes the concealed_target_identifer in the resources request, probably in lieu of any kind of “location” field. The semantics of this field could be defined in GNAP core or in a short extension describing the reusable field in the “resources” request:

resources: [
   “action": [“read”],
   “concealed_target_identifier”: “876tghjkjasdf7234f”
]

At that point, it’s up to the AS to bind that identifier to the resulting access token and make that information available to the RS. That could happen by packing it into a JWT, which is likely the format you’d want for this kind of thing because an introspection call from the RS would identify the RS to the AS. 

The missing piece is a way for the client to present the random number to the RS alongside the access token. I think this would make sense as a separate HTTP header defined in that extension. So the client would get back its token and send this to the RS:

Authorization: GNAP eyj0…
Target-Identifier-Random-Number: ABE54298411...


The RS would look at the token, find the hashed value within, and use the value in the secondary header to recalculate and verify the hash on the request. All of this can be done without the RS calling the AS and without the client divulging the RS’s location or identity to the AS.

 — Justin


> On Aug 12, 2020, at 10:34 AM, Denis <denis.ietf@free.fr> wrote:
> 
> Hi  Fabien,
>> Thanks Denis.
>> 
>> A few questions to clarify: 
>> - "the field included into the access token will look like a random number to the RS." - you mean AS?
> Correct. This was a typo.
> 
>> - "It should have two parts : a signed part and an unsigned part." - Something like an authenticated cipher (e.g. AES-GCM) + a KV mapping (with short expiry) between the temporary_id and the url, on the RS side?
> Sorry, I am not aware of this scheme.
> 
>> Then the algorithm would be :
>> 1. Client contacts the RS, which sends a resource description (temporary_id)
> No. It is not a temporary_id.  
> 
>> 2. The flow continues and a token is generated, using the temporary_id.
> No. Knowing the true identifier of the RS, the Client picks a random_number and computes a concealed_target_identifier =  hash (random_number, RS_identifier).
> 
> While requesting an access token, the Client asks the AS to include the concealed_target_identifier into the access token.
> 
> While sending the access token, the Client adds the random_number into the unsigned part of the access token.
> 
> While receiving the access token, the RS uses it own RS_identifier and retrieves the random_number placed into the unsigned part of the access token.
> It then computes a hash of (random_number, RS_identifier). If the result matches with the concealed_target_identifier placed into the signed part of 
> the access token, then the access token is well targeted, otherwise it is ignored.
> 
>> 3. Client makes the call to the RS, using the token. The RS verifies the signature + it also verifies that the mapping is the one expected.  
>> 
>> BTW, it makes the RS decide the maximum token expiry.
> Token expiration is unrelated.
> 
>> The issue is that it requires more work on the RS side, compared to a stateless JWT. 
> Adding two computations using a one way hash function is not a big deal.
> 
>>  Is that correct?
> No. The mechanism is fairly different. It has already been explained once on the OAuth mailing list.
> 
> Denis
> 
>> 
>> Fabien
>> 
>> 
>> On Wed, Aug 12, 2020 at 3:24 PM Denis <denis.ietf@free.fr <mailto:denis.ietf@free.fr>> wrote:
>> With so many messages in the last 24 hours, I can't respond to all of them at once.
>> I picked the last one first.
>> 
>>> Inline too :-)
>>> 
>>> On Wed, Aug 12, 2020 at 1:51 PM Francis Pouatcha <fpo@adorsys.de <mailto:fpo@adorsys.de>> wrote:
>>> Hello Fabian, inline
>>> 
>>> On Wed, Aug 12, 2020 at 4:02 AM Fabien Imbault <fabien.imbault@gmail.com <mailto:fabien.imbault@gmail.com>> wrote:
>>> Hi Francis, 
>>> 
>>> My comments are embedded into your email with FI.
>>> 
>>> You're saying in a follow-up message: 
>>> "- If you want privacy, don't expose RS identity to AS.
>>> - If you want transparency, expose RS identity to AS.
>>> You can't have both...."
>>> While that may seem a reasonable dichotomy at first sight, I believe the reality is actually more nuanced and depends on how we end up designing the system. 
>> [Denis] This is in fact more nuanced. It is possible to prevent the AS to know who the RS is by hiding the true identifier of the RS to the AS.
>> 
>> This means that for security reasons the access token is still targeted but that the field included into the access token will look like a random number to the RS.
>> That random number will change for every access token.
>> 
>> In order for the RS to make sure that the access token is indeed intended for itself, it will need to combine the field included into the access token 
>> with an unsigned field external to the access token. 
>> 
>> This would have a major consequence for the structure of a GNAP access token that will be rather different from an OAuth 2.0 access token. 
>> It should have two parts : a signed part and an unsigned part.
>> 
>>> 
>>> Cheers,
>>> Fabien
>>> 
>>> On Tue, Aug 11, 2020 at 11:27 PM Francis Pouatcha <fpo@adorsys.de <mailto:fpo@adorsys.de>> wrote:
>>> Hello Fabian,
>>> 
>>> On Tue, Aug 11, 2020 at 2:17 AM Fabien Imbault <fabien.imbault@gmail.com <mailto:fabien.imbault@gmail.com>> wrote:
>>> Hi Francis,
>>> 
>>> I think Denis points to the fact that, in the current situation, the AS receives the resource request from the Client and therefore knows what tokens are asked.
>>> The token request must not mention any reference of the RS.
>>> 
>>> FI : yes we can do that, but as Tom commented, it's not a general rule. And for instance in XYZ you do describe the URL of the resource. See also the use case on directed tokens, which is an interesting topic which makes sense in many scenarios.  
>>> Yes. But disclosing the protected resource discloses the RS. 
>>> 
>>> FI : yes of course. Which is why RS hiding may be a solution. 
>>> 
>>> But as soon as you include that possibility, it's fair to think that this capability could be used for surveillance purposes in some cases, unless you found a privacy by design scheme that applies by default. 
>>> Yes. THen default shall be using URI of resource description and not URL to indicate resource location. 
>>> 
>>> FI : yes 
>>> 
>>> Again this doesn't mean that transparency requirements aren't important too, but I think there are other ways it can be achieved (for instance, an inspiration is the certificate transparency project). Could be an extension to the protocol I believe. 
>>> The certificate transparency deals with something else. Does not fit in this context at all.
>>>  
>>> FI : It does, and has already been implemented by some projects in relationship with OAuth2, as an additional component. 
>>> 
>>>  
>>> Then it also implements the consent interface (and possibly the login too) and so it also knows who validates and what is accepted or not.
>>> Decoupling this does not change the privacy context, as the AS issues the Token. AS needs to add a reference to the RC in the token. SO AS can correlate on StudentId anyway.
>>> 
>>> FI : I disagree. It does change the privacy context, if as Denis suggested, the consent is made outside of the AS and if you don't send to the AS the information on the RS when it needs to issue the token.
>>> Correlation on StudentId is limited as long as it's a local identifier, i.e. not a public DID. 
>>> How local can the StudentId be? It is known to both universities and to the AS. Without a public reference, you can not link information between unrelated entities (AS, UNIV-0 and UNIV-1). Using VCs can help here. Then you do not need central AS anymore.
>>> 
>>> FI : see keri or peer DID for instance, as examples of local ID. 
>>> Again SSI/DID/VC doesn't mean you don't need AS, those technologies can be complementary. 
>>>  
>>> 
>>> As a concrete example: a user may want to use an application to access rs_domain/directory1 and rs_domain/directory2 in read and write, which are managed by a RO. 
>>> What I suggested is that the Client may (optionally) carry out its consent through a decoupled IS server (separated from the AS), that displays the UI based on the RS requirements => the IS knows what information is used, but the IS may be chosen by the IS independently from the AS or even run by the Client itself. 
>>> What do you need an AS for? Then it can sign the claim to present to RS.
>>> 
>>> FI : to be sure, what is "it"? 
>>>  
>>>  
>>> In this case, suppose the RO only provided consent for rs_domain/directory1 for read. 
>>> We now need to get back to the AS to mint the access token. 
>>> If AS mint access token, AS will be able to correlate. Unless start applying intransparent complex reference mapping techniques, wich might even open room for new attack vectors.
>>> 
>>> FI : not necessarily with respect to correlation, see above.
>>> As for mapping techniques, this is the very reason of my question to Denis. 
>>> 
>>> 
>>> If we want the AS to not know about the RS, we either : 
>>> - don't supply the rs_domain at all -> the JWT says that directory1 in read access is authorized. The downside is that we actually cannot control to which URL the authorization applies. In that case I agree with your either or statement.  
>>> Yes 
>>> - or find a way to hide it (not sure if that's practical, hence my questions on RS hiding). This would have the benefit of still allowing directed tokens -> the JWT says that rs_petname/directory1 in read access is authorized.
>>> More complexity. 
>>> 
>>> FI : yes
>> [Denis] As indicated at the top of this email, it is possible to always hide the identifier of the RS while still targetting every access token.
>> 
>> BTW, I have expanded the notion of targetting by allowing to place into a target field of an access token either or both a RS identifier and 
>> a Service Name (SN) identifier to which the RS belongs.
>> 
>> Two targetting fields should hence be possible: a RS identifier and a SN identifier.
>> 
>> This is also a difference with an OAuth 2.0 access token.
>> 
>>> Either way, the AS has not been provided any information as to where this token will effectively be used.  
>>> 
>>> 
>>> I don't think the abstract flow deals with those privacy concerns. 
>>> To solve the privacy problem addressed in this thread, we need to go the (SSI/DiD/VC) way. Then UNIV-0 (in his role of RS) will have to issue a VC (Verifiable Credential) to the Student (in his role of RC). The Student will then present this claim to UNIV-1 during his registration. In this case we need no Grant negotiation and no AS.
>> [Denis] This is a complete redesign of my example and hence this redesign has no relationship with my example.
>> 
>>> 
>>> FI : That may be useful but it's not enough. What you describe only works because you take a very specific use case, aka registration. This fits well into DID/VC without requiring authorization per say. However grant negotiation is still required for more general settings of authorization.  
>>> Please drop the next use case in the repo, so we can dive deeper into it and see how to provide both central grant negotiation and privacy.
>>> 
>>> FI : will do. 
>>> 
>>> I've added a DID example to my implementation, will publish it soon. 
>>> 
>>>  
>>> Best regards.
>>> /Francis
>>>  
>>> 
>>> Then I agree with you on the audience field of the token, if left empty it simplifies part of the problem, although it removes a big part of the control you may want from directed tokens. That's why I'm willing to better develop the RS hiding idea. 
>>> 
>>> Fabien 
>>> 
>>> Le mar. 11 août 2020 à 05:58, Francis Pouatcha <fpo=40adorsys.de@dmarc.ietf.org <mailto:40adorsys.de@dmarc.ietf.org>> a écrit :
>>> Hello Denis,
>>> 
>>> what you describe in the use case seems to be the default behavior of the protocol. Let me map it with this abstract protocol flow:
>> [Denis] The redesign below has no relationship with my use case.
>> 
>> A key element of my design is the User, i.e. a physical person which initiates the exchanges. In the example below the User has disappeared.
>> 
>> A User is not a role, but an entity.
>> 
>> BTW, I can't understand the role of an "Orchestrator" (which is left undefined). 
>> 
>>> 
>>> +-----------+      +--------------+  +-----------+  +----+  +---------------------+
>>> | Requestor |      | Orchestrator |  | RS        |  | GS |  | Resource Controller |
>>> | is UNIV-1 |      |  is UNIV-1   |  | is UNIV-0 |  | or |  |         is          |
>>> |   Staff   |      | Registr. App |  | Server    |  | AS |  |       Student       |
>>> +-----------+      +--------------+  +-----------+  +----+  +---------------------+
>>>   |(1) RegisterStudent    |                |           |                |
>>>   |---------------------->|                |           |                |
>>>   |                       |(2) RequestRecordIntent(RecordType,StudentId,
>>>   |                       |     OrchestratorId):AuthRequest[RecordType,StudentId]
>>>   |                       |<-------------->|           |                |
>>>   |                       |                |           |                |
>>>   |                       |(3) AuthZRequest(RecordType,StudentId,OrchestratorId)
>>>   |                       |--------------------------->|                |
>>>   |                       |                |           |(4) ConsentRequest(RecordType,
>>>   |                       |                |           |     OrchestratorId):Consent
>>>   |                       |                |           |<-------------->|
>>>   |                       |(5) AuthZ[RecordType,StudentId,OrchestratorId]
>>>   |                       |<---------------------------|                |
>>>   |                       |                |           |                |
>>>   |                       |(2) RequestRecord(RecordType,StudentId,OrchestratorId)
>>>   |                       |     :RecordOf[StudentId]   |                |
>>>   |                       |<-------------->|           |                |
>>>   |(7) Registered         |                |           |                |
>>>   |<----------------------|                |           |                |
>>>   +                       +                +           +                +
>>> 
>>> we assume the authz request sent by "Client" to "AS" describes the protected resource without referring to the authz server. An AS can issue the authz to release the graduation record  of a student ((5) AuthZ[RecordType,StudentId,OrchestratorId]), without any reference to the target university. 
>>> 
>>> What matters for this authz object is:
>>> - StudentId: a reference to the student as known to the resource server.
>>> - RecordType: a reference to a resource of type graduation record as understandable  by the resource server.
>>> - OrchestratorId: reference to the Orchestrator. Can be used to bind authz to Orchestrator.
>>> 
>>> But:
>>> - RS must trust AS issued token.
>>> - StudentId must be known to RS, AS and Orchestrator.
>>> 
>>> Therefore, the AS does not need to know the RS. Keep the audience field empty.
>>> 
>>> Same principle applies for the second use case.
>>> 
>>> What privacy problem do you see here?
>> [Denis] The User, a physical person which initiates the exchanges has disappeared. 
>> No more user, no more privacy issues ? :-)
>> 
>> Denis
>> 
>>> 
>>> Best regards.
>>> /Francis
>>> 
>>> On Tue, Aug 4, 2020 at 5:08 AM Denis <denis.ietf@free.fr <mailto:denis.ietf@free.fr>> wrote:
>>> I tried my best twice to download three use cases in the Use cases directory, but I failed.
>>> 
>>> Rather than failing a third time, here is the direct link of the second try:
>>> 
>>> https://github.com/ietf-wg-gnap/general/wiki/Three-Client-Server-use-cases-with-several-ASs-built-along-%22Privacy-by-Design%22-(PbD) <https://github.com/ietf-wg-gnap/general/wiki/Three-Client-Server-use-cases-with-several-ASs-built-along-%22Privacy-by-Design%22-(PbD)>
>>> Denis
>>> 
>>> 
>>> 
>>> -- 
>>> Francis Pouatcha
>>> Co-Founder and Technical Lead
>>> adorsys GmbH & Co. KG
>>> https://adorsys-platform.de/solutions/ <https://adorsys-platform.de/solutions/>
>> -- 
>> TXAuth mailing list
>> TXAuth@ietf.org <mailto:TXAuth@ietf.org>
>> https://www.ietf.org/mailman/listinfo/txauth <https://www.ietf.org/mailman/listinfo/txauth>
> 
> -- 
> TXAuth mailing list
> TXAuth@ietf.org
> https://www.ietf.org/mailman/listinfo/txauth