question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Feature] CosmosClient multi-tenant enablement

See original GitHub issue

Context

One of popular multi-tenant pattern, is to partition data per application tenant. Partitioning can be by Container OR container/PK (later is very prominent). Scale of multi-tenants might be very high.

Least privilege access principle demands application to use very constrained access credentials. Azure Cosmos DB has ResourceTokens which enables fine grained access credentials.

Challenges/Gaps

Client instances ~ #tokens

Tokens are created on-demand (when new tenant created etc…), and new CosmosClient instances needs to be created to access data. Resulting in #clients approx. #tokens.

  • Anti-pattern: Cosmos recommends Singleton pattern
  • Non-optimal (result of multiple instances) and might result in throttling

Maintaining a valid token

Each token generated has a temporal validity after which are invalid. Application needs to keep re-generate new replacement tokens for the ones which are expiring.

  • Re-generation demands CosmosClient re-creation
  • Re-generation demands service interaction NW call
  • Maintain map of token -> validity

This issue is trying to address the CosmosClient gaps only. Hence token generation gaps are out-of-scope.

Possibilities

Authorization provider API

Abstract authorization into a plug-in MasterKey plug-in will be out-of-box, enable customization for ResourceToken based implementation. Draft below

  • Fully extensible: Can be even leveraged for credential swap/rotation
  • Advanced usage: Depth of knowledge to map cosmos addressing -> tenant. Get-started sample might help, still user need to maintain it.
  • Overloaded with non-user concerns: ex: Background calls, new resource addresses
abstract class ICosmosAuthorizationProvider
{
    string GetAuthorization(OperationContext context);
}

class MasterKeyAuthorizationProvider : ICosmosAuthorizationProvider
{
    public MasterKeyAuthorizationProvider(string masterKey)
    {
        ...
    }

    public override string GetAuthorization(OperationContext context)
    {
        return AuthorizationHelper.Generate..(context);
    }
}

class TokenAuthorizationProvider : ICosmosAuthorizationProvider
{
    private Dictionay<string, string> tenantToTokens;

    public MasterKeyAuthorizationProvider(string masterKey)
    {
        ...
    }

    public override string GetAuthorization(OperationContext context)
    {
        string tenant = GetTenant(context);
        return tenantToTokens[tenant];
    }
}

Request level credential

Application has full context of tenant and easier/intutive to pass required context into the API call. One possibility is to have it as ReqeustOption, draft below.

What about non-user invoke API concerns like background calls etc… few possibilities are

  • Use master key & assert its non-use through custom handler
  • Enable client-option to start with no-key & lazy bound initialization to API invocation
class RequestOptions
{
    ...
    public string Authorization { get; set; }
}

Recommendation

ReqeustOptions is simple and very intutive. And get started with “MasterKey” based constructor. Its a kind of override mechanism. Assertion of always override can be asserted through CustomHandler.

References:

https://docs.microsoft.com/en-us/azure/cosmos-db/secure-access-to-data#resource-tokens #622 ResourceTokens support

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:7
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
aarondcolemancommented, Nov 20, 2020

@kirankumarkolli bumping this as well. We’re in need of this functionality and opening and closing a CosmosClient is causing major connection issues in our application at scale.

2reactions
tomasdemlcommented, Nov 24, 2020

If I am not mistaken, the situation with multiple CosmosClient instances is exacerbated by the fact that the client owns an instance of the DocumentClient class which in turn owns an HttpClient. The http client is disposed with the DocumentClient when the CosmosClient is disposed. And we all know what this can lead to

Read more comments on GitHub >

github_iconTop Results From Across the Web

Azure Cosmos DB considerations for multitenancy
On this page, we describe some of the features of Azure Cosmos DB that are useful when you're working with multitenant systems.
Read more >
Best practices for Azure Cosmos DB .NET SDK
Enable 2-4 regions and replicate your accounts in multiple regions for best availability. For production workloads, enable service-managed ...
Read more >
Building multi-tenant systems using NServiceBus ... - YouTube
It is a simple matter to configure a Cosmos DB collection to use a tenant ID as the logical partition key. This is...
Read more >
Building Multitenant App using Azure Cosmos DB in Clean ...
Discuss how to build a multitenant web API application with partition per tenant data isolation using Azure Cosmos DB in Clean Architecture.
Read more >
Building multi-tenant systems using NServiceBus and ...
So basically we just need to configure a Cosmos clients and then we certainly just say use the Cosmos persistence and we give...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found