ash icon indicating copy to clipboard operation
ash copied to clipboard

Allow marking actions as internal to prevent exposing them via APIs

Open smt116 opened this issue 1 year ago • 7 comments

In complex systems, there are often actions that suppose to only be used internally. For example, a way of user lookup by some custom key or creating a record. Currently, they can be added to policies with authorize_if always() or used only with authorized?: false.

Using a policy introduces a risk of exposing them in the API at some point. On the other hand, authorized?: false breaks the authorization circuit by not passing the current action context down the line (e.g., to nested actions).

It would be great if Ash could allow for something like internal? true on action definition. That property would be used when building APIs' actions, by raising a compilation error.

smt116 avatar Jul 01 '24 18:07 smt116

To align with what that means generally, we'd say something like private? true in the action. Although to align with 3.0 it would be something like public? false (and if I had thought of it before 3.0 it would default to false 😢). This seems like a good idea to me. It would be up to extensions to check that they are only using public actions, but thats how everything else already is so that should be fine.

zachdaniel avatar Jul 01 '24 18:07 zachdaniel

I've labeled this as a "good first issue", as implementing it in core will be easy. Once that is done, issues will need to be opened in AshGraphql, AshJsonApi, and AshPhoenix (not creating forms for private actions? maybe, maybe not) to track the usage of this metadata there.

zachdaniel avatar Jul 01 '24 18:07 zachdaniel

I think what we would likely still require, however, is something like this in policies:

bypass private_action?() do
  authorize_if always()
end

But it becomes safer to include a policy like this because you know for a fact that no public interface contains it.

zachdaniel avatar Jul 01 '24 18:07 zachdaniel

Once that is done, issues will need to be opened in AshGraphql, AshJsonApi, and AshPhoenix (not creating forms for private actions? maybe, maybe not)

I would say that a form is still kind of an application interface. IMHO, non-public actions should never be used outside of the system. Unfortunately, it means no console usage too (without authorized?: false), but better be consistent than having exceptions in the logic. It should be impossible to interact with non-public actions using any kind of "human accessible interface".

smt116 avatar Jul 02 '24 08:07 smt116

Console usage would be quite hard to detect unfortunately. I'm not sure if it's reasonable.

zachdaniel avatar Jul 02 '24 10:07 zachdaniel

Because if it uses process dictionary for example internal action calls by the action would think they are in the console too

zachdaniel avatar Jul 02 '24 10:07 zachdaniel

Right 🤔. Good enough

smt116 avatar Jul 02 '24 10:07 smt116