Releases: LeChatP/RootAsRole
v.3.2.4
v3.2.3
v3.2.2
v3.2.1 - Small documentation update
v3.2.0: editor update
What's New
For users:
- Feature:
chsrnow include a secure policy editing using vim. It has been secured by using Landlock and seccomp for applying POLP on the program. For now it's configured only for vim. -Kargument allows to delete the authentication cookie-vargument for getting the program Version- removed the wildcard-denied field. It was a messy pcre2 filter.
Internally:
- v3.1.1 Fix regression with path management by @LeChatP in #76
- Hardening Enums for policy checking (for harder Rowhammer attacks)
- An entire integration test mechanism implemented.
- Several bug fixes
Full Changelog: v3.1.0...v3.2.0
v3.1.0
Performance, configurability, features update
New Features
add -E (--preserve-env) for preserving environment variables from current execution environment.
{{If a task allow to override-env option, the users could replace the environment variable from Delete decision to Keep. This still applies env check, del and set policies, so still filters env variables
Let's take an example :
{
"name":"permissive-task",
"options": {
"env": {
"default": "delete",
"add": ["HOME"],
"check": ["TZ"],
"del":["PERLLIB"],
"set": { "PS1" : "RaR task $"}
},
"override-env": true
}
}When the user will use sr <command> the command will:
- delete all variables by default except for next rules:
- keep HOME value
- check TZ value and keeping if valid
- set PS1 set as "RaR task $" value.
And when the user will use sr --preserve-env <command>, the command will :
- keep All current env variables by default
- check TZ value and keeping if valid
- set PS1 set as "RaR task $" value.
- delete PERLLIB variable
Note: Enabling this option lowers the task's priority in the automatic selection (when no argument are written). Therefore, if an identical task exists without this option, it will be selected first.
add -u option (Thanks to Hocine)
Now setuid element is not just a string, it could be a structure, defining a set of users to change to, an enhanced and various ways than sudo. Let's take few examples:
{
"name":"permissive-task",
"cred": {
"setuid": ["user1","user2"]
}
}This allows users to do sr <command>, it will automatically take the first user for setuid by default. The user could also do : sr -u user2 <command> and it will execute the command with the user2 in setuid.
{
"name":"permissive-task",
"cred": {
"setuid": {
"fallback": "user1",
"default": "all",
"del": ["user2"]
}
}
}This example sets user1 as a "fallback" setuid user if no -u specified. Now users could become any user using -u except user2
Add -g option (Thanks to Hocine)
As the same manner than -u does, -g allows to users to specify a set of groups. The subtle is that it manages a set of groups making it a bit complexier than setgid as you can define array of groups, and the matching is always strict.
Note (already present in previous versions): setgid() is always the first group in a list, then the rest of groups are setgroups()
Implementing Interchangeable file format with CBOR and JSON
Since we've shifted our RootAsRole configuration from XML to a JSON base in 2023 or 2024 (I don't remember well), we decided to change the design of our tool to make it policy language-agnostic while still setting JSON for policy format and location. So today we implemented CBOR file format for performance objective.
Funnily enough, we initially considered supporting XML because it offers features JSON doesn't natively, like directly translating files to ASN.1 for an optimized binary format. But hey, we've basically rebuilt that functionality in a modern, dev-friendly way thanks to serde library.
🚀 Optimizing sr: A Performance Leap Over sudo and sudo-rs
Thanks to ESORICS conference reviewers, we took an special care to optimizing our tool. Indeed, reviewers were wondering that our new gensr automation tool were introducing a lot of rules for an Ansible playbook, and we didn't evaluate the performance in consequence. We indeed found performance issues initially. But we heavily optimized the whole tool. We compared to sudo and the graph is clear: 77% better raw performance, 45% better slope than sudo implementation.

You could reproduce it in this repo.
I recently tried to put sudo-rs through its paces to evaluate its performance, but I hit a wall. Unfortunately, it seems like scalability might not be a priority for them, and an issue I created (here) is set to "won't fix" for now. From the little I was able to test, the performance is either the same as, or even worse than, regular sudo. It really feels like sudo-rs is more or less a direct copy of the C sudo code in Rust.
Tests, tests, tests
We wrote a bunch of tests. It highlighted some bugs in the code which were instantly solved after tests writing. We think that we tested most of use-cases. Since 2024, we reviewed several times the tests.
About deploying RootAsRole to distributions
As for the package deployment, I really need your help to bring the project to Linux distributions repositories!
I've started working on it myself, starting with creating Debian packages for dependencies. There are many missing packages in the dependency tree, so it's not a simple task. To top it off, some of these dependencies appear to be unmaintained. I even had to take over the maintenance of rust-pam-client crate (so republishing to a pam-client2...), because the main contributor didn't respond to my emails or GitLab messages.
The main objective is to publish a first package called sr which deploys sr and chsr binaries. I still hesitate if I separate sr and chsr onto two distinct packages, but I think chsr is useful. Then in a second step generating a package like gensr or/and capable packages for having RootAsRole configuration helpers.
If you have experience packaging for different Linux distributions, your help would be greatly appreciated.
v3.0.0
🎉 RootAsRole v3.0.0 is Here! 🎉
What Does This Mean? 🚀
This release marks a huge milestone for RootAsRole! After months of dogfooding RootAsRole in my own setup without a hitch, I'm excited to finally say: we’re ready for deployment!
In addition to thorough automatic unit testing, I’ve been hard at work reviewing CVEs from both the Sudo-rs and sudo projects, ensuring RootAsRole remains secure and solid. Along the way, I squashed some bugs (all tracked in the commits), further polishing the reliability of the tool.
One major update: we've extracted the "capable" tool into a separate repository—it's a bit of a heavyweight right now and not quite ready for daily production. This way, RootAsRole stays lean and clean, with a lighter development environment for you.
What's New? ✨
- 🛠 Tons of fixes following daily personal use, making RootAsRole smoother than ever!
- 🌟 "capable" has a new home in its own repo: RootAsRole-capable.
- 🤖 Automated deployments with easy-to-use .deb and .rpm packages.
- ⚡️ Simplified installation process and streamlined dependencies.
- 🧑💻 Optimized binaries that now require fewer C libraries—just libc for
chsr, and pcre2 + pam (and libc) forsr.
And since v2.X, what happened ?
It's been a long journey. In October 2021, I started my PhD on the principle of least privilege, a logical continuation of my previous work during a second-year graduate internship. Two years later, I'm delighted to have deepened my research and significantly improved RootAsRole, in line with the state of the art and usability principles.
When I took over this project, I initially set out to make it ‘usable’ and ‘reliable’, so that it would provide accurate and fancy results for the research articles I was writing. However, as I worked on the new features, I discovered that managing memory security was impacting my productivity, as I had to continually check previously developed elements, in the fear of missing something that could be a big issue.
That's when I discovered Rust, a good solution for my fears! During a holiday, I decided to immerse myself in this language by completely rewriting RootAsRole. What a complex language! But right from the start, I knew that this work would save me a considerable amount of time.
Since version 2.X, it had become clear to me that there was a conceptual problem with RootAsRole. So I scrupulously followed the RBAC standards and their various variants (RBAC-0, OrBAC, etc.), which enabled me to clarify the conceptualisation of the tool. A quick note: in examining a lot of code, I've noticed that many libraries and services claiming to implement RBAC are mistaken.
I quickly implemented RBAC-0, then I implemented the static separation of roles, the hierarchy of roles in ‘plugins’, judging that they were not necessarily necessary in personal environments for example. I also rewrote the configuration file in JSON rather than XML, because no library provided all the functionality needed in XML (DTD, comment management). Conceptually, the policy is sufficiently structured to be stored in a relational database. I therefore decided to split the configuration in two: a ‘fixed’ part containing information about the policy, and the policy itself stored in another file, or directly integrated into the same file in JSON. I've also set up a versioning mechanism and a transparent update of the configuration and the policy.
chsr is a difficult policy modification tool to conceptualise. I looked for complex commands that had very good clarity, and I took inspiration from the ip and nftables commands for the organisation of my command. To do this, I had to learn how to write a grammar for a parser, and I discovered the pest library, which allowed me to do this easily with Rust.
Also, I had this thought: if you give administrator rights to a user, he can change the policy and roles, it is not desirable. So I made the RootAsRole configuration immutable with the chattr +i file system attribute. Also, I've gained a better understanding of everything that's possible with Linux capabilities, but above all everything that's really useful and practical for a privilege management tool.
Speaking of performance, I was able to run an initial benchmark between the version of sudo (C version) installed on my machine and RootAsRole. I was pleasantly surprised to find that RootAsRole was around 60% faster than sudo for the simple ‘sr ls’ and ‘sudo ls’ commands. However, further tests are needed to confirm these results and explain why a such huge difference.
Today, I'm proud to present RootAsRole 3.0, a complete, secure and easy-to-use role management tool. I hope you'll find it useful and enjoy using it as much as I enjoyed developing it. Don't hesitate to send me your feedback, I'm always interested in your suggestions for improving this tool. I'm counting on you to help me to make it even more secure, efficient, useful and reliable.
As capable is now in its own repository, I have many objectives, aligning with my PhD studies, and this is so exciting! So tomorrow, I am focusing on this tool that helps configuring RootAsRole.
In the future, I intend to continue to maintain the project, study proposals and improve RootAsRole.
Full Changelog:
Check out all the details here.
Thank you all !
Eddie
v3.0.0-alpha.5
What's Changed
- Addressing sudo's CVE that are potential to RAR by @LeChatP in #49
- v3.0.0-alpha.5 by @LeChatP in #50
- Making capable usable (not completely practical for now)
Full Changelog: v3.0.0-alpha.4...v3.0.0-alpha.5
v3.0.0-alpha.4
This new release adds many new features! With its comprehensive documentation and many unit tests.
Merges
- Update README.md by @SamerW in #38
- Patch install process by @LeChatP in #39
- v3.0.0-alpha.4 by @LeChatP in #42
- Bugfixes, Tests & Docs by @LeChatP in #43
- Hashchecker fix + docs by @LeChatP in #44
- Tests and bugfixes by @LeChatP in #45
- Capable: Add json output by @LeChatP in #46
- Fixes and tests + Better conflict resolution + Scenarios in documentation by @LeChatP in #47
- Fix env vars + erasing password in-memory by @LeChatP in #48
Replacing XML to JSON file format
- The project now embraces JSON for configuration management, offering improved flexibility.
- After careful consideration among JSON, YAML, or KDL, JSON emerged as the preferred choice.
chsris simple enough to avoid direct file manipulation- JSON is the industry's most used and interoperable.
- Discouraging text editing because
rootasrole.jsonshould be immutable, as usingchattris annoying - Other formats allow commenting but these would be deleted each time using
chsrtool.
Adding new configuration file for storage configuration
As RootAsRole implements the RBAC model, it would be interesting to plan the database integration, such as LDAP for user assignment and SQLite/PostgreSQL/MySQL for role and task definitions.
Rewrite of chsr tool
- The
chsrtool has undergone a complete rewrite, eliminating the Text User Interface (TUI). - Concerns regarding usability inefficiency drove the decision to move away from TUI.
- The new Command-Line Interface (CLI) offers enhanced usability and efficiency in managing roles.
- Inspired by tools like
ipornftables, the new CLI syntax is intuitive and user-friendly. - We developed a grammar
pestto enable syntax management like these tools, asclap-rscouldn't suffice.
- Inspired by tools like
- Closing #41
Plugin-based features
RBAC-0 features are now core program features, with the implementation of hierarchical roles moved to an 'API'. This facilitates the addition of new features for the separation of duties.
Other new features
- The sr command now operates in a pty, mitigating tty hijacking risks.
- password is now erased from memory after use.
- Enhanced options include:
- Multiple environment variable management policies for flexibility in handling environment variables.
- Inheritable option management allows administrators to define general and specific options with inheritance control.
- Timeout is now an option per-task, providing granular control over task execution.
- Fixes #40
Full Changelog: v3.0.0-alpha.3...v3.0.0-alpha.4
3.0.0-alpha.3
By rewriting this program entirely in Rust, I could add new features quickly and get almost the same performance as the C version. Rust language is appropriate for our software. And the rewriting was easy.
However, today, I would like to say what differs in this version:
From the most to the least exciting changes
- Full Rust Rewriting, no more C !
- The
srbinary is to execute a task with a role - The
chsrbinary is to modify the configuration and the RootAsRole policy with command line arguments or fancy terminal interface - The
capablebinary determines which capabilities are needed for a program.
- The
- Role hierarchy managed (role parents' tasks will be included)
- Parent roles and their tasks are Included in partial order comparison.
- This role will be chosen if a task is less privileged in its parents.
- TODO:
chsrneeds to be managed with cursive.
- Static separation of duties (SSD) implemented
- If one role defines another role as SSD, actors cannot be in this role
- This is checked on
chsr. Configurator no longer needs to check it manually; it will be informed as denied. - This is checked on
sr. If a user is added to a group that conflicts with SSD, conflicting roles are forbidden. - TODO: Editing the configuration of SSD with
chsr.
srnow handles timestamp cookies!- This means that
srdoesn't require authentication for every command executed before a certain delay. This is entirely configurable like sudo does.
- This means that
- Thanks to the Aya framework, The
capableeBPF program is now in Rust. It simplifies the compilation process, which was the main problem with the C version. - Capabilities are now entirely documented, thus automatically dumped from the capabilities manual.
- Better Command parsing
- Binary Path is matched with the extended glob syntax.
**means any path; you could translate it by "anything, everywhere".*means any direct file on the current path here will be relative to the current working directory.
- The previous meaning of
**was changed toALL. SoALLmeans any command and any arguments. This is because the meaning of**exists in the glob syntax and could be confusing. - Paths are now canonicalized.
- Arguments can use PCRE2 to match. See here to build your regular expression
- Binary Path is matched with the extended glob syntax.
- Configuration file Versionning management implemented
- This means that any upgrade of the current configuration will be managed and automatically migrated from one version to another.
- Now, capabilities can be denied from role definition, and their parents are included
- libxml2 is still needed to verify DTD
- This negatively impacts performance because the program parses two times the configuration file
- Today, XML rust crates do not provide every needed feature. SXD is the most complete one, so I implemented a part of libxml2 C bindings, but it needs to be completed and could be complex to enhance.
- One day, I will consider migrating to JSON or YAML... However, I enforce the need for Schema Validation, which is not provided by default.
- Switched to Termion backend for cursive interface.
Full Changelog: v3.0.0-alpha.2...v3.0.0-alpha.3