<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: ssglaser</title>
    <description>The latest articles on Forem by ssglaser (@ssglaser).</description>
    <link>https://forem.com/ssglaser</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F489784%2F174ed6c8-120b-47fe-b83c-2d501437badf.png</url>
      <title>Forem: ssglaser</title>
      <link>https://forem.com/ssglaser</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ssglaser"/>
    <language>en</language>
    <item>
      <title>Building a VS Code extension with Rust, WebAssembly, and TypeScript</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Mon, 10 Jan 2022 20:20:24 +0000</pubDate>
      <link>https://forem.com/ssglaser/building-a-vs-code-extension-with-rust-webassembly-and-typescript-1hl2</link>
      <guid>https://forem.com/ssglaser/building-a-vs-code-extension-with-rust-webassembly-and-typescript-1hl2</guid>
      <description>&lt;p&gt;New post out on how we built a VS Code extension with Rust, WebAssembly, and TypeScript Dive in to walk through our design decisions in building the extension, how an IDE extension works and more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.osohq.com/post/building-vs-code-extension-with-rust-wasm-typescript"&gt;https://www.osohq.com/post/building-vs-code-extension-with-rust-wasm-typescript&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>rust</category>
      <category>webassembly</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How We Built a Cross-Platform Library with Rust</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Tue, 26 Oct 2021 16:38:34 +0000</pubDate>
      <link>https://forem.com/ssglaser/how-we-built-a-cross-platform-library-with-rust-3mf8</link>
      <guid>https://forem.com/ssglaser/how-we-built-a-cross-platform-library-with-rust-3mf8</guid>
      <description>&lt;p&gt;When we create a new release of Oso, we run 87 different Github actions. Those actions build libraries for 6 different languages and test them on different versions of the language across 3 different operating systems. Oso has libraries for Python, Ruby, Java, Javascript, Go, and Rust, and each of those libraries works on Linux, Windows, and macOS. Every library is based on a core that is written in Rust. That allows us to support so many languages without rewriting every feature 6 times. &lt;/p&gt;

&lt;p&gt;See new post out to learn how it all works: &lt;a href="https://www.osohq.com/post/cross-platform-rust-libraries"&gt;https://www.osohq.com/post/cross-platform-rust-libraries&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Enforcing Authorization in your Application
</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Thu, 17 Jun 2021 18:33:12 +0000</pubDate>
      <link>https://forem.com/ssglaser/enforcing-authorization-in-your-application-5aa5</link>
      <guid>https://forem.com/ssglaser/enforcing-authorization-in-your-application-5aa5</guid>
      <description>&lt;h2&gt;
  
  
  1. What this guide covers
&lt;/h2&gt;

&lt;p&gt;Back in Chapter II we covered authorization architecture and walked through the life of a request in our GitClub sample application. We saw there are a few places that we might want to add authorization, and that these center on the question: is the actor allowed to perform action on this resource? This question is our authorization interface, and the two sides of that interface are the decision and the enforcement.&lt;/p&gt;

&lt;p&gt;In Chapters III and IV we looked at how we can use authorization models to make authorization decisions. These models included roles and relationships.&lt;/p&gt;

&lt;p&gt;This chapter covers enforcement, the second half of our authorization = decision + enforcement equation that we introduced in Chapter II. We provide a model for determining where to enforce authorization, what you should be enforcing at those places, how to connect enforcement to the decision mechanism, and what to do with the decision.&lt;/p&gt;

&lt;p&gt;As with the previous chapters, we continue to use our GitClub example application. As a reminder: GitClub is a website for source code hosting, collaboration, and version control, similar to real-life applications GitLab and GitHub. GitClub offers a pure example of what motivates authorization in the first place – securing access to resources. A "resource" is "something that can be accessed", like a repository in GitClub. Users may or may not be able to read or make changes to a repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is enforcement?
&lt;/h3&gt;

&lt;p&gt;In the last two chapters, we’ve walked through how to make the authorization decision: should this actor be able to take this action on this resource? Enforcement is the process of requesting that authorization decision and acting on the result.&lt;/p&gt;

&lt;p&gt;In other words, enforcement is the part you add to your application that will actually prevent users from accessing the wrong data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fKweM96c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01cwpo0uk8ayjckjcb07.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fKweM96c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/01cwpo0uk8ayjckjcb07.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the GitClub application, one example of enforcement is in the code that handles fetching and returning a single repository. To request an authorization decision, we first determine what the authorization query would be: is the current user allowed to read the repository they are asking for? In GitClub, we handle authorization through a library. So requesting a decision means invoking the library method &lt;code&gt;is_allowed(user, “read”, repository)&lt;/code&gt;.&lt;br&gt;
We get back a decision. If the decision is “allow", we let the request continue as normal. However, if the decision is “deny”, then we’ll return an error to the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to enforce?
&lt;/h3&gt;

&lt;p&gt;It is helpful to think about where to add enforcement by thinking about layers of a multitiered architecture. We’re not writing a book on architecture patterns here, so if this is unfamiliar, take a look at &lt;a href="https://en.wikipedia.org/wiki/Multitier_architecture"&gt;Wikipedia&lt;/a&gt; to see what we’re talking about.&lt;/p&gt;

