ReadonlyREST has evolved very rapidly in the last year, We ticked a lot of boxes in the features list. Currently, the X-Pack security module made by the Elastic team and the ReadonlyREST Enterprise features almost overlap.
Let’s compare the Elasticsearch and Kibana security plugins.
Licensing Model and Price
Both plugins rely on a subscription-based fee model. This model reflects the need for a continual process of keeping the services up-to-date with the latest changes in the Kibana and Elasticsearch internals and APIs, the development of new features, and the need for vulnerability research to keep these products on top of the information security food chain.
Notably though, ReadonlyREST Free, the security plugin for Elasticsearch, is free (and working under a GPLv3 license). It’s the only FOSS-licensed realistic competitor to X-Pack Security right now. Its development is entirely sponsored by the sales of ReadonlyREST PRO and Enterprise Kibana security plugins.
ReadonlyREST PRO and Enterprise security plugins for Kibana have a flat subscription model. It doesn’t matter how many nodes you have; you pay the same annual fee.
The pricing model of X-Pack Security, on the other hand, is very aggressive. Because X-Pack Security is not sold as a stand-alone plugin but rather as one of the plugins inside of a multi-functional Swiss Army knife extension pack, the features together increased perceived value, justifying higher prices.
The graph below explains how X-Pack prices start at three times the price of ReadonlyREST, and grow quasi-linearly as the number of nodes in your Elasticsearch cluster grow. On the same chart, you can see how the ReadonlyREST Enterprise (their most expensive Kibana security plugin) price remains constant as your project grows.
Price (approx, normalised to ROR Enterprise) | X-Pack | ReadonlyREST Enterprise |
---|---|---|
1 node | ~3x | 1 |
3 nodes | ~5x | 1 |
10 nodes | ~10x | 1 |
The ReadonlyREST pricing policy remains constant. Growing your nodes and number of clusters is never a problem.
Encryption
Sending across credentials over plain HTTP in any form (basic auth, JWT, hashed) is risky; eavesdroppers can intercept credentials and impersonate users.
Both ReadonlyREST and X-Pack have your back, because both support HTTPS.
X-Pack Security | ReadonlyREST | |
---|---|---|
HTTPS (port 9200) | ![]() |
![]() |
HTTPS Protocol/Cypher negotiation | ![]() |
![]() |
Inter-node SSL (port 9300) | ![]() |
![]() |
The inter-node SSL is the encryption is an encryption layer of the Elasticsearch transport protocol. This interface is used by the Elasticsearch nodes for joining the cluster, performing replication and master election, forwarding queries, and so forth.
Although Elastic recommends enabling encryption by default, the performance cost to pay for encrypting this kind of traffic may be significant. For example, at CERN, inter-node encryption slowed things down to the point they simply gave up on it and used a firewall instead.
(*) If you use ReadonlyREST, and you still require Inter-node SSL, you can use the Apache 2.0 licensed “Search Guard SSL” plugin. Remember to disable the HTTP encryption using “searchguard.ssl.http.enabled: false” in elasticsearch.yml.
Access Control
X-Pack access control is role-based (RBAC), while ReadonlyREST with its ACL (access control list) resembles an application level firewall. However, both behave like filters that grant access (or not) to incoming requests.
Below, we will examine the levels for which each product is able to analyze a request to compare the two solutions.
Network level
Network level | X-Pack Security | ReadonlyREST |
---|---|---|
IP Address | ![]() |
![]() |
IP Mask | ![]() |
![]() |
Although it is possible to explicitly block a set of IP addresses and masks in X-Pack, this action will act as a global pre-filter. That is, X-Pack will block the request before even running the RBAC logic.
xpack.security.transport.filter.allow: "192.168.0.1" xpack.security.transport.filter.deny: "192.168.0.0/24"
In ReadonlyREST, you can use network level filtering as ACL rules. This is significantly more versatile:
readonlyrest: access_control_rules: - name: "let localhost in" type: allow hosts: ["127.0.0.1"] - name: "let LAN in, but they see only logstash indices" type: allow hosts: ["10.0.0.0/16"] indices: ["logstash*"] # Implicitly reject any other requests
The above example literally reads:
- Does the request originate from 127.0.0.1? If so, then let it through.
- Does the request come from the local network AND refer to one or more indices whose name starts with “logstash?” If so, then let it through.
- If none of the above is verified, reject the request.
HTTP Level
HTTP level | X-Pack Security | ReadonlyREST |
---|---|---|
Path | ![]() |
![]() |
Method | ![]() |
![]() |
Body length | ![]() |
![]() |
X-Pack mainly takes access control decisions at the Elasticsearch level (actions, indices).
ReadonlyREST can build ACLs at many levels, including HTTP.
Elasticsearch level
Elasticsearch level | X-Pack Security | ReadonlyREST |
---|---|---|
indices | ![]() |
![]() |
actions | ![]() |
![]() |
snapshots | ![]() |
![]() |
In the Elasticsearch protocol, all operations clients or cluster members can perform are internally named with a string called “action.”
Here are examples of actions:
indices:data/read/msearch indices:data/write/bulk indices:data/write/delete
You can explore all of the actions that are available in Elasticsearch in our documentation.
A list of actions represents the most granular, detailed way to describe what kind of operations are allowed or forbidden to a client. Making this list is exactly what ReadonlyREST allows you to do.
The creators of X-Pack made a different design decision. X-Pack groups actions into non-intersecting sets, called “privileges.” This is a handy tradeoff, but, without the possibility to specify single actions, may be a bit too coarse grained.
Completely missing in X-Pack is control over the management of snapshots by name i.e., the possibility to give a user the ability to restore only snapshots named after them.
readonlyrest: access_control_rules: - name: "users can create/restore snapshots prefixed witht their name" type: allow ldap_authentication: ldap1 snapshots: [${user}_snapshot*]
Auditing
X-Pack Security | ReadonlyREST | |
---|---|---|
write to file | ![]() |
![]() |
write to time-rolling index | ![]() |
![]() |
be selective on what to log | ![]() |
![]() |
custom serializer API | ![]() |
![]() |
forward logs to another ES cluster | ![]() |
![]() |
User Experience
X-Pack settings can be changed from file, in-index settings, CLI tools, or API calls. The API is organized in a very granular way. There is an endpoint for everything. This makes it simpler for developers to integrate very specific pieces of automation into the software because there’s a smaller probability to accidentally affect other features’ settings.
ReadonlyREST takes a much simpler approach. The settings are established as a monolithic entity – an immutable object that can be loaded from file (readonlyrest.yml), loaded from index (.readonlyrest) or overridden entirely, or rejected (if invalid) via a single API endpoint.
UX Warts
X-Pack
X-Pack suffers from a fragmented interaction model. Despite the numerous ways settings can be altered, the ways are not equally potent. For example, LDAP/SAML authorization won’t work if you attempt to implement it before adding role mappings. The only way to do it is via API – i.e., with cURL instead of editing a YAML file like usual.
ReadonlyREST
Monolithic settings object. Will need to submit the whole settings to change a small thing.
There is no form-based GUI to add local users/groups in ReadonlyREST like there is in X-Pack. There is only a semigraphical UI with a syntax checked and validated YAML editor.
Authentication
Authentication connectors are crucial for security and for enabling seamless integration with existing enterprise infrastructures.
Both X-Pack and ReadonlyREST support the major enterprise grade authentication systems, but what happens when you need to integrate with a rare/custom authentication system?
X-Pack requires you to implement two Java classes. ReadonlyREST delegates the task to a well-known, battle-tested reverse proxy. If Apache HTTPD, Nginx, or any other reverse proxy can handle it, we can handle it.
X-Pack Security | ReadonlyREST | |
---|---|---|
Unix Style password shadowing | ![]() |
![]() |
Hashed credentials in cache | ![]() |
![]() |
Basic HTTP | ![]() |
![]() |
LDAP | ![]() |
![]() |
SAML | ![]() |
coming soon |
JWT | ![]() |
![]() |
Reverse Proxy (X-Forwarded-User) | ![]() |
![]() |
External site Basic HTTP | ![]() |
![]() |
Custom authentication | ![]() |
![]() |
Authorization
X-Pack Security | ReadonlyREST | |
---|---|---|
Local groups | ![]() |
![]() |
LDAP | ![]() |
![]() |
Reverse Proxy (X-Forwarded-Groups) | ![]() |
![]() |
External JSON service | ![]() |
![]() |
LDAP group mapping | ![]() |
![]() |
Custom authorization | ![]() |
![]() |
Kibana User Experience
X-Pack Security | ReadonlyREST | |
---|---|---|
Remove Kibana apps from UI | ![]() |
![]() |
Hide add/edit/delete buttons (RO users) | ![]() |
![]() |
Multi user | ![]() |
![]() |
Multi tenancy | ![]() |
![]() |
Tenant impersonation | ![]() |
![]() |
Conclusions
All in all, if what you are after is strictly a security solution for the Elastic Stack (Kibana, Elasticsearch, Logstash, Beats, etc.), ReadonlyREST Enterprise offers much more value than X-Pack for the price. And the contract includes private SLA support too.
If you need all the extras of X-Pack (e.g., machine learning, SQL, graph relationships), your only choice is to buy from Elastic.