My hope is that we can roll out "tenancy" in small, digestible, optional pieces to minimize impact. Here's how i see that rollout going. I'll probably skip over some details in my attempt to keep this short.
Phase 1 - Providing the ability to lock down (scope) delivery services Step #1 - support tenant CRUD -- a user w/ the proper permissions can CRUD tenants. remember, tenants have a required field - parentTenant - so you can really only create tenants inside the scope of your tenant :) -- i kind of envision an admin user with the "root" tenant will take a first pass at creating tenants (see example tenant tree below) Step #2 - support user->tenant assignment -- each user can be assigned 0 or 1 tenant -- i.e. user 1 will assign user 2 a tenant (but remember user 1 only has access to their tenant + children so user 2 can only be assigned a tenant from user 1's tenant hierarchy) Step #3 - support ds->tenant assignment -- each ds can be assigned 0 or 1 tenant -- user 1 will assign ds 1 a tenant (but remember user 1 only has access to their tenant + children so ds 1 can only be assigned a tenant from user 1's tenant hierarchy) ************************ Once phase 1 is complete, it could play out like this: 1. An admin user with the root tenant could take a first pass at creating tenants and we end up with this tenant hierarchy: - root (this tenant comes for free and cannot be modified) -- Org #1 --- Disney ---- ESPN ---- ABC ----- ABC Family --- Foo entertainment ---- Foo child 1 ---- Foo child 2 -- Org #2 2. With that tenant hierarchy in place, the admin user could start giving users the appropriate tenant -- all existing "admin" or "operations" users will probably be given the root tenant so they can see everything like they do today -- bob gets Disney meaning he can only see deliveryservices where tenant=null, disney, espn, abc or abc family -- cindy gets abc meaning she can only see deliveryservices where tenant=null, abc or abc family -- phil gets Foo child 1 meaning he can only see deliveryservices where tenant=null or Foo child 1 3. Start locking down delivery services by assigning them a tenant -- ds1 gets abc family meaning users with tenant=abc family or above can see ds1 -- ds2 gets disney meaning users with tenant=disney or above can see ds2 ******************* Remember, this is all optional. If you decide not to create tenants / assign users with a tenant / assign ds's with a tenants, then ds's are not scoped at all. That might be acceptable for many installations. However, after phase 1 is complete, you will now have the ability to (or not to) lock down delivery services as you please. Once that is done, I propose we talks about what the next phases are and the next set of resources (servers? cachegroups?) we attempt to lock down via tenancy. Thank you for your time :) Jeremy On Wed, Apr 19, 2017 at 10:05 AM, Nir Sopher <[email protected]> wrote: > 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 > > > > > > >
