Pyramid and Role-Based Access Control
Kleinfeldt, Sally
Snyder, Jesse
Mitchell, Alec
Ariadne Labs is a center for health systems innovation whose goal is to drive scalable solutions for better care. One of the projects at Ariadne Labs is the Better Evidence program, which provides free subscriptions to digital tools (such as the UpToDate decision support resource) to practitioners in developing countries. We assisted Ariadne in creating an improved Better Evidence website, making it easier for practitioners to apply and for administrators to review their applications. Although the application is long and involved and there are some interesting twists to the review process, this is basically a CRUD application that would have been suitable for a platform like Django except for one thing: the requirement for a placeful, role-based access control system. Because of this, we decided to use Pyramid. We will describe our solution, and contrast it with another Pyramid site with complex permission requirements, the Washington Trails Association's Volunteer Management System.
 Take over. Thank you, Eric. Oh, all right. So in this talk, we're going to describe two different projects, jazz, Carter projects for which we chose pyramid as the platform. Both those projects had a requirement to handle complex permissions, but the details of the projects were rather different. And let us do somewhat different solutions. So I'm going to talk, describe the first project here first, before we dive into the technical stuff. So the first project, the better evidence program was a project for Ariadne labs, which is a joint center for health systems innovation at Brigham and women's hospital in Boston, big hospital in Boston, jointly between the hospital and the Harvard T H chance school of public health. The goal of Ariadne labs is to design and scale health system solutions that can produce better care. It was founded by a fairly famous surgeon and Harvard professor and best selling author, I told the one day you see a picture of him there in the middle of the, the homepage. And he might have heard that name because he writes for the New Yorker magazine. And he was also recently named as a member of Joe Biden's covert 19 transition advisory board so very excited that that's a science is coming back into prominence in the US federal level anyway. So the better evidence program is one of Ariadne's programs and it is a tool to help free subscriptions to digital tools to practitioners in developing countries. So the up to date decision support resource and is an example of such a digital tool. And it is the subscription that is currently offered, although additional ones are planned in the future up to date is typically a fairly expensive subscription it costs 520 US dollars per year. And it is many times the cost of what people spend on health care in the settings of these practitioners that are applying for donated subscriptions. And that helps explain the willingness of the practitioners to go through a somewhat lengthy application process. So the better evidence website that we developed allows practitioners to apply for donated subscription. And it also allows for the administrators to review the applications. It's a fairly long complex five step application process that saves intermediate results at each step. First you create an account then fill out profile information then describe the medical site that the user works at then fill out a 30 plus question application form. And finally you get to write a short essay. So as I said it's a somewhat lengthy process. This is a screenshot of the giant application form just to emphasize the fact that it is rather long. We put a lot of effort into both presentation and widget choices on this form to make it as easy as possible for people to fill out. So the applicant users have a dashboard with dismissible notifications that shows any previous subscriptions and any previous application attempts. Then this is a review then there is a review system for admins. Here you see the screen for the application review work list. They can quickly scan new applications and accept or reject them. The key words in the applicant statement are highlighted in the, in yellow here in the little statements that go with the applications or essays. Admins can select from a menu of canned notification emails to send to the applicant. For example, explaining about how or why they should try again. Admins can also view all the application details by clicking on the application. And that includes a screen to show submission and approval history for the application. And they can leave internal notes on the applications for their colleagues or to remind themselves what's going on with the application. So medical sites have their own review screen. They're managed as separate objects since multiple applicants could work at the same medical site, of course. And new medical sites go through a review process also to make sure that they meet better evidence criteria. For example, for profit sites are not allowed in the program. Sometimes applicants inadvertently create duplicate medical sites by using an incorrect name or spelling or switching the order of words. And when admins discover duplicates, they can be merged together with the, with the original or correct medical site. You see the yellow icon on the right is the merge button. One more feature of the, of the site admins can also set different landing page messages to display to logged in versus anonymous users. Okay, now I'm going to turn it over to Jesse for a technical explanation of the site. Hey everybody. Let's see. So first I'll just go into a brief discussion of why we chose pyramid over other options. From the initial description of the project, we thought we were going to be building a very straightforward CRUD application. Applications we thought were likely to be in a standard format. And there would be just two categories of users. There'd be applicants who would submit and maybe edit applications. And then we'd have a fixed set of site administrators who would review the applications and apply some standard approval process. And since there's no reason to build admin UI, if you don't need to, we would have to do a lot of different things. We'll do a couple of models and views and we'll wire up, wire up the standard Django admin and we'll be 90% of the way there. Of course, more conversations with the client followed and the picture changed. So we had new requirements. And these included in addition to the core, better evidence, administrative requirements, and the application requirements. So there would soon be multiple products with different applicants, applications, and more importantly, admin teams. This multi product team model included a bunch of related feature requirements. So while some application questions would almost certainly be common to all products, many would not. Admins for product A need to review applications for their own product, and then we would have to do a lot of different things. So we would have to do a lot of different things. Workflow steps would likely vary between teams. So think. Simple, prone workflow versus some custom Byzantine workflow. Different teams might elect to do different things there. We needed to be ready to support permissions that varied by workflow state. So we had to do a lot of different things. And then we had to do a lot of different things. These are generally large hospitals or medical schools. And there was also some talk of a referral system. So it was becoming clear that this was no longer. Looking like a simple system. Specifically, we realized that Django really lacks the support for context based permissions that we needed here. And we needed to take action in a context that we needed to take action by in every context. But when you need to dictate that. One person can take some action in a context, but not another context. The support in Django is lacking. And as blown people, we, we really take all of this stuff for granted. And it's easy to forget that. This is pretty, pretty fancy stuff. Really. So we had to do a lot of different things. Based in pyramid. So an interesting aspect of the project was that a lot of the difficult requirements were not immediate. They were coming soon, but not right now. So we wanted to be able to start simple and then add complexity when the requirements actually emerged, especially around these permission requirements. And we wanted to be able to do that. So this was a really interesting thing. And it's a great thing for admins or users than a bunch of complex permissions stuff you're not actually using. We also wanted an established opinionated pattern for a wiring up permissions restrictions that didn't ooze into everything. And pyramid was really a great fit in this regard. So I'll go over some aspects of the pieces and how they fit together. I'll go through some of the things that we wanted to do. And I'll go through some of the things that we wanted to do. And I'll go ahead and go through the things that I wanted to do. These are all just ordinary sequel alchemy models, but this gives us a really flexible way to categorize users into groups, which we can then associate with permissions. So in our project, admins could be either global for better evidence staff or teams slash publisher specific. We can also use a lot of different types of roles. Our role models have a property which constructs principle identifiers based on both a publisher ID and a level like admin, for example. One or more of these roles can then get assigned to a user. So a quick reminder. A principle is just an identity for a user and they're often more than one. So we can use a principle. And we can also use a principle. And we can also use a principle. And we can also use an admin and a Jesse at email. Com principle. And principles are also the way you model arbitrary groups. You'd assign a bunch of users, the planista principle or whatever, and they could be treated as a group. That's basically how we're using them. We're just creating small publisher specific groups. And then the pyramid authentication model provides a standard way of doing it. So we can use principles and the user's associated role records, which we saw on the last slide, and then just aggregate them all. The resulting set of principles is what gets associated with the user when they log, or submit a request. And then the authorization half of this happens through ACLs. Access control list. Pyramid lets you set up context dependent permission by defining these ACLs. Critically for our project, we can programmatically determine the name for a principle to which will grant manage users permission, but only in the context of a specific publisher. So if we're in a part of the site under publisher one, users with principle publisher one admin will get the manage users permission, but principle two admin won't. And then the final bit of glue for all of this in pyramid is simple view decorators to declare permission restrictions. In the view, we just check for the manage users permission and that's all we care about here. So all the detail about how the user was granted that permission is out of our hair. And as we add new teams and possibly new ways of assigning principles and mapping them to permissions, this view will be completely unaffected. It may change for other reasons, of course, but you really don't need to think about the permission system very much once it's set up. You just go about your business with your other changes and that's pretty great. So now we're going to go back over to Sally, who's going to introduce our second case study, which is the Washington trails association. Great. Thanks, Jesse. So WTA or the Washington trails association provides extensive info about hikes in Washington state in the northwest corner of the US. Jesse and I are going to be giving a talk tomorrow describing WTA and their 13 year old Plum site. And I'm going to talk about the WTA and the WTA. But this talk is about their volunteer management system. As part of their mission to protect Washington's trails and wild lands, they organized trail maintenance work parties. And in 1999, a volunteer created a system to manage work party signups. He wrote it in Pearl. And it lasted until 2013. But by then they had pretty much outgrown it. And they needed a new volunteer management system. They hired just Carter to create the new system. And I'll just give you a quick tour of it. So WTA staff enter detailed information about the work parties in Salesforce, which is WTA's constituent relationship management system. And that information then gets displayed on the pyramid site through magic, which we're going to describe a little later. And then volunteers can filter, can search for work parties and filter them by criteria such as when they're happening, the type of work party, the region it is in, features like bridge building or bringing your family. And they can display the results of those filter queries in a list like shown here. Or display the results on a map as shown here. And handily they can also display the results on a calendar. They can click on the work party title and see detailed information and have a button to sign up for it. So the information includes the location of the work party on a map and also detailed driving directions. Pretty handy. The information includes what documents are required. For example, waivers that might need to be signed and you can fill out and sign those documents through this volunteer management system. And finally, the crew corner tab provides a message board where the leaders of the work party and the members can communicate amongst themselves and arrange carpooling, that sort of thing. And then the volunteers can register for a work party by just as a guest as an anonymous user on the site. But they can also log into their My Backpack account to register as a member of the site. My backpack being essentially their member account, their member profile. We'll be talking more about that tomorrow. That is a plon thing. So I'm going to turn it over to Alec for a technical explanation of the site. So I'm going to answer the question why pyramid. Our decision making process here is a little different than for better evidence. So our first thought was maybe we'd use plon. The reason is that WTA's primary website was already a plon site. So it would provide a seamless user experience. They have a ton of existing user accounts and plon has really great role based access control. We already have Salesforce synchronization on their site for all sorts of existing contents. And we also have a lot of other sites that are not available. And Jess Carter had already developed some similar kind of event management booking system using collective workspace for another client. And we thought we might be able to reuse that. But when we looked a little deeper, we thought maybe not plon. Doing a tightly coupled two way sync to Salesforce is tricky and can be prone to errors. And for this application, we would really need the data to be updated and then we would be able to use it as a platform to do that. And that's essentially right away from Salesforce. And that made that may that the synchronization we had in place that involves a lot of asynchronous. Operations not so useful. It was also very likely that, that we would see some performance issues, partly because of the Salesforce thinking, but also just because of general plon stuff and things around. And then we also had a lot of other things that we could do to make sure that we could use the Salesforce synchronization. And additionally, and perhaps the biggest concern from the client was that they didn't want to get further locked into a CMS platform that had a limited developer base. So our second thought was maybe we would build the whole thing in Salesforce. We could create a dynamic react front end. And that's something that really belongs in the CRM to begin with. They're already using Salesforce for all sorts of stuff. And there are a lot of Salesforce developers out there and we were going to be working with Salesforce developers in any case. However, when we look deeper, we thought, maybe not Salesforce. The issues were that it would make it almost impossible to do SSO with the Plon site, which is where all of the user accounts were. There might be some ways to do it, but they would probably be pretty expensive. Making direct API requests to Salesforce can potentially cause performance problems, single points of failure, and can get very expensive, especially when running on a nonprofit account where you have potential monthly API request limits. There's also no good options for caching if we're doing direct client site requests to Salesforce. And it was likely to have poor performance and reliability. So we went with a different solution, which is to take pyramid, which is very Pythonic. Good Python developers are relatively easy to find. Even if you can't find pyramid developers, most Python developers can get up to speed with the pyramid app pretty quickly so that eases maintainability and then react as a front end, which is also widely used and widely known and developers are easy to find. And so the architecture we chose looks like this. The flexible authorization system in pyramid lets us do SSO to the Plon using shared auth cookies. Registration data is cached in Redis on login and used to determine roles and permissions per user and per work party context. The work party data from Salesforce gets synced into an elastic search for high performance queries. The resulting system is loosely coupled to both Plon and Salesforce, except when you're logging in and modifying work party registrations. The system ended up being extremely fast because all the data for work party searches and primary work party views come straight out of the last elastic search. So now we're going to look at some of the code. First, the authorization part. We've got what pyramid calls a tween factory here that manages the SSO with the Plon site. If somebody visits this VMS site, which looks in a lot of ways like it's part of the Plon site and clicks the login button, they'll go over to the Plon login form. And once they log in, they get redirected back to pyramid with the JWT token in the query string. And then the user's email address. That JSON web token gets decoded by this tween here, which makes a call out to Salesforce with a user ID. And that returns contact details. And from that, we get everything we need to know about the user in Salesforce, the user Salesforce contact record, as well as any of the other data that they or any of their dependents have. All of that contact data stored in session and all the registration data is cached in Redis for making permission lookups. So this next bit is probably going to look very familiar to you from Jesse's portion a minute ago. We've got a group finder callback here. Users are pulled out of session and they are added to a variety of group principles. There are some that are user specific, some that are based on a global Salesforce role. And then there are a number that are going to be specific to any work party registrations that they already have. They can be registered to specific work parties with a volunteer role or an assistant crew leader role or crew leader role, all of their dependents also. They get groups representing all of their dependents so that they have permission to control any work party registrations that they for people that they're guardians for. Additionally, though it's not shown here in the code, there's a concept of land managers who are people who have some control over a specific area where a work party is happening. So these are usually people that work for some sort of governmental entity and they have certain rights to control or view information about a work party in their region. Here's the wiring. It's sort of some pyramid boilerplate. It's quite simple. The group factory is added to the authentication policy. The tween factory is registered as part of the authorization policy. And then cookie based sessions are set up and that's all there is to it. Once we've got all that information, we can start defining ACLs. We have a work party object, which is the context for most operations in the system. And that has an ACL and within that ACL, we assign permissions like view, roster, participate, assist, report, search, lead. And those permissions are assigned based on the principles, which can be work party specific. And there are land manager specific ones as well. And then these permissions end up being wired to views using decorators, just like Jesse showed earlier. So in summary, we had two projects, which were quite different in terms of user interactions, data models, backend storage. In the first one, the requirements for the sort of flexible permission structures that we're familiar with from Zocanplone led us to choose pyramid as the framework. In the second, performance concerns moved us away from Plone and the need for flexible permissions and authorization again led us to pyramid. In both cases, the ability to use relatively simple Python logic to map model attributes to roles and to declaratively configure access control is critical. We think the combination of performance and flexibility makes pyramid stand out from other frameworks and makes it ideal for medium to large web applications with complex and evolving requirements. Thank you. Awesome. Thanks, Alec and Jesse. And thank you all for watching. Presentation, we've got some recommended resources here. I'm just going to leave this up for a few minutes for you. While Eric turns to any questions that we can answer. And I encourage everybody to join us in the face to face session because it's really great to see your face. Exactly. Click the blue button below the video on loud form or just goes like I'm going to post there the link right now. And it's there. So I would love to see you all in the face to face. Thank you, Sally. Thank you, Jess. Thank you, Alec. That was really good talk. We do not have questions on Slido and on Slides. So just jump into the face to face. Thanks so much. Thank you. Thank you. Thank you.
 Take over.  Thank you, Eric.  Oh, all right.  So in this talk, we're going to describe two different projects, jazz,  Carter projects for which we chose pyramid as the platform.  Both those projects had a requirement to handle complex permissions,  but the details of the projects were rather different.  And let us do somewhat different solutions.  So I'm going to talk, describe the first project here first,  before we dive into the technical stuff.  So the first project, the better evidence program was a project for  Ariadne labs, which is a joint center for health systems innovation  at Brigham and women's hospital in Boston, big hospital in Boston,  jointly between the hospital and the Harvard T H chance school of public  health.  The goal of Ariadne labs is to design and scale health system solutions  that can produce better care.  It was founded by a fairly famous surgeon and Harvard professor and  best selling author, I told the one day you see a picture of him there in  the middle of the, the homepage.  And he might have heard that name because he writes for the New Yorker  magazine. And he was also recently named as a member of Joe Biden's  covert 19 transition advisory board so very excited that that's a science  is coming back into prominence in the US federal level anyway.  So the better evidence program is one of Ariadne's programs and it  is a tool to help free subscriptions to digital tools to practitioners  in developing countries. So the up to date decision support resource and  is an example of such a digital tool.  And it is the subscription that is currently offered, although additional  ones are planned in the future up to date is typically a fairly expensive  subscription it costs 520 US dollars per year.  And it is many times the cost of what people spend on health care in the  settings of these practitioners that are applying for donated subscriptions.  And that helps explain the willingness of the practitioners to go through a  somewhat lengthy application process.  So the better evidence website that we developed allows practitioners to  apply for donated subscription. And it also allows for the administrators to  review the applications.  It's a fairly long complex five step application process that saves  intermediate results at each step. First you create an account then fill out  profile information then describe the medical site that the user works at  then fill out a 30 plus question application form.  And finally you get to write a short essay. So as I said it's a somewhat  lengthy process.  This is a screenshot of the giant application form just to emphasize the  fact that it is rather long. We put a lot of effort into both presentation  and widget choices on this form to make it as easy as possible for people to fill out.  So the applicant users have a dashboard with dismissible notifications that  shows any previous subscriptions and any previous application attempts.  Then this is a review then there is a review system for admins.  Here you see the screen for the application review work list.  They can quickly scan new applications and accept or reject them.  The key words in the applicant statement are highlighted in the, in yellow  here in the little statements that go with the applications or essays.  Admins can select from a menu of canned notification emails to send to the  applicant. For example, explaining about how or why they should try again.  Admins can also view all the application details by clicking on the application.  And that includes a screen to show submission and approval history for the  application.  And they can leave internal notes on the applications for their colleagues or to  remind themselves what's going on with the application.  So medical sites have their own review screen.  They're managed as separate objects since multiple applicants could work at the  same medical site, of course.  And new medical sites go through a review process also to make sure that they meet  better evidence criteria. For example, for profit sites are not allowed in the  program.  Sometimes applicants inadvertently create duplicate medical sites by using an  incorrect name or spelling or switching the order of words.  And when admins discover duplicates, they can be merged together with the, with  the original or correct medical site. You see the yellow icon on the right is the  merge button.  One more feature of the, of the site admins can also set different landing  page messages to display to logged in versus anonymous users.  Okay, now I'm going to turn it over to Jesse for a technical explanation of the  site.  Hey everybody.  Let's see.  So first I'll just go into a brief discussion of why we chose pyramid  over other options.  From the initial description of the project, we thought we were going to be  building a very straightforward CRUD application.  Applications we thought were likely to be in a standard format.  And there would be just two categories of users. There'd be applicants who would  submit and maybe edit applications.  And then we'd have a fixed set of site administrators who would review the  applications and apply some standard approval process.  And since there's no reason to build admin UI, if you don't need to, we  would have to do a lot of different things.  We'll do a couple of models and views and we'll wire up,  wire up the standard Django admin and we'll be 90% of the way there.  Of course,  more conversations with the client followed and the picture changed.  So we had new requirements.  And these included in addition to the core, better evidence, administrative  requirements, and the application requirements.  So there would soon be multiple products with different applicants,  applications, and more importantly, admin teams.  This multi product team model included a bunch of related feature  requirements.  So while some application questions would almost certainly be common to all  products, many would not.  Admins for product A need to review applications for their own product,  and then we would have to do a lot of different things.  So we would have to do a lot of different things.  Workflow steps would likely vary between teams.  So think.  Simple,  prone workflow versus some custom Byzantine workflow.  Different teams might elect to do different things there.  We needed to be ready to support permissions that varied by workflow  state.  So we had to do a lot of different things.  And then we had to do a lot of different things.  These are generally large hospitals or medical schools.  And there was also some talk of a referral system.  So it was becoming clear that this was no longer.  Looking like a simple system.  Specifically, we realized that Django really lacks the support for  context based permissions that we needed here.  And we needed to take action in a context that we needed to take action  by in every context.  But when you need to dictate that.  One person can take some action in a context,  but not another context.  The support in Django is lacking.  And as blown people, we, we really take all of this stuff for granted.  And it's easy to forget that.  This is pretty, pretty fancy stuff.  Really.  So we had to do a lot of different things.  Based in pyramid.  So an interesting aspect of the project was that a lot of the  difficult requirements were not immediate.  They were coming soon, but not right now.  So we wanted to be able to start simple and then add complexity when  the requirements actually emerged,  especially around these permission requirements.  And we wanted to be able to do that.  So this was a really interesting thing.  And it's a great thing for admins or users than a bunch of complex  permissions stuff you're not actually using.  We also wanted an established opinionated pattern for a wiring up  permissions restrictions that didn't ooze into everything.  And pyramid was really a great fit in this regard.  So I'll go over some aspects of the pieces and how they fit together.  I'll go through some of the things that we wanted to do.  And I'll go through some of the things that we wanted to do.  And I'll go ahead and go through the things that I wanted to do.  These are all just ordinary sequel alchemy models,  but this gives us a really flexible way to categorize users into  groups, which we can then associate with permissions.  So in our project,  admins could be either global for better evidence staff or teams  slash publisher specific.  We can also use a lot of different types of roles.  Our role models have a property which constructs principle  identifiers based on both a publisher ID and a level like admin,  for example.  One or more of these roles can then get assigned to a user.  So a quick reminder.  A principle is just an identity for a user and they're often more than  one.  So we can use a principle.  And we can also use a principle.  And we can also use a principle.  And we can also use an admin and a Jesse at email.  Com principle.  And principles are also the way you model arbitrary groups.  You'd assign a bunch of users, the planista principle or whatever,  and they could be treated as a group.  That's basically how we're using them.  We're just creating small publisher specific groups.  And then the pyramid authentication model provides a standard way of  doing it.  So we can use principles and the user's associated role records,  which we saw on the last slide, and then just aggregate them all.  The resulting set of principles is what gets associated with the  user when they log,  or submit a request.  And then the authorization half of this happens through ACLs.  Access control list.  Pyramid lets you set up context dependent permission by defining  these ACLs.  Critically for our project,  we can programmatically determine the name for a principle to which  will grant manage users permission,  but only in the context of a specific publisher.  So if we're in a part of the site under publisher one,  users with principle publisher one admin will get the manage users  permission,  but principle two admin won't.  And then the final bit of glue for all of this in pyramid is simple  view decorators to declare permission restrictions.  In the view,  we just check for the manage users permission and that's all we care  about here.  So all the detail about how the user was granted that permission is out  of our hair.  And as we add new teams and possibly new ways of assigning  principles and mapping them to permissions,  this view will be completely unaffected.  It may change for other reasons, of course,  but you really don't need to think about the permission system very  much once it's set up.  You just go about your business with your other changes and that's  pretty great.  So now we're going to go back over to Sally,  who's going to introduce our second case study,  which is the Washington trails association.  Great. Thanks, Jesse.  So WTA or the Washington trails association provides extensive  info about hikes in Washington state in the northwest corner of the  US.  Jesse and I are going to be giving a talk tomorrow describing WTA and  their 13 year old Plum site.  And I'm going to talk about the WTA and the WTA.  But this talk is about their volunteer management system.  As part of their mission to protect Washington's trails and wild  lands, they organized trail maintenance work parties.  And in 1999, a volunteer created a system to manage work party  signups.  He wrote it in Pearl.  And it lasted until 2013.  But by then they had pretty much outgrown it.  And they needed a new volunteer management system.  They hired just Carter to create the new system.  And I'll just give you a quick tour of it.  So WTA staff enter detailed information about the work parties in  Salesforce, which is WTA's constituent relationship management  system.  And that information then gets displayed on the pyramid site through  magic, which we're going to describe a little later.  And then volunteers can filter,  can search for work parties and filter them by criteria such as  when they're happening, the type of work party, the region it is in,  features like bridge building or bringing your family.  And they can display the results of those filter queries in a list  like shown here.  Or display the results on a map as shown here.  And handily they can also display the results on a calendar.  They can click on the work party title and see detailed information  and have a button to sign up for it.  So the information includes the location of the work party on a  map and also detailed driving directions.  Pretty handy.  The information includes what documents are required.  For example, waivers that might need to be signed and you can fill out  and sign those documents through this volunteer management system.  And finally, the crew corner tab provides a message board where the  leaders of the work party and the members can communicate amongst  themselves and arrange carpooling, that sort of thing.  And then the volunteers can register for a work party by  just as a guest as an anonymous user on the site.  But they can also log into their My Backpack account to register as a  member of the site.  My backpack being essentially their member account, their member profile.  We'll be talking more about that tomorrow.  That is a plon thing.  So I'm going to turn it over to Alec for a technical explanation of  the site.  So I'm going to answer the question why pyramid.  Our decision making process here is a little different than for better  evidence.  So our first thought was maybe we'd use plon.  The reason is that WTA's primary website was already a plon site.  So it would provide a seamless user experience.  They have a ton of existing user accounts and plon has really great  role based access control.  We already have Salesforce synchronization on their site for all  sorts of existing contents.  And we also have a lot of other sites that are not available.  And Jess Carter had already developed some similar kind of event  management booking system using collective workspace for another  client.  And we thought we might be able to reuse that.  But when we looked a little deeper, we thought maybe not plon.  Doing a tightly coupled two way sync to Salesforce is tricky and can be  prone to errors.  And for this application, we would really need the data to be updated  and then we would be able to use it as a platform to do that.  And that's essentially right away from Salesforce.  And that made that may that the synchronization we had in place that  involves a lot of asynchronous.  Operations not so useful.  It was also very likely that, that we would see some performance issues,  partly because of the Salesforce thinking,  but also just because of general plon stuff and things around.  And then we also had a lot of other things that we could do to  make sure that we could use the Salesforce synchronization.  And additionally, and perhaps the biggest concern from the client was  that they didn't want to get further locked into a CMS platform that  had a limited developer base.  So our second thought was maybe we would build the whole thing in  Salesforce.  We could create a dynamic react front end.  And that's something that really belongs in the CRM to begin with.  They're already using Salesforce for all sorts of stuff.  And there are a lot of Salesforce developers out there and we were going  to be working with Salesforce developers in any case.  However, when we look deeper, we thought, maybe not Salesforce.  The issues were that it would make it almost impossible to do SSO with  the Plon site, which is where all of the user accounts were.  There might be some ways to do it, but they would probably be pretty  expensive.  Making direct API requests to Salesforce can potentially cause  performance problems, single points of failure, and can get very  expensive, especially when running on a nonprofit account where you  have potential monthly API request limits.  There's also no good options for caching if we're doing direct client  site requests to Salesforce.  And it was likely to have poor performance and reliability.  So we went with a different solution, which is to take pyramid,  which is very Pythonic.  Good Python developers are relatively easy to find.  Even if you can't find pyramid developers, most Python developers can  get up to speed with the pyramid app pretty quickly so that eases  maintainability and then react as a front end, which is also widely used  and widely known and developers are easy to find.  And so the architecture we chose looks like this.  The flexible authorization system in pyramid lets us do SSO to  the Plon using shared auth cookies.  Registration data is cached in Redis on login and used to determine roles  and permissions per user and per work party context.  The work party data from Salesforce gets synced into an elastic search  for high performance queries.  The resulting system is loosely coupled to both Plon and Salesforce,  except when you're logging in and modifying work party registrations.  The system ended up being extremely fast because all the data for  work party searches and primary work party views come straight out of  the last elastic search.  So now we're going to look at some of the code.  First, the authorization part.  We've got what pyramid calls a tween factory here that manages the SSO  with the Plon site.  If somebody visits this VMS site, which looks in a lot of ways like  it's part of the Plon site and clicks the login button, they'll go  over to the Plon login form.  And once they log in, they get redirected back to pyramid with the  JWT token in the query string.  And then the user's email address.  That JSON web token gets decoded by this tween here,  which makes a call out to Salesforce with a user ID.  And that returns contact details.  And from that, we get everything we need to know about the user in  Salesforce, the user Salesforce contact record, as well as any  of the other data that they or any of their dependents have.  All of that contact data stored in session and all the registration  data is cached in Redis for making permission lookups.  So this next bit is probably going to look very familiar to you from  Jesse's portion a minute ago.  We've got a group finder callback here.  Users are pulled out of session and they are added to a variety of  group principles.  There are some that are user specific, some that are based on a  global Salesforce role.  And then there are a number that are going to be specific to any  work party registrations that they already have.  They can be registered to specific work parties with a volunteer  role or an assistant crew leader role or crew leader role, all of  their dependents also.  They get groups representing all of their dependents so that they  have permission to control any work party registrations that they  for people that they're guardians for.  Additionally, though it's not shown here in the code, there's a  concept of land managers who are people who have some control over  a specific area where a work party is happening.  So these are usually people that work for some sort of governmental  entity and they have certain rights to control or view information  about a work party in their region.  Here's the wiring.  It's sort of some pyramid boilerplate.  It's quite simple.  The group factory is added to the authentication policy.  The tween factory is registered as part of the authorization policy.  And then cookie based sessions are set up and that's all there is to  it.  Once we've got all that information, we can start defining ACLs.  We have a work party object, which is the context for most  operations in the system.  And that has an ACL and within that ACL, we assign permissions like  view, roster, participate, assist, report, search, lead.  And those permissions are assigned based on the principles, which  can be work party specific.  And there are land manager specific ones as well.  And then these permissions end up being wired to views using  decorators, just like Jesse showed earlier.  So in summary, we had two projects, which were quite different in  terms of user interactions, data models, backend storage.  In the first one, the requirements for the sort of flexible  permission structures that we're familiar with from Zocanplone  led us to choose pyramid as the framework.  In the second, performance concerns moved us away from  Plone and the need for flexible permissions and authorization  again led us to pyramid.  In both cases, the ability to use relatively simple Python logic  to map model attributes to roles and to declaratively configure  access control is critical.  We think the combination of performance and flexibility makes  pyramid stand out from other frameworks and makes it ideal  for medium to large web applications with complex and  evolving requirements.  Thank you.  Awesome.  Thanks, Alec and Jesse.  And thank you all for watching.  Presentation, we've got some recommended resources here.  I'm just going to leave this up for a few minutes for you.  While Eric turns to any questions that we can answer.  And I encourage everybody to join us in the face to face session  because it's really great to see your face.  Exactly.  Click the blue button below the video on loud form or just goes  like I'm going to post there the link right now.  And it's there.  So I would love to see you all in the face to face.  Thank you, Sally.  Thank you, Jess.  Thank you, Alec.  That was really good talk.  We do not have questions on Slido and on Slides.  So just jump into the face to face.  Thanks so much.  Thank you.  Thank you.  Thank you.
Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_0_179.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_180_683.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_684_2423.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_2424_3923.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_3924_4019.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_4020_4295.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_4296_4427.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_4428_4547.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_4548_5003.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_5004_5459.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_5460_5819.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_5820_6875.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_6876_7511.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_7512_8735.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_8736_9143.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_9144_9323.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_9324_9551.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_9552_10247.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_10248_10379.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_10380_10835.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_10836_13979.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_13980_15263.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_15264_17351.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_17352_18059.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_18060_19091.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_19092_20375.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_20376_21971.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_21972_23267.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_23268_24455.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_24456_25487.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_25488_25667.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_25668_28091.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_28092_28691.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_28692_30539.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_30540_31655.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_31656_33455.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_33456_35327.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_35328_36947.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_36948_39311.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_39312_39395.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_39396_39755.png Pyramid_and_Role-Based_Access_Control_-_Sally_Klei_Zi6bBzGYSY4_39756_39763.png
Take over. Thank you, Eric. Oh, all right. So in this talk, we're going to describe two different projects, jazz, Carter projects for which we chose pyramid as the platform. Both those projects had a requirement to handle complex permissions, but the details of the projects were rather different. And let us do somewhat different solutions. So I'm going to talk, describe the first project here first, before we dive into the technical stuff. So the first project, the better evidence program was a project for Ariadne labs, which is a joint center for health systems innovation at Brigham and women's hospital in Boston, big hospital in Boston, jointly between the hospital and the Harvard T H chance school of public health. The goal of Ariadne labs is to design and scale health system solutions that can produce better care. It was founded by a fairly famous surgeon and Harvard professor and best selling author, I told the one day you see a picture of him there in the middle of the, the homepage. And he might have heard that name because he writes for the New Yorker magazine. And he was also recently named as a member of Joe Biden's covert 19 transition advisory board so very excited that that's a science is coming back into prominence in the US federal level anyway. So the better evidence program is one of Ariadne's programs and it is a tool to help free subscriptions to digital tools to practitioners in developing countries. So the up to date decision support resource and is an example of such a digital tool. And it is the subscription that is currently offered, although additional ones are planned in the future up to date is typically a fairly expensive subscription it costs 520 US dollars per year. And it is many times the cost of what people spend on health care in the settings of these practitioners that are applying for donated subscriptions. And that helps explain the willingness of the practitioners to go through a somewhat lengthy application process. So the better evidence website that we developed allows practitioners to apply for donated subscription. And it also allows for the administrators to review the applications. It's a fairly long complex five step application process that saves intermediate results at each step. First you create an account then fill out profile information then describe the medical site that the user works at then fill out a 30 plus question application form. And finally you get to write a short essay. So as I said it's a somewhat lengthy process. This is a screenshot of the giant application form just to emphasize the fact that it is rather long. We put a lot of effort into both presentation and widget choices on this form to make it as easy as possible for people to fill out. So the applicant users have a dashboard with dismissible notifications that shows any previous subscriptions and any previous application attempts. Then this is a review then there is a review system for admins. Here you see the screen for the application review work list. They can quickly scan new applications and accept or reject them. The key words in the applicant statement are highlighted in the, in yellow here in the little statements that go with the applications or essays. Admins can select from a menu of canned notification emails to send to the applicant. For example, explaining about how or why they should try again. Admins can also view all the application details by clicking on the application. And that includes a screen to show submission and approval history for the application. And they can leave internal notes on the applications for their colleagues or to remind themselves what's going on with the application. So medical sites have their own review screen. They're managed as separate objects since multiple applicants could work at the same medical site, of course. And new medical sites go through a review process also to make sure that they meet better evidence criteria. For example, for profit sites are not allowed in the program. Sometimes applicants inadvertently create duplicate medical sites by using an incorrect name or spelling or switching the order of words. And when admins discover duplicates, they can be merged together with the, with the original or correct medical site. You see the yellow icon on the right is the merge button. One more feature of the, of the site admins can also set different landing page messages to display to logged in versus anonymous users. Okay, now I'm going to turn it over to Jesse for a technical explanation of the site. Hey everybody. Let's see. So first I'll just go into a brief discussion of why we chose pyramid over other options. From the initial description of the project, we thought we were going to be building a very straightforward CRUD application. Applications we thought were likely to be in a standard format. And there would be just two categories of users. There'd be applicants who would submit and maybe edit applications. And then we'd have a fixed set of site administrators who would review the applications and apply some standard approval process. And since there's no reason to build admin UI, if you don't need to, we would have to do a lot of different things. We'll do a couple of models and views and we'll wire up, wire up the standard Django admin and we'll be 90% of the way there. Of course, more conversations with the client followed and the picture changed. So we had new requirements. And these included in addition to the core, better evidence, administrative requirements, and the application requirements. So there would soon be multiple products with different applicants, applications, and more importantly, admin teams. This multi product team model included a bunch of related feature requirements. So while some application questions would almost certainly be common to all products, many would not. Admins for product A need to review applications for their own product, and then we would have to do a lot of different things. So we would have to do a lot of different things. Workflow steps would likely vary between teams. So think. Simple, prone workflow versus some custom Byzantine workflow. Different teams might elect to do different things there. We needed to be ready to support permissions that varied by workflow state. So we had to do a lot of different things. And then we had to do a lot of different things. These are generally large hospitals or medical schools. And there was also some talk of a referral system. So it was becoming clear that this was no longer. Looking like a simple system. Specifically, we realized that Django really lacks the support for context based permissions that we needed here. And we needed to take action in a context that we needed to take action by in every context. But when you need to dictate that. One person can take some action in a context, but not another context. The support in Django is lacking. And as blown people, we, we really take all of this stuff for granted. And it's easy to forget that. This is pretty, pretty fancy stuff. Really. So we had to do a lot of different things. Based in pyramid. So an interesting aspect of the project was that a lot of the difficult requirements were not immediate. They were coming soon, but not right now. So we wanted to be able to start simple and then add complexity when the requirements actually emerged, especially around these permission requirements. And we wanted to be able to do that. So this was a really interesting thing. And it's a great thing for admins or users than a bunch of complex permissions stuff you're not actually using. We also wanted an established opinionated pattern for a wiring up permissions restrictions that didn't ooze into everything. And pyramid was really a great fit in this regard. So I'll go over some aspects of the pieces and how they fit together. I'll go through some of the things that we wanted to do. And I'll go through some of the things that we wanted to do. And I'll go ahead and go through the things that I wanted to do. These are all just ordinary sequel alchemy models, but this gives us a really flexible way to categorize users into groups, which we can then associate with permissions. So in our project, admins could be either global for better evidence staff or teams slash publisher specific. We can also use a lot of different types of roles. Our role models have a property which constructs principle identifiers based on both a publisher ID and a level like admin, for example. One or more of these roles can then get assigned to a user. So a quick reminder. A principle is just an identity for a user and they're often more than one. So we can use a principle. And we can also use a principle. And we can also use a principle. And we can also use an admin and a Jesse at email. Com principle. And principles are also the way you model arbitrary groups. You'd assign a bunch of users, the planista principle or whatever, and they could be treated as a group. That's basically how we're using them. We're just creating small publisher specific groups. And then the pyramid authentication model provides a standard way of doing it. So we can use principles and the user's associated role records, which we saw on the last slide, and then just aggregate them all. The resulting set of principles is what gets associated with the user when they log, or submit a request. And then the authorization half of this happens through ACLs. Access control list. Pyramid lets you set up context dependent permission by defining these ACLs. Critically for our project, we can programmatically determine the name for a principle to which will grant manage users permission, but only in the context of a specific publisher. So if we're in a part of the site under publisher one, users with principle publisher one admin will get the manage users permission, but principle two admin won't. And then the final bit of glue for all of this in pyramid is simple view decorators to declare permission restrictions. In the view, we just check for the manage users permission and that's all we care about here. So all the detail about how the user was granted that permission is out of our hair. And as we add new teams and possibly new ways of assigning principles and mapping them to permissions, this view will be completely unaffected. It may change for other reasons, of course, but you really don't need to think about the permission system very much once it's set up. You just go about your business with your other changes and that's pretty great. So now we're going to go back over to Sally, who's going to introduce our second case study, which is the Washington trails association. Great. Thanks, Jesse. So WTA or the Washington trails association provides extensive info about hikes in Washington state in the northwest corner of the US. Jesse and I are going to be giving a talk tomorrow describing WTA and their 13 year old Plum site. And I'm going to talk about the WTA and the WTA. But this talk is about their volunteer management system. As part of their mission to protect Washington's trails and wild lands, they organized trail maintenance work parties. And in 1999, a volunteer created a system to manage work party signups. He wrote it in Pearl. And it lasted until 2013. But by then they had pretty much outgrown it. And they needed a new volunteer management system. They hired just Carter to create the new system. And I'll just give you a quick tour of it. So WTA staff enter detailed information about the work parties in Salesforce, which is WTA's constituent relationship management system. And that information then gets displayed on the pyramid site through magic, which we're going to describe a little later. And then volunteers can filter, can search for work parties and filter them by criteria such as when they're happening, the type of work party, the region it is in, features like bridge building or bringing your family. And they can display the results of those filter queries in a list like shown here. Or display the results on a map as shown here. And handily they can also display the results on a calendar. They can click on the work party title and see detailed information and have a button to sign up for it. So the information includes the location of the work party on a map and also detailed driving directions. Pretty handy. The information includes what documents are required. For example, waivers that might need to be signed and you can fill out and sign those documents through this volunteer management system. And finally, the crew corner tab provides a message board where the leaders of the work party and the members can communicate amongst themselves and arrange carpooling, that sort of thing. And then the volunteers can register for a work party by just as a guest as an anonymous user on the site. But they can also log into their My Backpack account to register as a member of the site. My backpack being essentially their member account, their member profile. We'll be talking more about that tomorrow. That is a plon thing. So I'm going to turn it over to Alec for a technical explanation of the site. So I'm going to answer the question why pyramid. Our decision making process here is a little different than for better evidence. So our first thought was maybe we'd use plon. The reason is that WTA's primary website was already a plon site. So it would provide a seamless user experience. They have a ton of existing user accounts and plon has really great role based access control. We already have Salesforce synchronization on their site for all sorts of existing contents. And we also have a lot of other sites that are not available. And Jess Carter had already developed some similar kind of event management booking system using collective workspace for another client. And we thought we might be able to reuse that. But when we looked a little deeper, we thought maybe not plon. Doing a tightly coupled two way sync to Salesforce is tricky and can be prone to errors. And for this application, we would really need the data to be updated and then we would be able to use it as a platform to do that. And that's essentially right away from Salesforce. And that made that may that the synchronization we had in place that involves a lot of asynchronous. Operations not so useful. It was also very likely that, that we would see some performance issues, partly because of the Salesforce thinking, but also just because of general plon stuff and things around. And then we also had a lot of other things that we could do to make sure that we could use the Salesforce synchronization. And additionally, and perhaps the biggest concern from the client was that they didn't want to get further locked into a CMS platform that had a limited developer base. So our second thought was maybe we would build the whole thing in Salesforce. We could create a dynamic react front end. And that's something that really belongs in the CRM to begin with. They're already using Salesforce for all sorts of stuff. And there are a lot of Salesforce developers out there and we were going to be working with Salesforce developers in any case. However, when we look deeper, we thought, maybe not Salesforce. The issues were that it would make it almost impossible to do SSO with the Plon site, which is where all of the user accounts were. There might be some ways to do it, but they would probably be pretty expensive. Making direct API requests to Salesforce can potentially cause performance problems, single points of failure, and can get very expensive, especially when running on a nonprofit account where you have potential monthly API request limits. There's also no good options for caching if we're doing direct client site requests to Salesforce. And it was likely to have poor performance and reliability. So we went with a different solution, which is to take pyramid, which is very Pythonic. Good Python developers are relatively easy to find. Even if you can't find pyramid developers, most Python developers can get up to speed with the pyramid app pretty quickly so that eases maintainability and then react as a front end, which is also widely used and widely known and developers are easy to find. And so the architecture we chose looks like this. The flexible authorization system in pyramid lets us do SSO to the Plon using shared auth cookies. Registration data is cached in Redis on login and used to determine roles and permissions per user and per work party context. The work party data from Salesforce gets synced into an elastic search for high performance queries. The resulting system is loosely coupled to both Plon and Salesforce, except when you're logging in and modifying work party registrations. The system ended up being extremely fast because all the data for work party searches and primary work party views come straight out of the last elastic search. So now we're going to look at some of the code. First, the authorization part. We've got what pyramid calls a tween factory here that manages the SSO with the Plon site. If somebody visits this VMS site, which looks in a lot of ways like it's part of the Plon site and clicks the login button, they'll go over to the Plon login form. And once they log in, they get redirected back to pyramid with the JWT token in the query string. And then the user's email address. That JSON web token gets decoded by this tween here, which makes a call out to Salesforce with a user ID. And that returns contact details. And from that, we get everything we need to know about the user in Salesforce, the user Salesforce contact record, as well as any of the other data that they or any of their dependents have. All of that contact data stored in session and all the registration data is cached in Redis for making permission lookups. So this next bit is probably going to look very familiar to you from Jesse's portion a minute ago. We've got a group finder callback here. Users are pulled out of session and they are added to a variety of group principles. There are some that are user specific, some that are based on a global Salesforce role. And then there are a number that are going to be specific to any work party registrations that they already have. They can be registered to specific work parties with a volunteer role or an assistant crew leader role or crew leader role, all of their dependents also. They get groups representing all of their dependents so that they have permission to control any work party registrations that they for people that they're guardians for. Additionally, though it's not shown here in the code, there's a concept of land managers who are people who have some control over a specific area where a work party is happening. So these are usually people that work for some sort of governmental entity and they have certain rights to control or view information about a work party in their region. Here's the wiring. It's sort of some pyramid boilerplate. It's quite simple. The group factory is added to the authentication policy. The tween factory is registered as part of the authorization policy. And then cookie based sessions are set up and that's all there is to it. Once we've got all that information, we can start defining ACLs. We have a work party object, which is the context for most operations in the system. And that has an ACL and within that ACL, we assign permissions like view, roster, participate, assist, report, search, lead. And those permissions are assigned based on the principles, which can be work party specific. And there are land manager specific ones as well. And then these permissions end up being wired to views using decorators, just like Jesse showed earlier. So in summary, we had two projects, which were quite different in terms of user interactions, data models, backend storage. In the first one, the requirements for the sort of flexible permission structures that we're familiar with from Zocanplone led us to choose pyramid as the framework. In the second, performance concerns moved us away from Plone and the need for flexible permissions and authorization again led us to pyramid. In both cases, the ability to use relatively simple Python logic to map model attributes to roles and to declaratively configure access control is critical. We think the combination of performance and flexibility makes pyramid stand out from other frameworks and makes it ideal for medium to large web applications with complex and evolving requirements. Thank you. Awesome. Thanks, Alec and Jesse. And thank you all for watching. Presentation, we've got some recommended resources here. I'm just going to leave this up for a few minutes for you. While Eric turns to any questions that we can answer. And I encourage everybody to join us in the face to face session because it's really great to see your face. Exactly. Click the blue button below the video on loud form or just goes like I'm going to post there the link right now. And it's there. So I would love to see you all in the face to face. Thank you, Sally. Thank you, Jess. Thank you, Alec. That was really good talk. We do not have questions on Slido and on Slides. So just jump into the face to face. Thanks so much. Thank you. Thank you. Thank you.
permissions, but the details of the projects were project, the better evidence program was a project for Ariadne labs, which is a joint center for health systems innovation at Brigham and health system solutions that can produce better it is a tool to help free subscriptions to digital tools to practitioners in developing countries. So the up to date decision support resource and is an example of such a digital allows practitioners to apply for donated administrators to review the applications. It's a fairly long complex five step application process a very straightforward CRUD application. application requirements. So there would soon be their own product, and then we would have to do a not another context. The support in Django is that. So this was a really interesting thing. And website was already a plon site. So it would great role based access control. We already have to use it as a platform to do that. And that's with a different solution, which is to take are some that are user specific, some that are