&lt;p&gt;The layers of GitClub:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service layer – responsible for handling and routing requests, in GitClub this layer refers to both our network proxy and the router in the application itself.&lt;/li&gt;
&lt;li&gt;Business logic layer – the functionality of the GitClub application.&lt;/li&gt;
&lt;li&gt;Data layer – provides access to data. In GitClub this is the database, and the filesystem where we store repository data.&lt;/li&gt;
&lt;li&gt;Presentation layer – what to show to the user. This is the GitClub web interface that you’d see if you visited the (hypothetical) &lt;a href="https://www.gitclub.dev"&gt;https://www.gitclub.dev&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each layer of our application, there are different levels of authorization to apply. Levels are differentiated by the data they use to make authorization decisions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iJ2_d86z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7nhipa9tcvyambv4th3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iJ2_d86z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7nhipa9tcvyambv4th3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
In the service layer, we can make authorization decisions based on the contents of the request. Given the lack of application context, it is only practical to enforce whether the endpoint is accessible. This is request-level authorization.&lt;/p&gt;

&lt;p&gt;The business logic layer is where we mostly focus. At this layer, we have full context about what the user is doing and the resource they are accessing. This is resource-level authorization.&lt;/p&gt;

&lt;p&gt;When performing authorization in bulk over datasets, it is desirable to push it down to the data layer. The way to accomplish this is by applying authorization to the communication with the data layer. This is query-level authorization.&lt;/p&gt;

&lt;p&gt;We can also perform a kind of authorization in the presentation layer. This is client-side authorization. Unlike the other levels, this cannot be trusted to actually enforce authorization, since it’s possible for users to circumvent the client and access our backend directly.&lt;/p&gt;

&lt;p&gt;In the next section, we’ll go through each layer and level in turn and go into detail about the steps to take in constructing the query, sending it to the decision mechanism, and handling the response.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Enforcement by Layer + Level
&lt;/h2&gt;

&lt;p&gt;Let’s go through each in layer turn and see what enforcement looks like. We’ll leave the presentation layer to the end, it’s a bit different compared to the others.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service layer + Request-level
&lt;/h3&gt;

&lt;p&gt;At the service layer we are dealing with raw HTTP requests. In GitClub, one of the places we handle the HTTP requests is in the request middleware. Almost every web framework will have some form of request middleware that you can use to apply the same logic to every request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s1-3m5D8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l0de2z9daqegjwnxhk1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s1-3m5D8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2l0de2z9daqegjwnxhk1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  What is request-level authorization?
&lt;/h4&gt;

&lt;p&gt;Performing authorization over requests at the service layer is appropriately known as request-level authorization. This is authorization that makes use of information available in the request itself to make authorization decisions.&lt;/p&gt;

&lt;p&gt;In request-level authorization, there is only a single kind of query: “is the actor allowed to make this request to this service”. In the case of HTTP requests, the information used to make an authorization decision is typically the request path and the HTTP method.&lt;/p&gt;

&lt;p&gt;It is also common to have access to the user data. For example, many applications will handle user sessions as part of a middleware step or include additional data about the user as part of the authentication credentials. However, you should not commonly fetch resources from the database as part of the service layer, since this will be duplicating work that will happen in the business layer.&lt;/p&gt;

&lt;p&gt;This restriction prevents us from applying many authorization models. The models we’ve covered in previous chapters all depend on application data to make decisions.&lt;/p&gt;

&lt;p&gt;Let’s take a look at a couple of examples and what the actor, action, and resource is in each case.&lt;/p&gt;

&lt;p&gt;A user who isn’t logged visits the homepage&lt;/p&gt;

&lt;p&gt;When the web user is logged-out, we would consider the actor to be a guest.&lt;br&gt;
The action in this case is making a GET request to /home.&lt;br&gt;
The resource is the GitClub web application.&lt;/p&gt;

&lt;p&gt;The authorization query is: are guests allowed to make GET requests to the /home route on the GitClub web application?&lt;/p&gt;

&lt;p&gt;For the decision, we would implement: “anyone can make GET requests to a route starting with /home on the web application”. We will also need to make sure that guests can visit the login page. Anything else will be denied, and redirect the user to the login page&lt;/p&gt;

&lt;p&gt;We can perform more kinds of request-level authorization by adding additional context to the request. The best way to do this is by adding it to the cryptographic tokens that are often used for managing sessions. This way, additional context can be provided to the user and included in subsequent requests. The cryptographic guarantees that the token provides ensure the user is not manipulating that additional context.&lt;/p&gt;

&lt;p&gt;In GitClub, we might want to allow users to create API tokens with a specific set of permissions. There would be a special page where users can request an API token, and select what permissions they want the token to have. For example, a token would have a list of strings “issues:read”, “repositories:read” indicating what actions the bearer of the token can perform.&lt;/p&gt;

&lt;p&gt;The GitClub CLI tries to use an API token to open a new pull request in the Acme/Anvil repository&lt;/p&gt;

&lt;p&gt;When using the API token to make requests, we identify the bearer of the token as the actor. &lt;br&gt;
The action in this case is making a POST request to /org/acme/repo/anvil/pull_requests.&lt;br&gt;
The resource is the GitClub API service.&lt;/p&gt;

&lt;p&gt;The authorization query is: Is the API token allowed to make POST requests to /org/acme/repo/anvil/pull_requests on the GitClub API service?&lt;/p&gt;

&lt;p&gt;We are unable to conclusively determine whether the request should be allowed. We cannot know whether the user who created the token is allowed to open pull requests in the Acme/Anvil repository.&lt;/p&gt;

&lt;p&gt;However, we can use the information in the request to make an initial decision. Our API tokens are cryptographic tokens and contain what permissions are granted to the bearer of the token. Therefore, we can make a decision based on whether the token has the “repository:write” permission.&lt;/p&gt;

