Packages
ash_graphql
1.3.2
1.10.0
1.9.4
1.9.3
1.9.2
1.9.1
1.9.0
1.8.5
1.8.4
1.8.3
1.8.2
1.8.1
1.8.0
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.0
1.5.1
1.5.0
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.1
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.5
1.0.0-rc.4
retired
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.28.1
0.28.0
0.27.1
0.27.0
0.26.9
0.26.8
0.26.7
0.26.6
0.26.5
0.26.4
0.26.3
0.26.2
0.26.0
0.25.13
0.25.12
0.25.10
0.25.9
0.25.8
0.25.7
0.25.6
0.25.5
0.25.4
0.25.3
0.25.2
0.25.1
0.25.0
0.24.1
0.24.0
0.23.3
0.23.2
0.23.1
0.23.0
0.22.13
0.22.12
0.22.11
0.22.10
0.22.9
0.22.8
0.22.7
0.22.6
0.22.4
0.22.3
0.22.2
0.22.1
0.22.0
0.21.0
retired
0.20.5
0.20.4
0.20.3
0.20.2
0.20.1
0.20.0-rc.3
0.20.0-rc.2
0.20.0-rc.1
0.20.0-rc.0
0.19.0
0.18.0-rc0
0.17.5
0.17.5-rc0
0.17.4
0.17.2
0.17.1
0.17.0
0.16.28
0.16.27
0.16.26
0.16.25
0.16.24
0.16.23
0.16.22
0.16.21
0.16.20
0.16.18-rc5
0.16.18-rc4
0.16.18-rc3
0.16.18-rc2
0.16.18-rc1
0.16.18-rc0
0.16.17
0.16.16
0.16.15
0.16.14
0.16.13
0.16.12
0.16.11
0.16.10
0.16.9
0.16.8
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.1
0.14.0
0.13.1
0.13.0
0.12.5
0.12.4
0.12.3
0.12.1
0.12.0
0.10.0
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.3
0.1.2
The extension for building GraphQL APIs with Ash
Current section
Files
Jump to
Current section
Files
documentation/topics/authorize-with-graphql.md
# Authorize with GraphQL
AshGraphql uses three special keys in the `absinthe` context:
- `:actor` - the current actor, to be used for authorization/preparations/changes
- `:tenant` - a tenant when using [multitenancy](https://hexdocs.pm/ash/multitenancy.html).
- `:ash_context` - a map of arbitrary context to be passed into the changeset/query. Accessible via `changeset.context` and `query.context`
By default, `authorize?` in the domain is set to true. To disable authorization for a given domain in graphql, use:
```elixir
graphql do
authorize? false
end
```
If you are doing authorization, you'll need to provide an `actor`.
To set the `actor` for authorization, you'll need to add an `actor` key to the
absinthe context. Typically, you would have a plug that fetches the current user and uses `Ash.PlugHelpers.set_actor/2` to set the actor in the `conn` (likewise with `Ash.PlugHelpers.set_tenant/2`).
Just add `AshGraphql.Plug` somewhere _after_ that in the pipeline and the your
GraphQL APIs will have the correct authorization.
```elixir
defmodule MyAppWeb.Router do
pipeline :api do
# ...
plug :get_actor_from_token
plug AshGraphql.Plug
end
scope "/" do
forward "/gql", Absinthe.Plug, schema: YourSchema
forward "/playground",
Absinthe.Plug.GraphiQL,
schema: YourSchema,
interface: :playground
end
def get_actor_from_token(conn, _opts) do
with ["" <> token] <- get_req_header(conn, "authorization"),
{:ok, user, _claims} <- MyApp.Guardian.resource_from_token(token) do
conn
|> set_actor(user)
else
_ -> conn
end
end
end
```
## Policy Breakdowns
By default, unauthorized requests simply return `forbidden` in the message. If you prefer to show policy breakdowns in your GraphQL errors, you can set the config option:
```elixir
config :ash_graphql, :policies, show_policy_breakdowns?: true
```
```json
{
"data": {
"attendanceRecords": null
},
"errors": [
{
"code": "forbidden",
"fields": [],
"locations": [
{
"column": 3,
"line": 2
}
],
"message": "MyApp.Authentication.User.read\n\n\n\n\nPolicy Breakdown\n Policy | ⛔:\n forbid unless: actor is active | ✓ | ⬇ \n authorize if: actor is Executive | ✘ | ⬇",
"path": ["attendanceRecords"],
"short_message": "forbidden",
"vars": {}
}
]
}
```
Be careful, as this can be an attack vector in some systems (i.e "here is exactly what you need to make true to do what you want to do").
## Field Policies
Field policies in AshGraphql work by producing a `null` value for any forbidden field, as well as an error in the errors list.
> ### nullability {: .warning}
>
> Any fields with field policies on them should be nullable. If they are not nullable, the _parent_ object will also be `null` (and considered in an error state), because `null` is not a valid type for that field.
To make fields as nullable even if it is not nullable by its definition, use the `nullable_fields` option.
```elixir
graphql do
type :post
nullable_fields [:foo, :bar, :baz]
end
```