Documentation Blog Community Forum Media
|
|
Sign In
    • Ash
      • Get Started
      • Philosophy
      • Why Ash
      • Extending Resources
    • AshPostgres
      • Get Started With Postgres
    • AshSqlite
      • Get Started With Sqlite
    • AshPhoenix
      • Getting Started With Ash And Phoenix
    • AshGraphql
      • Getting Started With Graphql
    • AshJsonApi
      • Getting Started With Json Api
    • AshAuthentication
      • Auth0 Quickstart
      • Getting Started With Authentication
      • Github Quickstart
      • Magic Links Quickstart
    • AshAuthenticationPhoenix
      • Getting Started With Ash Authentication Phoenix
      • Use Ash Authentication With Liveview
    • AshStateMachine
      • Get Started With State Machines
    • AshCSV
      • Get Started With Csv
    • Reactor
      • Getting Started With Reactor
    • Spark
      • Get Started With Spark
    • Ash
      • Actions
      • Aggregates
      • Atomics
      • Attributes
      • Bulk Actions
      • Calculations
      • Code Interface
      • Constraints
      • Development Utilities
      • Embedded Resources
      • Expressions
      • Flows
      • Glossary
      • Identities
      • Managing Relationships
      • Manual Actions
      • Monitoring
      • Multitenancy
      • Notifiers
      • Pagination
      • Phoenix
      • Policies
      • Pub Sub
      • Relationships
      • Security
      • Store Context In Process
      • Testing
      • Timeouts
      • Validations
    • AshPostgres
      • Migrations And Tasks
      • Polymorphic Resources
      • Postgres Expressions
      • References
      • Schema Based Multitenancy
    • AshSqlite
      • Migrations And Tasks
      • Polymorphic Resources
      • References
      • Sqlite Expressions
    • AshPhoenix
      • Working With Phoenix
    • AshGraphql
      • Graphql Generation
      • Modifying The Resolution
      • Relay
    • AshJsonApi
      • Open Api
      • Relationships
    • AshAuthentication
      • Custom Strategy
      • Policies On Authentication Resources
      • Upgrading
    • Ash
      • Contribute
      • Define Idiomatic Actions
      • Defining Manual Relationships
      • Handle Errors
      • Structure Your Project
      • Upgrade
      • Use Without Data Layers
      • Validate Changes
    • AshPostgres
      • Join Manual Relationships
      • Test With Postgres
      • Using Fragments
    • AshSqlite
      • Join Manual Relationships
      • Test With Sqlite
      • Using Fragments
    • AshGraphql
      • Authorize With Graphql
      • Handle Errors
      • Use Enums With Graphql
      • Use Json With Graphql
      • Use Subscriptions With Graphql
      • Use Unions With Graphql
    • Spark
      • Writing Extensions
    • AshGraphql
      • Monitoring
    • AshArchival
      • Archival
      • Unarchiving
    • Ash
      • Get Started
      • Philosophy
      • Why Ash
      • Extending Resources
    • AshPostgres
      • Get Started With Postgres
    • AshSqlite
      • Get Started With Sqlite
    • AshPhoenix
      • Getting Started With Ash And Phoenix
    • AshGraphql
      • Getting Started With Graphql
    • AshJsonApi
      • Getting Started With Json Api
    • AshAuthentication
      • Auth0 Quickstart
      • Getting Started With Authentication
      • Github Quickstart
      • Magic Links Quickstart
    • AshAuthenticationPhoenix
      • Getting Started With Ash Authentication Phoenix
      • Use Ash Authentication With Liveview
    • AshStateMachine
      • Get Started With State Machines
    • AshCSV
      • Get Started With Csv
    • Reactor
      • Getting Started With Reactor
    • Spark
      • Get Started With Spark
    • Ash
      • Actions
      • Aggregates
      • Atomics
      • Attributes
      • Bulk Actions
      • Calculations
      • Code Interface
      • Constraints
      • Development Utilities
      • Embedded Resources
      • Expressions
      • Flows
      • Glossary
      • Identities
      • Managing Relationships
      • Manual Actions
      • Monitoring
      • Multitenancy
      • Notifiers
      • Pagination
      • Phoenix
      • Policies
      • Pub Sub
      • Relationships
      • Security
      • Store Context In Process
      • Testing
      • Timeouts
      • Validations
    • AshPostgres
      • Migrations And Tasks
      • Polymorphic Resources
      • Postgres Expressions
      • References
      • Schema Based Multitenancy
    • AshSqlite
      • Migrations And Tasks
      • Polymorphic Resources
      • References
      • Sqlite Expressions
    • AshPhoenix
      • Working With Phoenix
    • AshGraphql
      • Graphql Generation
      • Modifying The Resolution
      • Relay
    • AshJsonApi
      • Open Api
      • Relationships
    • AshAuthentication
      • Custom Strategy
      • Policies On Authentication Resources
      • Upgrading
    • Ash
      • Contribute
      • Define Idiomatic Actions
      • Defining Manual Relationships
      • Handle Errors
      • Structure Your Project
      • Upgrade
      • Use Without Data Layers
      • Validate Changes
    • AshPostgres
      • Join Manual Relationships
      • Test With Postgres
      • Using Fragments
    • AshSqlite
      • Join Manual Relationships
      • Test With Sqlite
      • Using Fragments
    • AshGraphql
      • Authorize With Graphql
      • Handle Errors
      • Use Enums With Graphql
      • Use Json With Graphql
      • Use Subscriptions With Graphql
      • Use Unions With Graphql
    • Spark
      • Writing Extensions
    • AshGraphql
      • Monitoring
    • AshArchival
      • Archival
      • Unarchiving