&lt;p&gt;Since this same logic is required for every API endpoint, by using request-level authorization at the service layer we can handle it in just one place. &lt;/p&gt;

&lt;p&gt;However, the authorization it handles is still quite coarse. For example, the application would still need to check if the user who created the token is allowed to open pull requests to Acme/Anvil. This would need to take place at the resource-level in the business layer. The advantage is that the logic for handling API tokens is handled in the service layer, so we do not need to pass this information along to the business layer.&lt;/p&gt;

&lt;h4&gt;
  
  
  Where to enforce
&lt;/h4&gt;

&lt;p&gt;In a monolith application, request middleware is the best place to implement request-level authorization. The best approach is to perform authorization on every request, and rely on an opt-out mechanism to specific routes that do not need authorization.&lt;/p&gt;

&lt;p&gt;In the context of service-oriented architectures, you can also add request-level authorization checks as part of network proxies. These come in a few different flavors, like API gateways, service meshes, and load balancers. Network proxies can enforce request-level authorization by delegating the authorization decision to a central service. As we have seen in the previous examples, this service will typically need to access user data.&lt;/p&gt;

&lt;h4&gt;
  
  
  What to return
&lt;/h4&gt;

&lt;p&gt;For API requests, it is better to return a 403 Forbidden error message along with any error details in the body of the response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Business logic layer + Resource-level
&lt;/h3&gt;

&lt;p&gt;Once the request has been properly routed, we’re into the business logic of the application. This is where the magic happens! This is where the application retrieves data, operates on it, updates other pieces of data, and triggers background jobs.&lt;/p&gt;

&lt;p&gt;In the business logic layer, the code often deals with objects, classes, or types that represent the core domain concepts of the application. And this is where you will typically find the majority of authorization takes place, in the form of resource-level authorization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZGWqkMtI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kp158hhq1gubay8gxmro.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZGWqkMtI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kp158hhq1gubay8gxmro.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  What is resource-level authorization
&lt;/h4&gt;

&lt;p&gt;A “resource” refers to any piece of data that users may attempt to access or interact with in an application. Organizations, repositories, issues, and comments are all examples of resources in GitClub.&lt;/p&gt;

&lt;p&gt;Resource-level authorization uses resources and their associated data directly when making decisions. The examples we’ve used in past Authorization Academy chapters are all resource-level. For example, “is the user allowed to read issue #1313 of the acme/anvil repository?” is a resource-level check.&lt;/p&gt;

&lt;h4&gt;
  
  
  What to enforce
&lt;/h4&gt;

&lt;p&gt;Imagine your friend asks you: "can I let myself into your apartment?". You might find it hard to answer without any additional context! "Well, sure... but what do you want to do?". Maybe they just left their jacket behind and want to go fetch it.  It would be easier to answer your friend if they asked 'can I pick up my jacket from your apartment?'"&lt;br&gt;
We have the same problem with application authorization. Suppose we are handling a request from a user to close issue #312 of the acme/anvil repository. The most specific query we can construct would be: “is the user (actor) allowed to close (action) issue #312 of the acme/anvil repo (resource). This specificity provides the decision mechanism with as much information as possible, which it will use to determine the best answer.&lt;/p&gt;

&lt;p&gt;Let’s consider the alternative: making the authorization query more general. At times, this can be tempting because you can potentially reuse the query across other methods, and you have fewer permissions to worry about. For example, if we change the query above to “is the user (actor) allowed to edit (action) the acme/anvil repository (resource)”, then we can easily make an authorization decision based on what permissions the user has for the repository. And we can use this same query for any change a user requests on the repo!&lt;br&gt;
But if we do that, we’ve thrown away information by making the query more general. What if the user is not a member of the repository, but is actually an external collaborator who opened the original issue? We should be able to use relationship-based authorization to determine that issue owners can close issues, which the original, more specific query supports.&lt;/p&gt;

&lt;p&gt;The problem is that authorization logic has leaked into the application code. We’ve implicitly assumed that users can close an issue if they can edit the repository it belongs to.&lt;/p&gt;

&lt;p&gt;In summary, always make the authorization query as precise as possible. This keeps the authorization logic separated, requires less thinking about what to enforce, and lets the decision logic be more flexible.&lt;/p&gt;

&lt;h4&gt;
  
  
  Where to enforce
&lt;/h4&gt;

&lt;p&gt;The best place to add resource-level authorization is in the application code, as close as possible to where the intended action is performed.&lt;/p&gt;

&lt;p&gt;If we already have the resource in hand, then we can perform the authorization straight away. This is often the case for creating new resources.&lt;/p&gt;

&lt;p&gt;Otherwise, we might need to first fetch the resource, enforce access, and then perform the action. For example, when reading data, the first step will be to fetch the resource from the database, and then check whether the user is allowed to read it. (We’ll cover an alternative approach in the next section).&lt;/p&gt;

&lt;h4&gt;
  
  
  What to return
&lt;/h4&gt;

&lt;p&gt;The default strategy for handling an authorization failure is to return an HTTP 403 Forbidden message, along with any details that might be helpful for the client.&lt;/p&gt;

&lt;p&gt;However, in some cases returning an error message would be revealing information that the user should not otherwise know. For example, suppose a GitClub user visits /org/acme/repo/secret_project – a private repository – then a 403 Forbidden message might reveal to the user that such a repository exists.&lt;/p&gt;

&lt;p&gt;Therefore, it is best practice to return an HTTP 404 NotFound message whenever the user is not even allowed to read the resource, regardless of what action they are attempting.&lt;/p&gt;

