External roles and attributes mapping
If you managed which topics (or any other resource) in an external system, you have access to 2 more implementations mechanisms to map your authenticated user (from either Local, Header, LDAP or OIDC) into AKHQ roles and attributes:
If you use this mechanism, keep in mind it will take the local user's groups for local Auth, and the external groups for Header/LDAP/OIDC (ie. this will NOT do the mapping between Header/LDAP/OIDC and local groups)
Default configuration-based This is the current implementation and the default one (doesn't break compatibility)
akhq:
security:
default-group: admin
groups:
reader:
- role: reader
# patterns: [ ".*" ]
# clusters: [ ".*" ]
ldap: # LDAP users/groups to AKHQ groups mapping
oidc: # OIDC users/groups to AKHQ groups mapping
header-auth: # header authentication users/groups to AKHQ groups mapping
REST API
akhq:
security:
default-group: no-roles
rest:
enabled: true
url: https://external.service/get-roles-and-attributes
groups: # anything set here will not be used
In this mode, AKHQ will send to the akhq.security.rest.url
endpoint a POST request with the following JSON :
{
"providerType": "LDAP or OIDC or BASIC_AUTH or HEADER",
"providerName": "OIDC provider name (OIDC only)",
"username": "user",
"groups": ["LDAP-GROUP-1", "LDAP-GROUP-2", "LDAP-GROUP-3"]
}
and expect the following JSON as response :
{
"groups": {
"topic-writer-clusterA-projectA": [
{
"role": "topic-reader",
"patterns": [
"pub.*"
]
}, {
"role": "topic-writer",
"patterns": [
"projectA.*"
],
"clusters": [
"clusterA.*"
]
}
],
"acl-reader-clusterA": [
{
"role": "acl-reader",
"clusters": [
"clusterA.*"
]
}
]
}
}
If you want to send a static authentication token to the external service where it might be public, you can extend the configuration for the rest interface as follows:
akhq:
security:
rest:
enabled: true
url: https://external.service/get-roles-and-attributes
headers:
- name: Authorization
value: Bearer your-token
WARNING
The response must contain the Content-Type: application/json
header to prevent any issue when reading the response.
Groovy API
akhq:
security:
default-group: no-roles
groovy:
enabled: true
file: |
package org.akhq.models.security;
class GroovyCustomClaimProvider implements ClaimProvider {
@Override
ClaimResponse generateClaim(ClaimRequest request) {
String filterRegexp = request.groups.collect {
'^' + it + '\\..*'
}.join('|')
def groups = [
"reader": [
new org.akhq.configs.security.Group(role: "reader", patterns: [filterRegexp]),
]
]
return ClaimResponse.builder().groups(groups).build();
}
}
groups: # anything set here will not be used
akhq.security.groovy.file
must be a groovy class that implements the interface ClaimProvider :
package org.akhq.models.securitys;
public interface ClaimProvider {
ClaimResponse generateClaim(ClaimRequest request);
}
enum ClaimProviderType {
BASIC_AUTH,
LDAP,
OIDC
}
public class ClaimRequest {
ClaimProvider.ProviderType providerType;
String providerName;
String username;
List<String> groups;
}
public class ClaimResponse {
private Map<String, List<Group>> groups;
}