View this guide on GitHub View this guide on Hex

Security

Table of Contents

  1. Important Note!
  2. Sensitive Attributes
  3. Authorization
    1. Actors
    2. Context
    3. Authorization Configuration

Important Note!

A great thing to do early on is to be explicit about your security configuration. To that end, once you’ve read this guide, we highly recommend that you place the configuration found at the bottom of your guide into your api modules, even if you are simply setting them to their default values. Especially the authorize option.

Sensitive Attributes

Using sensitive? true will cause the argument to be ** Redacted ** from the resource when logging or inspecting. In filter statements, any value used in the same expression as a sensitive attribute will also be redacted. For example, you might see: email == "** Redacted **" in a filter statement if email is marked as sensitive.

Authorization

Authorization in Ash is done via authorizers. Generally, you won’t need to create your own authorizer, as the builtin policy authorizer Ash.Policy.Authorizer should work well for any use case. Authorization is performed with a given actor and a query or changeset.

Actors

An actor is the “entity performing the action”. This is generally a user, but could potentially be an organization, a group, whatever makes sense for your use case. By default, when using Ash in code, authorization does not happen.

# Does not perform authorization
Api.read!(User)

However, if you either 1. provide an actor or 2. use the authorize?: true option, then authorization will happen.

# Authorize with a `nil` actor (which is valid, i.e if no one is logged in and they are trying to list users)
Api.read!(User, actor: nil)

# Authorize with a `nil` actor
Api.read!(User, authorize?: true)

# Authorize with an actor
Api.read!(User, actor: current_user)

# Authorize with an actor, but being explicit
Api.read!(User, actor: current_user, authorize?: true)

# Skip authorization, but set an actor. The actor can be used in other things than authorization
# so this may make sense depending on what you are doing.
Api.read!(User, actor: current_user, authorize?: false)

Where to set the actor

When setting an actor, if you are building a query or changeset, you should do so at the time that you call the various for_* functions. This makes the actor available in the context of any change that is run. For example:

# DO THIS
Resource
|> Ash.Query.for_read(:read, input, actor: current_user)
|> Api.read()

# DON'T DO THIS
Resource
|> Ash.Query.for_read(:read, input, actor: current_user)
|> Api.read(actor: current_user)

The second option “works” in most cases, but not all, because some change s might need to know the actor

Context

Ash can store the actor, query context, or tenant in the process dictionary. This can help simplify things like live views, controllers, or channels where all actions performed share these pieces of context.

This can be useful, but the general recommendation is to be explicit by passing options.

# in socket connect, liveview mount, or a plug
Ash.set_actor(current_user)

# This will now use the actor set in the context.
Api.read!(User)

Authorization Configuration

The default behavior is illustrated above, but it can be customized with the options in the d:Ash.Api.authorization section of the Api module you are calling.

d:Ash.Api.Dsl.authorization|require_actor?

Requires that an actor is set for all requests.

Important: nil is still a valid actor, so this won’t prevent providing actor: nil .

d:Ash.Api.Dsl.authorization|authorize

Important!

The default value for this is relatively loose, and we intend to change it in the 3.0 release (which is not scheduled for anytime soon). Right now, it is :when_requested , but a better default would be :by_default , and is what you should choose when starting out.

When to run authorization for a given request.

  • :always forces authorize?: true on all requests to the Api.
  • :by_default sets authorize?: true if the authorize? option was not set (so it can be set to false ).
  • :when_requested sets authorize?: true whenever an actor is set or authorize?: true is explicitly passed. This is the default behavior.
Source Report an issue