Search code examples
gremlintinkerpop

Is there a way to map users to individual graphs in Gremlin server?


I am setting up multiple graph mappings to an OrientDB database in Gremlin server. However, I can't find what to script in Groovy plus what to configure in the configuration yaml file in order to be able to map each authenticated user to a single graph, rather than have all the users validated by the authenticator be able to access everything. Is there any way to achieve this?


Solution

  • Gremlin Server does not provide any features for authorization - only authentication. You would have to build something yourself to handle restricting users to different graphs (or other constraints). That would mean building two things:

    1. A custom ChannelInboundHandlerAdapter to handle authorization - maybe called AuthorizationHandler
    2. A custom Channelizer implementation to wire in your custom authorizer to the pipeline - maybe called AuthorizingChannelizer

    The AuthorizationHandler would basically just override Netty's channelRead() method

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof RequestMessage){
            RequestMessage requestMessage = (RequestMessage) msg;
    
            // examine contents of RequestMessage to see what is being requested
            // e.g. the graph - the user information will be there too but 
            // depending on the authentication method you're using you might need
            // to re-decode it at this time as it doesn't appear that the authenticated
            // user is placed on the ChannelHandlerContext for some reason. i made
            // a note to change that as it seems helpful and is a simple enough thing 
            // to do
        }
    }
    

    For the AuthorizingChannelizer you would basically extend the WebSocketChannelizer and override the configure() method:

    @Override
    public void configure(ChannelPipeline pipeline) { 
        super.configure(pipeline);
    
        // add an instance of your `AuthorizingChannelizer` to the end of the 
        // netty pipeline which will put it after the `AuthenticationHandler`
        // but before all the Gremlin processing/execution
        pipeline.addLast("authorizier", authorizingChannelizer); 
    }
    

    Then, in your Gremlin Server config you replace the channelizer setting with the fully qualified name of your AuthorizingChannelizer. Assuming you've placed your jar containing that class in Gremlin Server's path it should create an instance of it at startup.

    I would look at the existing "handler" and "channelizer" code for more inspiration on how to make this happen.