&lt;h4&gt;
  
  
  Field-level access
&lt;/h4&gt;

&lt;p&gt;It is often the case that we want to control what fields of a resource a user can access.&lt;/p&gt;

&lt;p&gt;For example, in GitClub users can view their own profile, and see all the data about themselves. Users are also allowed to view other’s profiles, but they can only see a subset of the data.&lt;/p&gt;

&lt;p&gt;This is known as field-level access. It’s an additional level beyond resource-level.&lt;/p&gt;

&lt;p&gt;There are two ways to handle field-level enforcement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Individual: create a new, more specific action to represent the field being accessed&lt;/li&gt;
&lt;li&gt;Generic:  make the field an additional parameter to the authorization decision.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The individual approach requires no additional work on top of resource-level authorization, but is a little less flexible. The second is more powerful, but requires changing the authorization interface. Let’s look at when we would use either one in the context of GitClub.&lt;/p&gt;

&lt;p&gt;GitClub users are allowed to make changes to repositories. They can change the name, add a description, specify tags, and so on. All of this is handled through a single “update repository” method. We use resource-level authorization to check if the user is allowed to update the repository.&lt;/p&gt;

&lt;p&gt;However, now we want to restrict this so that only organization admins are allowed to make a repository private. Our current approach cannot handle this, since we only check whether a user is allowed to update the repository.&lt;/p&gt;

&lt;p&gt;Taking the individual approach to field-level enforcement is fine for a small number of fields, but over time leads to a substantial amount of authorization logic spilling over into the application. Here’s how we would do it:&lt;/p&gt;

&lt;p&gt;First, we would add a new action called “change visibility” on repositories and assign this as a permission to the organization admin role. On the enforcement side, we would have to use the “change visibility” action in our authorization query if the user attempts to modify the “private” field of a repository. This requires us to add some authorization logic into our application, as we must choose what enforcement to apply based on what resource fields are present in the request.&lt;/p&gt;

&lt;p&gt;Over time, we might want to add more control over which fields users can update. For example, only repository maintainers are allowed to update the repository description, but repository contributors are allowed to add tags.&lt;/p&gt;

&lt;p&gt;To make those changes, we would have to leak a lot of our authorization logic into the application.&lt;/p&gt;

&lt;p&gt;The generic approach to field-level enforcement would instead update the query to include what fields are being requested. In the case of an update, we would amend the original query to: is the user allowed to update these fields on the repository? That is, instead of thinking about the action as simply “update”, we instead include the full context of the fields that are being updated. &lt;/p&gt;

&lt;p&gt;By doing this, the decision mechanism is responsible for handling the logic of: if the update request contains a “private” attribute, then the user must have permission to “change_visibility” on the repository. And similarly for all other fields contained in the request.&lt;/p&gt;

&lt;p&gt;The downside of the generic approach is that we need to update our authorization interface to handle the additional parameter -- the fields. Given this, the individual approach is suitable when there are only a few fields to handle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data layer + Query-level
&lt;/h3&gt;

&lt;p&gt;Resource-level authorization has one substantial disadvantage: you need to fetch the resource in order to perform authorization.&lt;/p&gt;

&lt;p&gt;This may not seem like such a big deal. After all, we generally want to get the resource anyway. However, fetching each resource individually  becomes a problem when performing authorization over a large set of resources, as is common when implementing list endpoints. &lt;/p&gt;

&lt;p&gt;In GitClub, we expose an endpoint that lists all of the repositories that a user has access to.&lt;/p&gt;

&lt;p&gt;Doing this with resource-level authorization means fetching every repository in the database and requesting an authorization decision for each one.. Instead, we can push authorization down to the data layer and use query-level authorization. The data layer commonly refers to a database, although it can also mean other services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jBwYRDVd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ilxodyosvg3rqtywq1b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jBwYRDVd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ilxodyosvg3rqtywq1b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  What is query-level authorization
&lt;/h4&gt;

&lt;p&gt;Query-level authorization is an approach to enforcing authorization at the data layer by modifying the data access query (e.g. SQL query) to include authorization parameters.&lt;/p&gt;

&lt;p&gt;This involves an authorization interface that is different from what we have seen so far. The authorization decision is no longer a single yes/no response. Instead the decision must be made for each resource in the dataset, by encoding the decision as a filter on the query.&lt;/p&gt;

&lt;p&gt;As a simple example, we know that a user can read any repository that they’ve created. To reflect this authorization logic, a query to fetch all repositories could contain the condition “where the created_by field is set to the ID of the current user”. With this in place, we are filtering the database so that only the authorized resources are returned.&lt;/p&gt;

&lt;h4&gt;
  
  
  Decisions and enforcement
&lt;/h4&gt;

&lt;p&gt;You should think about the authorization query for query-level authorization as: is the actor allowed to perform action over all the resources in this query?&lt;/p&gt;

&lt;p&gt;For the example above, the query would be: is the user allowed to perform the action “read” over the repositories returned by querying the “repositories” table?&lt;/p&gt;

&lt;p&gt;In our past enforcement examples, the authorization decision would be a simple yes/no answer. But for query-level authorization the decision must include all of the conditions that the enforcement should apply to the query.&lt;/p&gt;

