Skip to content

Latest commit

 

History

History
154 lines (127 loc) · 4.74 KB

5-restrict-command-execution-with-role-based-permissions.mdx

File metadata and controls

154 lines (127 loc) · 4.74 KB
sidebar_position sidebar_label description keywords seoFrontMatterUpdated
5
Restrict command execution with role-based permissions
Learn how to restrict command execution with role-based permissions.
hasura
hasura ddn
authorization
role-based execution
false

Restrict Command Execution with Role-based Permissions

Introduction

Often, you'll want to limit a user's ability to execute certain commands — which power mutations in your GraphQL API — based on some related data. In the example below, we'll build on the tutorial found in our PostgreSQL getting-started section and restrict users to only being able to update posts of which they're the author.

:::info Prerequisites

Before continuing, ensure you have:

  • A local Hasura DDN project.
  • Either JWT or Webhook mode enabled in your AuthConfig.

:::

Tutorial

Step 1. Add an author role to your CommandPermissions object

---
kind: CommandPermissions
version: v1
definition:
  commandName: UpdatePostsById
  permissions:
    - role: admin
      allowExecution: true
    - role: author
      allowExecution: true
      argumentPresets:
        - argument: preCheck
          value:
            booleanExpression:
              relationship:
                # Here, `user` refers to the pre-generated relationship's name
                name: user
                predicate:
                  fieldComparison:
                    field: id
                    operator: _eq
                    value:
                      sessionVariable: x-hasura-user-id

This role grants the author role permission to execute the UpdatePostsById command, but only if the user who authored the post has an id that matches the x-hasura-user-id session variable in the request header. This ensures users can only update posts they have authored.

Step 2. Add TypePermissions to your response type

The new author role will need access to return types for the UpdatePostsByIdResponse type.

kind: TypePermissions
version: v1
definition:
  typeName: UpdatePostsByIdResponse
  permissions:
    - role: admin
      output:
        allowedFields:
          - affectedRows
          - returning
    - role: author
      output:
        allowedFields:
          - affectedRows

In the configuration above, we're only allowing a user with the role of author to access the number of affected rows. Alternatively, you could include returning in the output array and then set ModelPermissions and TypePermissions for the author role on the Posts type to allow for any or specific fields to be returned.

Step 3. Create a new build and test {#build-and-test}

kind: AuthConfig
version: v3
definition:
  mode:
    noAuth:
      role: author
      sessionVariables: { "x-hasura-user-id": 1 }

This will set your x-hasura-role session variable as author and the x-hasura-user-id as 1, enabling you to impersonate Alice.

ddn supergraph build local && ddn run docker-start
mutation UPDATE_POST_TITLE {
  updatePostsById(keyId: "1", updateColumns: { title: { set: "This is not Alice's first post" } }) {
    affectedRows
  }
}
{
  "data": {
    "updatePostsById": {
      "affectedRows": 1
    }
  }
}
mutation UPDATE_POST_TITLE {
  updatePostsById(keyId: "4", updateColumns: { title: { set: "Malicious Actions in the API" } }) {
    affectedRows
  }
}
{
  "data": {
    "updatePostsById": {
      "affectedRows": 0
    }
  }
}

Wrapping up

In this tutorial, we've demonstrated the minimum sets of permissions necessary to enforce role-based execution of commands. While the example illustrates limiting users to updating their own posts, the principles can be applied to any scenario by which you want to limit command execution — and mutations — based on relationships.

Learn more about permissions and auth