Fork me on GitHub

Are there any known examples of securing an api endpoint further? I read the security chapter of the guide but there are some additional things that come to mind like: • Requiring a valid session for all requests via middleware except for whoami / current-user & login - I could try to examine the request AST before processing or maybe move those requests to another unrestricted endpoint / remote? • Handling session expiration - use a custom global-error-action that will redirect to the login screen on 401 (does this cover loads also)? • Role based access control for resolvers / mutations - look into Pathom plugins for possible declarative security vs having special admin resolvers / mutations under a separate endpoint with additional checks?


re: your third point, see this discussion here


I've been having success using the ::pc/transform-based access control in my own project--code is here if you're curious


I do something similar, though I wrote my own defresolver/defmutation macros so that they check that you supply a security check or won’t compile. I defined my own key for that in the map, instead of using transform. It has the same basic shape, though. The top-level session block in middleware really isn’t necessary IMO. I think the checks that resolvers can run are sufficient. I use a :check (fn [env params] boolean?) key in my macro, so saying something is “open” is just (constantly true) , and pre-defining a logged-in function that just checks the ring request for a valid session is also easy. On (2): I usually put that in the Fulcro remote response middleware, and have a particular response code for it. Putting the app in an atom gets around the circular reference problem…or you can set the remote after creating the app..either way. I give the app to the response middleware, and then it can run arbitrary mutations to do things like notify the user, route them, show a toast, etc.


I do general error handling in the middleware as well. The global-error-action is also a useful place to put it.


And yes, you can look at the session in the Ring middleware for detecting that someone is no longer in a valid session and return a response code for that

Karol Wójcik17:09:34

@tony.kay Is it possible to distribute this a library? Preferably with the following ns name: com.fulcrologic.guardrails.core. The thing is that guardrails does some stuff that are incompatible with GraalVM. I would love to provide set of PR's to address this issue, but still having noop implementation of Guardrails would be awesome. Mostly because the binary size will become much more smaller with noop on GraalVM. PS: Thank you for the awesome library! EDIT: 🙏


I don't understand the question


That is already distributed

Karol Wójcik20:09:16

Yeah, but not as a separate artifact.


oh, you want just that ns in a lib?


oh, no, not AS core...that can cause all sorts of nightmares


if both accidentally end up on classpath, the one that is first is what you get

Karol Wójcik20:09:30

For instance I’m using pathom3 that uses guardrails. The current guardrails release is not graalvm compatible, therefore I had to do exclusions on the guardrails from pathom3 & include the noop namespace in my source code. If noop would be a library I could just include is as a dependency.


right, and would cause nightmares for library users when they get both on the classpath (transitively). It's not an option

Karol Wójcik20:09:49

Do you thing there is other option we can use instead?


Happy to take PRs on the actual library to do whatever makes sense to try to make it work well with GraalVM, but the separate library idea has cropped up and been tried more than once


(in other libraries, and by myself...that's why I know it's such a bad idea 😄 )

😄 2
Karol Wójcik20:09:21

Like maybe one can choose whether one wants to use guardrails or fallback to noop via system property?

Karol Wójcik20:09:36

I mean there are two things to consider. 1. GraalVM binary size. For this we need to substitute fulcro core with noop. Maybe system property? 2. GraalVM compatibility. This one I can help with. The first one i dont know which way of achieving this is the best


yeah, on (1) I do no know...typically you don't have to worry about clj size, since they are small source files. Spec kind of blows things up a bit. I'm game for a system property...we alraedy use those. It would just have to be bw compatible.


The real problem is the transitive requires. What we could do, though it is probably a bit rough for GVM, is to not use the ns macro, and instead do all of the requires via algorithms. Or, for that matter, make a top-level macro that looks for system property and subs out the entire body of the file based on that. That might work…but lots of fun for cljc 🙂


That’s probably ok for CLJC, actually, since macros run in CLJ land.


Not sure how much that’d mess with IDEs and source analysis, though