Role based authorization(with PKI auth)

I'm trying to enable role based authorization with PKI auth.

I created a test user:
curl -k -u elastic:changeme "https://localhost:9200/_xpack/security/user/testuser"
{"elasticsearch.kibana.social.ea.com":{"username":"testuser","roles":["superuser","testkibana"],"full_name":null,"email":null,"metadata":{},"enabled":true}}

and when I search using the user's client certificate I got 403:
certs curl https://localhost:9200/test_index/_search
--key testuser.key --cert testuser.crt --cacert intermediates.pem -k -v
< HTTP/1.1 403 Forbidden
< content-type: application/json; charset=UTF-8
< content-length: 311
<

  • Connection #0 to host localhost left intact
    {"error":{"root_cause":[{"type":"security_exception","reason":"action [indices:data/read/search] is unauthorized for user [testuser]"}],"type":"security_exception","reason":"action [indices:data/read/search] is unauthorized for user [testuser]"},"status":403}%

Did I miss something here?

Yes.

See step 5 of Configuring a PKI realm | Elasticsearch Guide [8.11] | Elastic

The user you created via the API is a native realm user. It has no relationship with the user that is authenticated via PKI except for having the same username.

You do not need to define a native user for each of your PKI users, users that authenticate via the PKI realm are emphemeral they exist simply by virtue of authenticating.

So, in your example you are getting a 403 because you authenticated as a PKI user, but that user has no roles.

You have two options:

  1. Map the PKI username/DN to a set of roles.
  2. Delegation authentication to your native realm.

In the first case, you would use the role mapping API to do the equivalent of what you tried to do in the user API.

POST /_xpack/security/role_mapping/testuser
{
  "roles": [ "superuser", "testkibana" ], 
  "rules": { "field" : { "username" : "testuser" } },
  "enabled": true,
}

In the second case, you would change your PKI realm configuration to set the authorization_realms to your native realm.
Something like:

xpack.security.authc.realms:
  native.native1:
    order: 0
  pki.pki1:
    order: 1
    authorization_realms: [ "native1" ]   

Note: the above syntax is for ES 7.x, the format for 6.x is different.
You didn't indicate which ES version you are using.

Thanks a lot. that makes a lot of sense. However I'm getting No handler found when I try to create the mapping:

➜ certs curl -u elastic:changeme -k -v -X POST -d '{"roles":["superuser","testkibana"],"rules":{"field":{"dn":"cn=testuser"}},"enabled":true}' 'https://localhost:9200/_xpack/security/role_mapping/testuser'
Note: Unnecessary use of -X or --request, POST is already inferred.

  • upload completely sent off: 118 out of 118 bytes
    < HTTP/1.1 400 Bad Request
    < content-type: text/plain; charset=UTF-8
    < content-length: 109
    <
  • Connection #0 to host localhost left intact
    No handler found for uri [/_xpack/security/role_mapping/elasticsearch.kibana.social.ea.com] and method [POST]%

That doesn't look right - the error message you've provided doesn't match the URL you've posted. Did you manually edit one of them?

Yes. I did. the actual message is:
No handler found for uri [/_xpack/security/role_mapping/testuser] and method [POST]%

but you get my idea. The error message just says No handler found.

I am wondering if it is because I'm using 5.0.2

I think the reason might be just the older version of ES used role_mapping file, and it doesn't have a api to change the role mapping.

Thanks a lot Tim.

Hi @TimV, I still haven't get the PKI auth working for my 5.2.2 cluster.
When I authenticate with the client cert: ES returns:

➜ curl https://localhost:9200/_xpack/security/_authenticate?pretty
--key key.key --cert cert.crt --cacert ca_cert.pem -k -v
< HTTP/1.1 200 OK
< content-type: application/json; charset=UTF-8
< content-length: 153
<
{
"username" : "app.test.com",
"roles" : ,
"full_name" : null,
"email" : null,
"metadata" : { },
"enabled" : true
}

so there is no "pki_dn" in metadata filed in the response as it is supposed to be based on this document: https://www.elastic.co/blog/elasticsearch-security-configure-tls-ssl-pki-authentication

so looks like I can't associate my client cert with a specific role in the mapping file.

Do you know what could be wrong?

That is an ancient version (released more than 2 years ago).
I'll do my best to help, but we've fixed a lot of bugs since then, and my memory of exactly what is in each version gets fuzzy the further back we go.
Are you sure you can't upgrade? You're making your life very difficult and if you raise a case with our support team they'll have difficulty supporting you on an old EOL version.

That metadata field didn't exist in 5.2

PKI works in 5.2, it's just harder to set up since there's no API and no metadata to inspect.
You're probably entering the wrong DN in the role mapping file. Openssl reports DNs in format from parent RDN to child RDN (e.g. DC=com, DC=example, OU=users, CN=john)
Elasticsearch uses the LDAP/X.500 style format of child-first e.g. CN=john,OU=users,DC=example,DC=com)

You saved my day, Tim.
I reverse the order of the DN in my role_mapping file and it worked

Thanks a lot

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.