Sorry, this feature is not documented mostly because it was experimental and we thought it is going to change. Anyways, I can briefly describe here how it works so that you can work with it.
**** This is what is already there and how it works ****
For the purpose of authorization, Druid HTTP endpoints will extract two information namely a
Resource and an
Action. As of now, there are three types of Resources in Druid -
STATE. For any type of resource, possible actions are -
WRITE. Here are some examples of what it means in practice -
If a query is posted to Druid then that means the
Resource is the ‘DATASOURCE’ being queried and the
Action is a
If an indexing task is submitted then the
Resource is the
DATASOURCE being indexed and the
If a GET is done on coordinator dynamic config then the
CONIFG and the
READ, vice-versa if a POST is done then
If a GET is done on /status endpoint or /leader endpoint then the
STATE and the
Thus, POST or DELETE always corresponds to the
WRITE action and GET to
Resource type is pre-defined for each endpoint.
DATASOURCE resource type contains more information about datasource name,
STATE resource type does not carry any information about the exact configuration or state being accessed or modified.
For more implementation details read the master comment on PR - https://github.com/druid-io/druid/pull/2424
**** This is what you will have to implement ****
druid.auth.enabled is set to
true then for each HTTP call Druid will extract the appropriate
Action information depending on the endpoint. After this, Druid code will look for an implementation of
AuthorizationInfo interface in the request attribute of the HTTP request with attribute name as
AuthConfig.DRUID_AUTH_TOKEN (which is currently set to “Druid-Auth-Token”).
Therefore, you will need to implement a servlet Filter which will inject appropriate implementation of
AuthorizationInfo interface as a request attribute (“Druid-Auth-Token”). After getting this object, Druid will then call
isAuthorized(Resource resource, Action action) method of your implementation. Thus, you will write your authorization logic inside this method, you can use the Resource object to figure out what is being accessed. For example, for an indexing task POST, resource.getType() will return
ResourceType.DATASOURCE and resource.getName() will return the datasource name. However, for all
STATE ResourceType, return value of resource.getName() is same and does not matter.
Now the question is how to inject the servlet Filter in Druid. The answer is you will need to create a Druid extension. I am assuming you would already be knowing how to create and load custom extensions with Druid. So, I will just give some pointers here - http://druid.io/docs/latest/development/modules.html. Also, there are numerous extensions in the Druid repo here https://github.com/druid-io/druid/tree/master/extensions-core.
In your extension, you will need to implement
ServletFilterHolder interface which will return your implementation of
AuthorizationInfo. You can follow example of
QosFilterHolder here - https://github.com/druid-io/druid/blob/master/server/src/main/java/io/druid/server/initialization/jetty/JettyBindings.java#L53 to write logic that can return your own implementation of
AuthorizationInfo. Finally, bind your implementation of
ServletFilterHolder in the DruidModule of your extension like this - https://github.com/druid-io/druid/blob/master/server/src/main/java/io/druid/server/initialization/jetty/JettyBindings.java#L48
- Implement AuthorizationInfo interface and write your authorization logic in the isAuthorized method
- Inject this implementation in every request sent to Druid as a request attribute with name “Druid-Auth-Token” using servlet filter
- Enable security by setting druid.auth.enabled=true
As noted this is an experimental feature and is not perfect. If you have any more questions, feel free to ask. Thanks