DEV Community


Discussion on: Help: Security per record - is it possible to make optimal solution ?

greenroommate profile image
Haris Secic Author

Thanks a lot for the answer. I do have a problem where this is actually a requirement and people will be spending a lot of time managing access control through out the system.

I remembered one real world example on small scale. Let's say you have a building and it has floors and rooms on it. Now you wan't some users to access some rooms. But not all. So if you give user access to room 2001 on floor 2, it means that user has to have access to a building because he cannot access floor unless he access room. But on the other hand he doesn't have to have access to floor 1, he can use elevator directly to floor 2, and have a key or a card for specific room.

Now my problem in comparison to example would be I have customers owning thousands of buildings. And I have a lot of customers. And some of them want to offer access to users belonging to a different client BUT only for SPECIFIC buildings :D

I tried to push something which most people hate me for and that is "tell clients this cannot work good and let's have access per parent". I'm not sure will it work (will sales accept the suggestion and will clients agree on it as reasonable approach) but if so I still need to have access per building and you if you have 1 user with access to buildings A,B,C another one can have access to C,D and third one to B,D,N,L,M. So I would have to do all permutations of it to make roles or have role per object in database which still brings me to I need access control inside of my own graph database and roles don't help at all as in this case it's much easier to have users have access to different parts.

Your example sounds interesting but I have no idea where to start with it so I'll start searching for "data source identifiers" and check if something pops up.

Again, thanks a lot for the answer.

phlash909 profile image
Phil Ashby

Nice analogy - thanks, and glad you aren't trying to solve a non-existent problem :)

As @tonymet suggests, this does feel like a file system in some ways. Perhaps you can use the graphDB primarily as the permissions management system though appropriate use of relationships from a node to nodes that represent users, so you can express the 'room access' you describe and build searches that apply the stated permissions (by requiring the edges back to the user(s)), then collecting related attributes from the 'pile' once you have filtered down the nodes?

Thread Thread
greenroommate profile image
Haris Secic Author

I'm actually working towards it. Thanks. Also the thing with this one was performance concern, where I have additional call to access management API, or even if I kind of "monolith it" I still need that extra call to filter out data not allowed for specific users. I'll look into options for my framework and how not to redesign whole architecture because of this but still maintain some performance. Anyways I think it's safe to say I'm using Neo4j sa graph db and Spring (for now) as framework so there might be a way. Just not here yet.

But more importantly I value your answer as it gave me some encouragement that there's just no way around "user per resource" as it's a requirement, but it might be not that bad as I think.

Just want to share latest experiment in Cypher

RETURN EXISTS((s)-[*0..]->()<-[:HAS_ACCESS]-()<-[:HAS_ROLE*0..1]-(u))

So this would work for both User having direct access to a certain object or Role having access to it. It's also relying on a fact that only parents point to children not the other way around. So if I have two options:
where User - has access -> child2 but Role -> has access -> child 1
I can get true for

MATCH (c:Child) WHERE = 'Child' OR = 'Child2'
MATCH (u:User {name: "user1"})
RETURN EXISTS((s)-[*0..]->()<-[:HAS_ACCESS]-()<-[:HAS_ROLE*0..1]-(u))

so it either uses Role if it can or ignores it. And it's quite fast to my surprise, however it's just a sample cypher on sample DB. But also I can ask for Super parent in same query and get true. But it does go through Role as it's using most of the relationships or it might be that role access relationship was made first so it hits it first.

So I discovered that I can have optional relationships and mandatory ones in query with Neo4j. Might write post about this one as I find it interesting what can you do with cypher regardless of what I use in the project.