Skip to content
This repository has been archived by the owner on Jul 19, 2024. It is now read-only.

Resource token access control for partial partition key does not work for queries #14

Open
idg10 opened this issue Feb 23, 2023 · 1 comment

Comments

@idg10
Copy link

idg10 commented Feb 23, 2023

We have a Cosmos DB with a two-level hierarchical partition key. (/tenantId/operationId). We were hoping to be able to enforce strict tenant isolation using a hierarchical partition key in combination with resource access token (somewhat similar to how AWS's DynamoDB lets you create access tokens with a "leading key" constraint).

In a multi-tenant design where each tenant has their own container, it is relatively easy to enforce strict security boundaries. We were hoping to be able to achieve the same thing within a container using hierarchical partition keys, and resource access tokens specifying just the first section of the partition key.

This works for some scenarios.

It is possible to create a user permission specifying just the first level of the partition key (the tenantId part here). In our example case, that corresponds to a permission to see anything in a particular tenant. And it is possible to create a token from that permission. For point queries, this seems to work fine: clients using such a token can fetch items in any partition where the tenantId part matches the value in the token.

But it does not seem to work for queries.

If I want to, say, search for all items with a particular tenantId, based on some other criteria, e.g.:

SELECT * FROM c WHERE c.tenantId ='{tenant}' AND c.status = 'Not started'

then the request will be rejected with a Forbidden response.

As far as I can tell, if your CosmosClient is configured with a resource access token, any attempt to execute a query will be blocked unless your request options includes the partition key, e.g. something like this:

requestOptions: new QueryRequestOptions { PartitionKey = pk }

However, this only works if I specify all levels of hierarchy in the partition key.

What I want to do is search all the items with a particular tenantId (and my token gives me permission to do that), but when using a resource token that stipulates just the first level of a hierarchical partition key, the query API not only rejects requests that don't specify a partition key, it also seems to reject quests that don't specify the full /tenantId/operationId partition key. This narrows the search down more than I want.

It seems there's a slight disconnect between the way the hierarchical partition key feature expects queries to be narrowed down to a particular subset of partitions, and the way the resource token access control mechanism expects this to work:

Looking at the Run a query section of the hierarchical partition key docs, there seems to be an implied assumption that Cosmos DB will work out which partitions need to be involved by analyzing the query. It shows various WHERE clauses that enable Cosmos DB to determine which partitions can safely be left out. As far as I can tell from these docs, there is no expectation that you're going to provide QueryRequestOptions.PartitionKey to tell it which partition(s) to look in—Cosmos DB is going to work that out from your query.

But that doesn't seem to be how the resource token system expects things to work. As far as I can tell, the access control mechanism happens before the query gets as far at the query processor. So if you are using a token that stiplates a particular partition key (even if it's only the first level of a hierarchical key) the resource token access control system apparently won't even look at the WHERE clause until it is satisfied that you will only be looking in partitions that your token grants you access to. So that effectively rules out a mechanism where the query processor can determine which partitions your query applies to.

This wouldn't be so problematic if you were allowed set QueryRequestOptions.PartitionKey to a partially-specified key. But you can't - if you don't provide a full partition key it rejects the request.

This seems to indicate that for queries, you basically can't do queries that work like the second one in the docs (" to only the targeted subset of logical and physical partition(s) that contain data for the specified values of TenantId and UserId.") Targetted cross-partition queries don't appear to be possible if you're using an access token that specifies a partial partition key.

I'm wondering if this is by design. It works the way I had hoped for point queries, so evidently at least some parts of the system are perfectly capable of processing partially-specified partition keys. (I'm also not entirely sure this isn't a client-side library problem. I'm using the .NET Microsoft.Azure.Cosmos component version 3.32.0-preview.)

@robertgm
Copy link

We have the same problem. Resource tokens doesn't work with hierarchical partition key when we want to execute query with WHERE on all projects. It only works in case when the entire HPK is specified

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants