Hi Ryan & All,

Following a discussion with co-workers @Qwilt, as well as a earlier
discussion with Jeremy and Dewayne, I'll try to outline the main concepts
of a solution.


*As this email turned out to be long, I'll start with the conclusions:*

   1. As the first "tenancy introduction" phase includes only
   "org-tenancy", we may to assume that there is a single ISP using the TC
   instance, and that this ISP tenant is the ancestor of all content-provider
   tenants.
   Therefore, tenants hierarchy based decision is a reasonable solution for
   now.
   2. For the next phases we need to create a module that is able to
   provide the answer to the question:
    *"may operation <O1> on resource of type <R1> which belongs to tenant
   <T1> be performed by a user from tenant <T2> ?"*.
   This module can
      1. Be derived from a set of relations held in traffic-ops DB.
      Note that it may turn out to be complicated to cover all tenants
      relations use-cases and nuances.
      2. Be based on a "Resource-type | Resource-tenant | Operation |
      Operating-tenant" white-list table in traffic-ops DB, against
which we test
      each requested operation.
      Note that this table may be hard to maintain.
      3. Be delegated, fully or partially, to a specialized service outside
      traffic-ops.

Taking a step further, one may say that "tenant hierarchy" may be
considered just as one example for "tenants relationship", and as such we
need to decide if it deserved a special treatment.


============================================================

Now, for the full discussion.
Note that the discussion is a bit futuristic - suggesting a solution more
complicated than currently required/implemented for the step of "org (CP)
tenancy".

I'll first define the issue as I see it, in more technical terms:
Every resource in the system has tenancy, where tenancy in this context is
quite equivalent to "the organization the resource belongs to".
For example:

   1. *Delivery-Service*
   usually belongs to a content provider (CP), but can also belong to an ISP
   2. *CDN*
   usually belongs to an ISP
   3.
*User *belongs to the organization set as his "tenant".
   In this context, user as a resource has a single tenant. Tenants
   hierarchy is not relevant for this definition.
   4. *Tenant*
   belongs to its "parent" tenant


For each resource, there are users that can operate on it. For example

   1. *Delivery-Service*
   Edit the service - e.g. change the origin server, delete the DS
   2. *CDN*
   Edit the CDN - e.g. change the description, add a server to the CDN
   3.
*User *Manage the users in this tenant - e.g. add/remove user; reset
   password
   4. *Tenant*
   Create a sub tenant, change description,...


Who are these users (the users allowed to edit the resource)? The users who
has the proper "tenancy".
In this context "tenancy" means "permissions" (which resource can the user
access) and the user may have multiple accessible tenants, currently
derived from the tenants hierarchy.


As Ryan indicated, things get complicated when a user of one tenant needs
to access resources of tenant out of his tenants hierarchy.
To understand the below example, imagine that traffic-control evolves to a
product that can maintain CDNs of several ISPs, and hold delivery-services
of several content-providers.
In such a product a delivery-service will potentially be used for more than
a single CDN. I.e. the "cdn" field might be removed from the
"delivery-service" configuration and a "CDN / DS" table will be created to
indicate which DS is served by which CDNs.

Now, how can ISP "ISP1", that signed an agreement with content provider
"CP1", view the list delivery-services of content-provider "CP1"?
Additionally, how can he configure his CDN to serve one of "CP1" DSs?
As long as there is only one ISP in the traffic-control deployment (ISP1),
that is assumed to have agreements with all content-providers in the
system, we can just make "ISP1" tenant the parent of all content provider
tenants. This allows the ISP to view everything, and each content provider
can view only his own delivery-services.
However, this solution is not available if we have multiple ISPs in the
system, and does not support the granularity of which content-provider
information can be viewed by the ISP.
Furthermore, even in the single ISP scenario, such a solution allows ISP1
users not only to view "CP1" delivery-services, but also to edit them.


A more advanced solution, controlling the "inter-tenant" accessibility with
better granularity on both "operation" and "tenant" levels, is required.

What we practically need to verify in each operation is:
*"may the current user perform the operation <O1> on resource of type <R1>
which belongs to tenant <T1>?":*
For example (if you got the concept, just skip the grayed out examples):

   1. When presenting the information about a user "user1" (*GET
   api/1.2/user/user1*) we may test:
   'May the current user perform the operation "*read*" (==O1) on resource
   of type "*USER*" (==R1) which belongs to tenant "*user1->tenant*"
   (==T1)?'
   2. When changing the description of CDN "cdn1" (*PUT api/1.2/cdns/cdn1*)
   we may test:
   'May the current user perform the operation "*update*" (==O1) on
   resource of type "*CDN*" (==R1) which belongs to tenant "*cdn1->tenant*"
   (==T1)?'
   3. When deleting the delivery-service "ds1" (*DELETE
   api/1.2/deliveryservices/ds1*) we may test:
   'May the current user perform the operation "*delete*" (==O1) on
   resource of type "*DS*" (==R1) which belongs to tenant "*ds->tenant*"
   (==T1)?'
   4. When adding a new tenant with parent tenant "tn" (
   *POST api/1.2/tenants)* we may test:
   'May the current user perform the operation "*create*" (==O1) on
   resource of type "*TENANT*" (==R1) which belongs to tenant "*tn*"
   (==T1)?'
   5. When listing all delivery-services available for an ISP (*GET
   api/1.2/deliveryservices*), we can iterate over all delivery-services
   and present only those who pass the test:
   'May the current user perform the operation "*read*" (==O1) on resource
   of type "DS" (==R1) which belongs to tenant "*ds->tenant*" (==T1)?'
   6. For the operation of assigning a delivery-service "ds1" to the CDN
   "cdn1", I guess we would make 2 tests:
   1. 'May the current user perform the operation "*read*" (==O1) on
      resource of type "*DS*" (==R1) which belongs to tenant "*ds1->tenant*"
      (==T1)?'
      2. 'May the current user perform the operation "*update*" (==O1) on
      resource of type "*CDN*" (==R1) which belongs to tenant "
      *cdn1->tenant*" (==T1)?'

The remaining question is "How the answer to these questions can be
provided? Based on which information".
All the examples, but the last 2, can base the decision on the current user
tenant, and the tenants' hierarchy: The user would be able to access the
resource if the resource's tenant is below the user's tenant hierarchy.

The last 2 examples however are special, as the user from cdn1 needs to be
able to view a DS resource with unrelated tenancy.
My initial thought was that "we need to model somehow in traffic-control
that ISP1 works with CP1 and may have read access to its delivery-services".
However, based on his experience, Nir Ichye from our team convinced me that
we cannot really model within traffic-control all types and nuance of
agreements between tenants, and therefore we need some module that just
provides the answer to the question *"may operation <O1> on resource of
type <R1> which belongs to tenant <T1> be performed by a user from tenant
<T2> ?"*.

This can be done by one of the below options:

   1. Maintaining a white-list table within traffic control -
   "Resource-type | Resource-tenant | Operation | Operating-tenant" -
   according to which the operation will be permitted or blocked.
   Maintaining this table in a reasonable manner (operation wise) is an
   issue for itself.
   2. Delegate the question to another, specialized, micro-service.
   Personally, I tend towards this option.

Nir Ichye further suggested that "tenant's hierarchy" is just another type
of relations between tenants, and therefore should not get special
treatment and managed in the same way other relations do. This approach is
stronger than having just a tenant hierarchy in TC as we did so far. For
example, with tenant hierarchy we assume the parent tenant has full control
over all resources of the child tenant. Is this always the case? Should the
admin of the parent tenant be able to change-password for users in one of
its child tenant? Is the answer to this question the same for all
"parent/child" tenants in the system?
On the other hand, one may argue that the hierarchy is a simple enough
mechanism that may be sufficient for a large portion of the deployments,
and is justified as a simple solution for the use-case of "single ISP TC
deployments".

