Skip to content

Conversation

sourabh1007
Copy link
Contributor

@sourabh1007 sourabh1007 commented Mar 14, 2024

Why make this change?

We need to support Item Level DB policies for cosmosdb.

{
  "role": "item-level-permission-role", // Role Name
  "actions": [
    {
      "action": "read",
      "policy": { 
        "database": "@item.type eq 'earth0'"  // DB policy
      }
    }
  ]
}

How is it different from Relational DB?

In case of Relational Database like SQL, each entity indicates a separate table which can be queried independently.
But in comosdb, there is nothing like table, Here we have a container which contains data in JSON format consists of entities defined in the configuration file.

What is this change?

Context: We always run a GraphQL query against a container. Hence, we have information about container and we run only those filters which are defined in the GraphQL filter.
Item level policy should always applied (no matter if entity is a part of query or not)
e.g
Schema: We have a container (Planet) with 2 other sub entities Character, Star

type Character {
    id : ID,
    name : String,
    type: String,
    homePlanet: Int,
    primaryFunction: String,
    star: Star
}

type Planet @model {
    id : ID!,
    name : String,
    character: Character,
    stars: [Star],
}

type Star {
    id : ID,
    name : String,
    tag: Tag
}

DB Config: In DB config, DB Policy is defined for star

  "Planet": {
  },
  "Character": {
  },
  "Star": {
    "permissions": [
     {
        "role": "item-level-permission-role",
        "actions": [
           {
              "action": "read",
              "policy": {
                     "database": "@item.name eq 'earth0'"
                }
            }
        ]
     }]
  }

GraphQL Query: Query an entity for which policy is not defined

string gqlQuery = @"{
    planets(first: 1, " + QueryBuilder.FILTER_FIELD_NAME + @" : { character: {type: {eq: ""Mars""}}})
    {
        items {
            id
        }
    }
}";

Generated CosmosDB Query: It should fire a query with conditions from policies along with JOIN if entity is of array type.

SELECT c.id 
FROM c 
WHERE c.character.type = 'Mars'  ## From filter
AND c.character.star.name = 'earth0'  ## From DB Policy
AND EXISTS ( SELECT VALUE 1 
                      FROM table1 IN c.stars 
                      WHERE (table1.name = 'earth0'))  ## From DB Policy

Code Design:

Defining Container

[Breaking Change: Need Documentation Update]_ Since, CosmosDB natively supports one entity per container, hence @model will indicate container level entity and other entities should be defined as type only.

Process Configuration During Load

(src/Core/Services/MetadataProviders/CosmosSqlMetadataProvider.cs)

  1. Generate EDM model.
  2. Collecting all the paths for an Entity from container.
    private void ParseSchemaGraphQLFieldsForJoins()

    a) If given entity is on Array format, creating alias for the same.
    EntityWithJoins[entityType].Add(currentEntity);

    b) Generate JOIN statement
    currentEntity.JoinStatement = previousEntity.JoinStatement + " JOIN " + currentEntity.JoinStatement;

Generate and Append conditions during query.

  1. Use above models, generate filter clause for each entity (including resolving @claim also).
    postProcessCallback: (filterClause, _) =>
  2. Generate where conditions for an entity using prefixes collected_(at point 2 in "Process Configuration during load" section).
    predicates = filterClause?.Expression.Accept(new ODataASTCosmosVisitor($"{pathConfig.Path}.{pathConfig.ColumnName}"));

Other Changes:

  1. I realized during implementation of this, in cosmos DB it is recommended to use subquery instead of join if entity type is of Array type.
    private void HandleNestedFilterForCosmos(
  2. Fix tests to use model entity instead of direct type entity as it is not recommended to use @model for all the entities
    (src/Service.Tests/CosmosTests/MutationTests.cs and other test files)

Clean up

Removed all the JOIN related changes

How was this tested?

  • Integration Tests
  • Unit Tests

@sourabh1007 sourabh1007 changed the title Cosmos DB: Item Level Auth approach2 Cosmos DB: Item Level Auth approach3 Mar 14, 2024
@sourabh1007 sourabh1007 force-pushed the users/sourabhjain/itemlevelauthapproach3 branch from b1ca432 to 08b02a5 Compare March 17, 2024 04:59
@sourabh1007 sourabh1007 changed the title Cosmos DB: Item Level Auth approach3 Cosmos DB: Adds Item Level Auth support using DB Policy Mar 17, 2024
@sourabh1007
Copy link
Contributor Author

/azp run

@sourabh1007 sourabh1007 force-pushed the users/sourabhjain/itemlevelauthapproach3 branch from a8eb931 to 4cdd2e5 Compare March 18, 2024 06:57
@sourabh1007
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@sourabh1007
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@sourabh1007
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Contributor

@seantleonard seantleonard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still reviewing (need another day Redmond time) but some questions that have come up so far.

@sourabh1007
Copy link
Contributor Author

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@sourabh1007
Copy link
Contributor Author

/azp run

@Azure Azure deleted a comment from sourabh1007 Apr 9, 2024
@Azure Azure deleted a comment from azure-pipelines bot Apr 9, 2024
@Azure Azure deleted a comment from sourabh1007 Apr 9, 2024
@Azure Azure deleted a comment from azure-pipelines bot Apr 9, 2024
@Azure Azure deleted a comment from sourabh1007 Apr 9, 2024
@Azure Azure deleted a comment from sourabh1007 Apr 9, 2024
@Azure Azure deleted a comment from azure-pipelines bot Apr 9, 2024
@Azure Azure deleted a comment from sourabh1007 Apr 9, 2024
@Azure Azure deleted a comment from azure-pipelines bot Apr 9, 2024
@Azure Azure deleted a comment from sourabh1007 Apr 9, 2024
@Azure Azure deleted a comment from azure-pipelines bot Apr 9, 2024
@Azure Azure deleted a comment from azure-pipelines bot Apr 9, 2024
@Azure Azure deleted a comment from azure-pipelines bot Apr 9, 2024
Copy link
Member

@sajeetharan sajeetharan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sourabh1007
Copy link
Contributor Author

Synced up with @sajeetharan, It is not a breaking change and it is already documented that, container level entity should be model.

@sourabh1007
Copy link
Contributor Author

/azp run

@seantleonard
Copy link
Contributor

/azp run

1 similar comment
@sourabh1007
Copy link
Contributor Author

/azp run

@sourabh1007
Copy link
Contributor Author

/azp run

@sourabh1007 sourabh1007 merged commit e660ba3 into main Apr 16, 2024
@sourabh1007 sourabh1007 deleted the users/sourabhjain/itemlevelauthapproach3 branch April 16, 2024 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Known Issue] Azure Cosmos DB Support for Authorization Policies
4 participants