&lt;p&gt;For GitClub, some of the scenarios under which somebody can read a repository are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The repository is public&lt;/li&gt;
&lt;li&gt;The user was added to the repository as a collaborator&lt;/li&gt;
&lt;li&gt;The user has a role in the organization the repository belongs to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these conditions would need to be represented in such a way that the enforcement mechanism is able to apply the suitable query filter. The more flexible the format for these conditions, the more extensible the authorization logic is. However, this requires implementing a decision mechanism that is able to return arbitrary conditions. In Oso, we made this possible by having our policy language Polar able to return a set of constraints as the output of an authorization query.&lt;/p&gt;

&lt;p&gt;You can avoid needing a full policy language by sacrificing some flexibility and specifying a finite number of conditions that can be returned by the decision mechanism. In the previous example, we could return a string for each condition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“repository_is_public” – check the repository is public&lt;/li&gt;
&lt;li&gt;“user_has_repository_role_contributor” – check the user has the “contributor” role for a repository&lt;/li&gt;
&lt;li&gt;“user_has_organization_role_member” – check the user has the “member” role for the organization that a repository belongs to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The role of the enforcement mechanism is to process the conditions returned by the decision mechanism and apply these to the query. You can think of this as the enforcement being applied proactively, as opposed to retroactively enforcing after data is retrieved.&lt;/p&gt;

&lt;p&gt;We expect that the data layer supports some form of filtering, whether accessing a database, search engine, or external service. To enforce authorization at the query-level, you must be able to translate any conditions returned from the decision into those supported filters.&lt;/p&gt;

&lt;p&gt;For example, each of the previous conditions can be implemented as SQL filters:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AaCmEiLa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ltr1i9dyeuujvny24ejv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AaCmEiLa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ltr1i9dyeuujvny24ejv.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Where to enforce
&lt;/h4&gt;

&lt;p&gt;Query-level authorization should be added in the data access layer – the part of the application code responsible for fetching data from databases and other sources.&lt;/p&gt;

&lt;p&gt;The authorization query still needs much of the same context as resource-level authorization, such as the current user and the action being performed. This context needs to become part of the query interface. &lt;/p&gt;

&lt;h4&gt;
  
  
  What to return
&lt;/h4&gt;

&lt;p&gt;Since authorization is applied via filtering the dataset, there is no need to handle the result in any specific way. To the application code, an unauthorized item will simply look as though it does not exist. This is ideal for “read” actions.&lt;/p&gt;

&lt;p&gt;However, in some cases it is better to differentiate “no results”, from “not allowed”. If a GitClub user attempts to list the teams for an organization, there might be no results because the user is not a part of the organization, or no results because all the teams are private. To differentiate these two cases, you can add an additional resource-level check: is the user allowed to “list teams” for this organization. If the result is no, then return an error or redirect the user. If the result is yes, then proceed to making the query-level check.&lt;/p&gt;

&lt;p&gt;Query-level authorization can also be used to replace some resource-level checks. For example, instead of fetching a repository from the database and then checking whether the user has read access, you can do both steps in one go with query-level authorization. This is good when you want to avoid revealing whether a resource exists, much like we described earlier for resource-level checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Presentation layer + Client-side authorization
&lt;/h3&gt;

&lt;p&gt;The last layer to consider for enforcement is the presentation layer. The presentation layer refers to any user interface (UI), whether a server-side rendered web page, single page application, command line application or website. In all of these cases, the enforcement code is running on the untrusted client. Since this can easily be bypassed, we can only use client-side authorization as a way to provide a better user experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is client-side authorization?
&lt;/h4&gt;

&lt;p&gt;Client-side authorization refers to using authorization decisions in a user interface in order to inform what a user can expect to be able to do. This makes for a better user experience — nobody wants to click on a button only to be presented with an error message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YpFS-wFW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s0xddpbe02ey85ijq46b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YpFS-wFW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s0xddpbe02ey85ijq46b.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To avoid this, we use client-side authorization to preempt whether a request will be allowed or not. If the request will be denied, then the particular user interface component can either be deactivated or hidden from the user entirely.&lt;/p&gt;

&lt;p&gt;Even better, we could display the reason for an authorization decision to the user, so they know exactly why they cannot do the action in the first place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_b00DSgF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5d1w7ctfmec2nfs5hr5o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_b00DSgF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5d1w7ctfmec2nfs5hr5o.png" alt="GitHub repository settings page explaining why an organization member cannot delete or transfer a repository."&gt;&lt;/a&gt;&lt;br&gt;
GitHub repository settings page explaining why an organization member cannot delete or transfer a repository.&lt;/p&gt;

&lt;h4&gt;
  
  
  What to enforce
&lt;/h4&gt;

&lt;p&gt;One of the main challenges of client-side authorization is how to keep it synchronized with the authorization implemented in the backend.&lt;/p&gt;

&lt;p&gt;Usually you want to hide or show a UI component based on what actions the current user is allowed to take on a resource. A good pattern is to ask the backend server for what those actions are. This avoids duplicating the authorization logic that the server already must implement. And the client is able to use those actions at its discretion.&lt;/p&gt;

&lt;p&gt;For example, when rendering the “repositories settings” page, we can compute all the set of all permissions the current user has for the repository. This might be “read”, “change_visibility”, and “update”. The web page only needs to implement simple logic: hide the delete button if the “delete” permission is absent in the list of user permissions.&lt;/p&gt;

&lt;p&gt;However, we have still introduced a dependency between the client and server: the two must stay synchronized on what actions are required for each endpoint on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Summary: when to use each level
&lt;/h2&gt;

&lt;p&gt;When we covered where to perform authorization in Chapter II, we concluded that it should happen in the business logic and data access layers. In these two places we had the most context available to handle common authorization scenarios, like “can this user read this repository?”&lt;/p&gt;