*We would highly appreciate any input on the entire issue.*

*Note again* that our first "tenancy" phase includes only "org-tenancy".
In this phase we can assume that there is a single ISP using the TC, and
this ISP is the ancestor of all content-provider tenants. Therefore we can
use tenant-hierarchy to answer just the below 2 tenancy access tests:

   1. "May the current user perform a '*read*' operation on *any resource*
    of* tenant 'T1'* ?"
   2. "May the current user perform a '*write*' operation on *any resource*
    of *tenant *'*T1*' ?"


Thanks,
Nir


On Tue, Apr 18, 2017 at 6:00 PM, Durfey, Ryan <[email protected]>
wrote:

> Responding to Nir’s comment on https://issues.apache.org/
> jira/browse/TC-217 Tenancy Feature Request
>
>
>
> I am trying to move the debate discussions into the email system.
>
> -Jira Ticket = Tracking development and deployment of code.
>
> -Email List = Active Debate/Discussion
>
> -Wiki = Summary of Key Concepts and Decisions
>
>
>
> Tenancy – User Access to Multiple Tenants
>
> I am struggling on the use case for viewing tenants outside one's assigned
> hierarchy.  This could get problematic in that it could allow users to see
> which companies have Tenant accounts on a CDN which could violate some
> non-disclosure agreements.  When we originally thought up Tenants, we
> assumed a user would only be assigned to one Tenant and would be able to
> see down their hierarchy.  However, we have since decided that a user may
> be assigned to multiple Tenants which should allow viewing across multiple
> Tenant hierarchies as long as they are explicitly assigned.
>
>
>
> A Tenant is really just a container for Services and Users.  The idea of
> seeing across different ISPs was brought up.  I haven’t given this enough
> thought yet but I don’t envision ISPs being a blocker.  An ISP would be a
> container for Caches that reside within its network.  This would be
> separate structure from Tenancy which relates to the physical servers,
> networks, and pricing of delivery.    A User in any Tenant should be able
> to see the ISP market place available to its services and could choose how
> caches are assigned to its services.   We probably need to put some more
> thought into how this works.
>
>
>
> *Ryan Durfey*
>
> Sr. Product Manager - CDN | Comcast Technology Solutions
>
> 1899 Wynkoop Ste. 550 | Denver, CO 80202
>
> M | 303-524-5099 <(303)%20524-5099>
>
> [email protected]
>
>
>
> https://issues.apache.org/jira/browse/TC-217
>
>
>
>
>
> [image: nirsopher]Nir Sopher
> <https://issues.apache.org/jira/secure/ViewProfile.jspa?name=nirsopher> added
> a comment - 5 hours ago - edited
>
> Hi,
> I believe we need to distinguish between the 2 terminologies:
> "descendent-tenants", and "allowed-tenants".
> A tenants has "descendent-tenants", all the tenants beneath it in the
> hierarchy.
> A user has its "allowed-tenants" - tenants he can view and manage.
>
> Currently, the to terms are closely related - the "allowed-tenants" of a
> user are the "descendent-tenants" of the user's tenant.
> But this is not necessarily the case.
> There are a few futuristic examples for users need to be able to view
> tenants not in his own tenant hierarchy.
> For example, when we have multiple ISPs in the TC, none of which can be
> "root" tenant, but the users of this tenants need to be able to view
> "org-tenants" in order to work with their delivery services.
>
> Therefore we suggested that:
> api/1.2/tenants - will show all tenants. Only tenants viewable to the
> current user will be shown.
> api/1.2/tenants/:id/subtenants - will show all "tenants" decendent to the
> specified one (still, under the limitation of what the current user can
> view)
>
> Do we need additionally
> api/1.2/users/:id/tenants - get all the tenants viewable to the specified
> user (still, under the limitation of what the current user can view)
> ?
>
> Nir
>
>
>

Reply via email to