Re: [GNAP] Accounting for Resource Owner in RS::AS interactions

Justin Richer <> Tue, 28 September 2021 18:57 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 449F73A0B08 for <>; Tue, 28 Sep 2021 11:57:36 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -1.497
X-Spam-Status: No, score=-1.497 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, KHOP_HELO_FCRDNS=0.399, SPF_HELO_NONE=0.001, SPF_NONE=0.001, URIBL_BLOCKED=0.001] autolearn=no autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 27YtHxr6GsjY for <>; Tue, 28 Sep 2021 11:57:32 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id BFD943A0B05 for <>; Tue, 28 Sep 2021 11:57:31 -0700 (PDT)
Received: from [] ( []) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by (8.14.7/8.12.4) with ESMTP id 18SIvSx7000521 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 28 Sep 2021 14:57:28 -0400
From: Justin Richer <>
Message-Id: <>
Content-Type: multipart/alternative; boundary="Apple-Mail=_CE480443-F779-464D-848A-A47A809405A8"
Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.\))
Date: Tue, 28 Sep 2021 14:57:28 -0400
In-Reply-To: <>
To: Josh Mandel <>
References: <>
X-Mailer: Apple Mail (2.3608.
Archived-At: <>
Subject: Re: [GNAP] Accounting for Resource Owner in RS::AS interactions
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: GNAP <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Tue, 28 Sep 2021 18:57:37 -0000

Hi Josh, thanks for bringing up this use case. An AS protecting several different unrelated RS’s is absolutely in scope, as this is a common deployment for OAuth 2 today. If I understand everything you’re asking, currently GNAP would allow everything here, but it doesn’t specify the details of every part of it. I’m going to reply to your scenarios inline below. Apologies in advance for the long email, there’s a lot to unpack here!

> On Sep 27, 2021, at 1:56 PM, Josh Mandel <> wrote:
> Hi All,
> I'm interested in exploring how GNAP can/does/might account for the Resource Owner associated with specific protected resources, in scenarios where a single AS is trusted by multiple independent RS's (specifically in scenarios where these RS's don't know or trust one another). Justin suggestd I might reach out here.
> My sense is that there are security considerations related to these questions, and perhaps some best practices or even areas where the core spec's data models could be enhanced to support these scenarios. I'm not proposing anything in particular at this stage; just trying to get the lay of the land.
> See assumptions and scenarios below.
> -Josh
> --
> Assumptions. I'll focus on a very simple API from the RS perspective: a standardized file access API where resource servers would like to make access control decisions based on access tokens whose RARs look something like:
> {
>   "type": "file-access",
>   "actions": ["read"],
>   "location": ["{{URL of one protected file}}"]
> }
> ---
> Scenario 1. Consider the case where a single RS manages files owned by multiple end users. The RS uses a single AS for all files (but the AS also serves other untrusted RS's). Each RO is allowed to set authorization policies for their own files. In this scenario, how does the AS learn which RO is responsible for setting policies for each file, so it can present Alice with a list of current policies, allow her to review/tweak access, etc?

Setting and updating policies are outside the scope of GNAP core, including any interfaces for doing so.

The policies are controlled at the AS and enforced by the RS. It’s really up to the individual deployments how and where to make that split: an AS could issue tokens that are simply tied to the specific data, the result of processing the security context of the delegation. Or the AS could send over all the context information to the RS to let it make its own decisions entirely, while the AS only has an idea of something existing and not who owns or controls it. Or something in between. And all of these are functionally the same whether you’re introspecting or using structured tokens, so I’m not going to get into the differences here.

Doing this statically would be pretty easy, since the decisions can just be set in code and executed. Doing it dynamically feels a lot harder and more interesting. There are a lot of pieces that need to be fulfilled to even get to this point, and I’ll try to add some thoughts on each: 

- How does the AS know who Alice is? In OAuth, it’s assumed that Alice can “log in” to the AS using her account. In GNAP we also allow that but further let Alice have other ways of interacting with the AS, and doesn’t assume that Alice has an “account” at the AS in a traditional sense. Even so, it’s likely in this scenario that the AS will have some set of identifiers that it has bound to Alice, which can be associated with that policy.

- How does the RS know about the AS? GNAP does offer some discovery for the technical connections (, but more important is the question of how the RS decides to trust the AS to protect any given resource. In your scenario this sounds like a configuration time decision, but it might not always be.

> (If an AS is confused on this point, there's a risk that Bob can set policies for Alice's files.) It's possible that the Resource Registration API could be extended to model this kind of ownership, if both servers have some interoperable way to communicate user identities. I'm not sure if there are existing patterns to recommend here?

- How does the AS know about what the RS is protecting? GNAP allows the RS to dynamically introduce a new resource set to the AS and get back a reference for it ( <>), and like you, I could see this being expanded with an ability to say “this RO / set of ROs controls this resource set” as part of that registration step. As long as the identifiers aligned, it would let the AS do some enforcement at token issuance time. But that really isn’t meant to set policies, it’s meant to allow an RS to register a set of rights with a simple identifier (like a scope with a random value). Perhaps a different API is actually needed for policy management? And with that in mind, it would only be needed if we wanted the AS to make sure Bob is never prompted for one of Alice’s files at the AS, ever. If you don’t want that information to leak to the AS, you can allow Bob to get an ineffective token for Alice’s file resource, and count on the RS to say “hey you aren’t Alice, go away”. Again, this goes back to where you draw the enforcement lines, which often has more to do with the nature of the API you’re protecting than anything.

- How does the RS know how to associate a specific resource with “Alice”, and not “Bob"? This requires the RS to know who “Alice” is and know that a given file is hers to control. Doing this dynamically feels really difficult

- How do the RS and AS agree that “Alice” is the same person with the same identifiers? It’s obvious that simply trusting a global identifier here won’t solve it on its own — confusion remains trivial, it would just take an RS to apply Bob’s global identifier to Alice’s data, or for Bob to get assigned Alice’s identifier by a bad AS. But GNAP does have a whole notion of “subject identifiers” that are scoped to the AS’s trust domain that can be used here: if the RS refers to Alice by an identifier known to the AS, and it trusts the AS to enforce that binding for Alice, then it will work.

> It's also very important for the RS to know, whenever it receives an access token, that the RS is an intended audience for that token. The RAR "locations" aren't enough to accomplish this, unless the AS has a reliable scheme in place to prevent one RS from crafting RARs that refer to resource locations within another RS.  And as the spec says, the AS introspection endpoint needs to ensure that access tokens are "appropriate for presentation at the identified RS". But that's especially challenging when a single access token can include multiple RARs, potentially intended for different RS's (which appears to be allowed by the base spec). And for structured token formats where introspection isn't required, the same questions hold; is there existing work on this?

The ‘locations’ field on its own isn’t enough for this, but it can be a place to hold identifiers for each RS. These need not be URLs to the APIs in question, though in practice I’d expect them to be. It then also begs the question of how the RS identifiers came to be, and if they’re then required for this type of processing. 

> Scenario 2. Now consider the case where 10 organizations each manage a File Sharing RS. Each RS hosts files for multiple ROs, and the ROs get to choose which AS should be trusted for their own files. In this context, I suppose the workflow that introduces the RS to the AS can be mediated by the RO, so that the RO is logged into both systems when making the introduction, and the RS can essentially register a new client instance with the AS for each RO who decides to establish a connection. This pattern has the advantage that there's no confusion about *who* controls a given resource -- but perhaps there are other, better ways to accomplish this.

That was what UMA tried to do with resource set registration, in a way. It was awkward from a technology perspective, and it made RS owners nervous in a lot of ways to have a new AS introduced. I appreciate the ideology, but to this day I don’t believe it’s realistic to implement or deploy.

I think a better pattern is to allow introduction of “Alice” at the AS level instead of at the RS level. In other words, Alice doesn’t bring her own “AS”, but she could bring her own identity and policy to the AS that protects the RS. That way the RS-AS relationship can be more tightly aligned, but the user capabilities are greatly expanded. It changes the fit of the components from what we might be used to, but I strongly believe there’s a lot of promise in this pattern. And in fact, we see a similar pattern in OAuth 2 today with API Gateways that can be configured to allow federated logins, for example.

Finally, I think there’s an even more interesting scenario: when Alice says that Bob should be able to access her stuff. Who does she tell and who needs to care? There are a lot of ways to slice this, but this jumps to my mind immediately:

 - Alice has a resource A at the RS, which is protected by the AS
 - The AS has a policy that says Alice can authorize client instances to access resource A
 - The AS also has an interface for Alice to set additional policies
 - Alice says to the AS that a user identified as Bob can also access A
 - When either Alice or Bob come to the AS, the AS can figure out from this policy to create an access token that can access A
 - The RS doesn’t need to know about Alice or Bob at all, only whether the token is good for accessing A

 — Justin

> -- 
> TXAuth mailing list