&lt;p&gt;We’ve now covered in more detail four different layers throughout the application architecture that we can enforce authorization, and what level of authorization we can add. The summary is that each authorization level has its place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request-level should be used to extract out common enforcement steps that are the same across all requests. It can also be used for defense-in-depth, as an additional layer on top of resource-level authorization.&lt;/li&gt;
&lt;li&gt;Resource-level is a safe choice for most scenarios. At this level, all the relevant context is available for authorization decisions.&lt;/li&gt;
&lt;li&gt;Query-level is a powerful approach and should be used when you need to apply resource-level authorization over an entire dataset.&lt;/li&gt;
&lt;li&gt;Client-side is a purely additive layer on top of any enforcement performed on the backend. It should be used wherever possible to help signal to users what actions can/cannot be performed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, there are a lot of places where authorization might be happening, and it can be hard to keep track! You should look to ensure that at least one level of authorization is applied across a request path.&lt;/p&gt;

&lt;p&gt;For more guidance on authorization, see other chapters from &lt;a href="https://www.osohq.com/developers/authorization-academy"&gt;Authorization Academy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As before, we encourage you to join the community of developers in the &lt;a href="https://join-slack.osohq.com/"&gt;Oso Slack&lt;/a&gt;! We'd love to talk about what you're working on and answer any questions you may have. If you want to kickstart the process of building authorization into your application, you can use the Oso library and learn more about it in the &lt;a href="https://docs.osohq.com/"&gt;Oso documentation&lt;/a&gt;.‍&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>authorization</category>
      <category>permissions</category>
    </item>
    <item>
      <title>Implementing role-based access control (RBAC) in Flask</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Mon, 10 May 2021 15:38:58 +0000</pubDate>
      <link>https://forem.com/ssglaser/implementing-role-based-access-control-rbac-in-flask-525b</link>
      <guid>https://forem.com/ssglaser/implementing-role-based-access-control-rbac-in-flask-525b</guid>
      <description>&lt;p&gt;Many frameworks and libraries provide plug-ins for common authorization patterns like roles, but either don't provide enough of a model to be helpful or are so rigid that you need to migrate away from them down the line.&lt;/p&gt;

&lt;p&gt;We just released a library that provides a configuration-based approach to adding role-based access control (RBAC) to your application. The new Oso Roles library, with support for Python + Flask, speeds up the time it takes to build fine-grained permissions using roles and related patterns. The library includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Role configuration&lt;/li&gt;
&lt;li&gt;Data management&lt;/li&gt;
&lt;li&gt;Enforcement&lt;/li&gt;
&lt;li&gt;End-user configuration&lt;/li&gt;
&lt;li&gt;Last-mile customizations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The library is in early access. Here are relevant links:&lt;/p&gt;

&lt;p&gt;Documentation showing how to use the library to add roles to a Flask app with GitClub, our best practice example app: &lt;a href="http://docs.osohq.com/python/guides/new-roles.html"&gt;http://docs.osohq.com/python/guides/new-roles.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitClub source code: &lt;a href="https://github.com/osohq/gitclub-sqlalchemy-flask-react"&gt;https://github.com/osohq/gitclub-sqlalchemy-flask-react&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flask</category>
      <category>python</category>
      <category>programming</category>
      <category>rbac</category>
    </item>
    <item>
      <title>The basics of role-based access control (RBAC) in SQLAlchemy</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Mon, 03 May 2021 18:01:20 +0000</pubDate>
      <link>https://forem.com/ssglaser/the-basics-of-role-based-access-control-rbac-in-sqlalchemy-1h1f</link>
      <guid>https://forem.com/ssglaser/the-basics-of-role-based-access-control-rbac-in-sqlalchemy-1h1f</guid>
      <description>&lt;p&gt;Almost every application will need to control who can do what - and a good way to solve for this is "roles"! Often this is referred to as role-based access control (RBAC). An ‘admin’ is a role, for instance, and so is a ‘moderator’. Roles map very nicely to how we talk about our systems.&lt;/p&gt;

&lt;p&gt;To celebrate a new release of &lt;a href="http://osohq.com"&gt;Oso&lt;/a&gt;, our open-source authorization library, this blog post demonstrates a few ways of modeling role-based access control in Python and SQLAlchemy. It has complex examples to provide you with the building blocks for adding RBAC to your app and are written in a multi-tenant production system. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.osohq.com/post/sqlalchemy-role-rbac-basics"&gt;Read the blog post&lt;/a&gt; and join&lt;a href="https://docs.osohq.com/python/new-roles/install.html"&gt;here and checkout our documentation on the new library&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;If this is an area you’re exploring, we encourage you to join the community of developers in the &lt;a href="http://join-slack.osohq.com/"&gt;Oso Slack&lt;/a&gt;! Our core engineering team is also in Slack and is happy to engage and answer your questions.&lt;/p&gt;

</description>
      <category>authorization</category>
      <category>python</category>
      <category>sqlalchemy</category>
      <category>rbac</category>
    </item>
    <item>
      <title>Authorization Academy: Technical guides for building application authorization
</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Thu, 22 Apr 2021 01:43:33 +0000</pubDate>
      <link>https://forem.com/ssglaser/authorization-academy-technical-guides-for-building-application-authorization-3lhp</link>
      <guid>https://forem.com/ssglaser/authorization-academy-technical-guides-for-building-application-authorization-3lhp</guid>
      <description>&lt;p&gt;I'm on the founding team at &lt;a href="https://www.osohq.com/"&gt;Oso&lt;/a&gt;, an open source library for authorization. Over time, we've gotten a lot of questions from developers on authorization basics – like how to model roles, where to add authorization checks, or how to integrate permissions in the UI.&lt;/p&gt;

&lt;p&gt;It turns out that there's not much information available on these topics that's technical, concrete and user-friendly. So, we started writing a series of guides on these topics to capture everything we've learnt, heard, and experienced ourselves.&lt;/p&gt;

&lt;p&gt;The series is called &lt;a href="https://www.osohq.com/developers/authorization-academy"&gt;Authorization Academy&lt;/a&gt;. The first few chapters cover architecture and modeling roles. In the coming chapters we'll cover relationship-based access control, enforcement, and integrating permissions data into UIs. &lt;/p&gt;

&lt;p&gt;We have a lot of topics we'd like to write about, and they take a fair bit of time, but let us know if there's anything in particular you'd like to read about!&lt;/p&gt;

&lt;p&gt;The guides cover authorization generically and are not specific to Oso, so they should be useful for anyone who is building authorization into their app or otherwise wants to learn about the area. Of course, if you'd like to learn more about Oso you can visit our &lt;a href="https://www.osohq.com"&gt;site&lt;/a&gt; or come talk with us in &lt;a href="https://join-slack.osohq.com"&gt;Slack&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Looking forward to your feedback! And if you find the chapters useful sign up to get notified when the next ones are released.&lt;/p&gt;

</description>
      <category>authorization</category>
      <category>webdev</category>
      <category>security</category>
      <category>accesscontrol</category>
    </item>
    <item>
      <title>Authorization Academy Chapter I: Intro on how to build authorization into your app</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Tue, 23 Mar 2021 18:42:29 +0000</pubDate>
      <link>https://forem.com/ssglaser/authorization-academy-a-technical-guide-for-building-application-authorization-ejg</link>
      <guid>https://forem.com/ssglaser/authorization-academy-a-technical-guide-for-building-application-authorization-ejg</guid>
      <description>&lt;p&gt;Authorization is a critical element of every application, but the problem is: there’s limited concrete material available for developers on how to build authorization into your app. To help developers build these systems and features, we built &lt;a href="https://www.osohq.com/developers/authorization-academy"&gt;Authorization Academy.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chapter 1: Introduction&lt;/strong&gt;&lt;br&gt;
Authorization is the mechanism for controlling who can do what in an application, and for making sure users have access to the right data. It’s a critical element of every application, but it's nearly invisible to users. It's also usually unrelated to the core features that you're working on. If you’re like most development teams, you want to spend only as much time as you need to spend on authorization – and not a moment more.&lt;/p&gt;

&lt;p&gt;The problem is: there’s limited concrete material available for developers on how to build authorization into your app. To help developers build these systems and features, we built Authorization Academy.&lt;/p&gt;

&lt;p&gt;Authorization Academy is a series of technical guides that explains how to build authorization into an app, including architecture, modeling patterns, enforcement, testing, integration at the UI level and more. After completing this course, you will have a mental model for how authorization works and the tools to build it into an application yourself.&lt;/p&gt;

&lt;p&gt;To make the course as concrete as possible, we use an example application throughout the course, called GitClub. GitClub is a website for source code hosting, collaboration, and version control. This might sound familiar! Our inspiration for GitClub comes from real-world applications – GitHub and GitLab – which are good case studies for common authorization scenarios.&lt;/p&gt;

&lt;p&gt;This course focuses on authorization in business-to-business (B2B) software-as-a-service (SaaS) applications, though we’ll also cover other patterns and models along the way. Developers of all temperatures will find the course useful. For beginner developers, the course will establish a strong base of authorization fundamentals. For more seasoned veterans, the course will offer a cleaner approach to problems they have likely encountered in the past.&lt;/p&gt;

&lt;p&gt;We’re authorization professionals. We built this course based on our experience writing authorization systems ourselves, as well as just dozens of meetings with developers working on authorization at companies ranging from startups to the Fortune 100.&lt;/p&gt;

&lt;p&gt;This course is broken up into chapters, where we’ll be covering the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture&lt;/li&gt;
&lt;li&gt;Modelling Patterns&lt;/li&gt;
&lt;li&gt;Enforcement&lt;/li&gt;
&lt;li&gt;User Interfaces&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Security&lt;/li&gt;
&lt;li&gt;Microservices&lt;/li&gt;
&lt;li&gt;Other advanced concepts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Authentication vs. Authorization&lt;/strong&gt;&lt;br&gt;
Many folks often use the term “auth” to refer to both authentication and authorization, which are related and somewhat overlapping mechanisms in application security. But they aren’t the same thing.&lt;/p&gt;

&lt;p&gt;Authentication is the mechanism for verifying who a user is. It’s the front door to the application. For example, a username and password together make up an identity (username) and a verification method (do you know the password). Other forms of authentication include OAuth and OpenID Connect (OIDC), which is often used for adding features like “Login with Google” or “Login with Facebook”; and SAML, which is a standard that enterprises use for giving employees a single login across multiple apps.&lt;/p&gt;

&lt;p&gt;Authorization is the mechanism of controlling what the user can do. If authentication is the front door, authorization controls what doors you can open once you’re inside. &lt;/p&gt;

&lt;p&gt;Authorization often builds on authentication, and the two overlap most closely when information about who the user is becomes an input to determining what she can do. For instance, once a user is authenticated, we might use her username to look up her permissions; or we might be able to infer her permissions based on some other attribute that we can look up. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.osohq.com/academy/authorization-academy-chapter-1-introduction"&gt;This course&lt;/a&gt; focuses on authorization, and will only touch on authentication when relevant. We assume you have an authentication system in place, or can set one up by following guidance readily available elsewhere.&lt;/p&gt;

&lt;p&gt;For more on this, see our &lt;a href="https://www.osohq.com/academy/chapter-2-architecture"&gt;next chapter on Architecture.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>authorization</category>
      <category>permissions</category>
      <category>authentication</category>
    </item>
    <item>
      <title>A Principled Approach to Authorization Using Python &amp; SQLAlchemy</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Mon, 01 Mar 2021 18:10:51 +0000</pubDate>
      <link>https://forem.com/ssglaser/a-principled-approach-to-authorization-using-python-sqlalchemy-c5f</link>
      <guid>https://forem.com/ssglaser/a-principled-approach-to-authorization-using-python-sqlalchemy-c5f</guid>
      <description>&lt;p&gt;Authorization is an unstructured problem. Writing code to decide who can do what in your app can cover a broad set of cases. The most structure that typically gets applied to this problem area is a set of if statements and roles, but in reality, there are a lot more patterns and structure that we can apply. &lt;/p&gt;

&lt;p&gt;Oso is an open source system for building authorization into applications. It's a bit like SQLAlchemy in that it provides a structured approached to authorization, much like SQLAlchemy does for data modeling and access. Oso cofounder/CTO, Sam Scott, gave a talk providing a mental model for authorization and showing how to apply it using Oso, Python and SQLAlchemy - watch the recording below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.osohq.com/post/authorization-using-oso-python-sqlalchemy"&gt;https://www.osohq.com/post/authorization-using-oso-python-sqlalchemy&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>sqlalchemy</category>
      <category>authorization</category>
    </item>
    <item>
      <title>Implementing Role-Based Access Control (RBAC) in SQLAlchemy with oso</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Thu, 07 Jan 2021 17:57:18 +0000</pubDate>
      <link>https://forem.com/ssglaser/implementing-role-based-access-control-rbac-in-sqlalchemy-with-oso-2g76</link>
      <guid>https://forem.com/ssglaser/implementing-role-based-access-control-rbac-in-sqlalchemy-with-oso-2g76</guid>
      <description>&lt;p&gt;&lt;a href="https://www.osohq.com/post/introducing-builtin-roles"&gt;https://www.osohq.com/post/introducing-builtin-roles&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>sqlalchemy</category>
      <category>authorization</category>
      <category>rbac</category>
    </item>
    <item>
      <title>Adding Authorization to a Node.js App – Beyond Role-Based Access Control</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Fri, 23 Oct 2020 16:54:27 +0000</pubDate>
      <link>https://forem.com/ssglaser/adding-authorization-to-a-node-js-app-beyond-role-based-access-control-15ge</link>
      <guid>https://forem.com/ssglaser/adding-authorization-to-a-node-js-app-beyond-role-based-access-control-15ge</guid>
      <description>&lt;p&gt;We wrote a blog post on Adding Authorization to a Node.js App and Role-Based Access Control. Learn why RBAC isn't always enough &amp;amp; how we used oso (&lt;a href="https://www.osohq.com/"&gt;https://www.osohq.com/&lt;/a&gt;) to represent common access control patterns in a NestJS app. &lt;/p&gt;

&lt;p&gt;The post covers how to use the oso Node.js library, how to represent common access control patterns, what to do when RBAC isn't enough, and what a declarative approach to policy code looks like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.osohq.com/post/adding-authorization-nodejs-app-beyond-role-based-access-control"&gt;https://www.osohq.com/post/adding-authorization-nodejs-app-beyond-role-based-access-control&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Generating Django QuerySet filters from oso policies</title>
      <dc:creator>ssglaser</dc:creator>
      <pubDate>Fri, 16 Oct 2020 20:05:17 +0000</pubDate>
      <link>https://forem.com/ssglaser/generating-django-queryset-filters-from-oso-policies-246</link>
      <guid>https://forem.com/ssglaser/generating-django-queryset-filters-from-oso-policies-246</guid>
      <description>&lt;p&gt;We're building an open source policy engine for adding access control (permissions, roles, etc.) to apps, called oso. oso policies are declarative, and enable users to cleanly separate authorization logic from the rest of their application code.&lt;/p&gt;

&lt;p&gt;In our latest release of django-oso, we added functionality to enforce authorization policies directly on Django QuerySets. The declarative policy is translated into filters that can be understood by the Django ORM, in a way that is fully abstracted from the library user. In the future, we'll be adding support for SQLAlchemy and other Python ORMs.&lt;/p&gt;

&lt;p&gt;We wrote about it in this blog post: &lt;a href="https://www.osohq.com/post/django-list-view"&gt;https://www.osohq.com/post/django-list-view&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Cleanly separating an authorization policy from other application code can be challenging, especially when authorizing a collection of objects, often necessary in list views. This feature makes it possible to enforce authorization as a filter when querying the application data store while still taking full advantage of the declarative policy provided by oso.&lt;/p&gt;

&lt;p&gt;This functionality is in preview in the 0.3.0 release of django-oso: &lt;a href="https://pypi.org/project/django-oso/"&gt;https://pypi.org/project/django-oso/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install via pip: pip install django-oso&lt;/p&gt;

&lt;p&gt;Let us know what you think in our Slack channel or on this thread! &lt;a href="https://app.slack.com/client/T017ZS940LR"&gt;https://app.slack.com/client/T017ZS940LR&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>security</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
