Skip to content
CAI
Software that uses CAICheck a score

trifectatechfoundation/sudo-rs

70.2

Strong · 30 September 2026

37.8k

lines of production code

Rust

primary language

2

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a Rust-based reimplementation of the sudo, su, and visudo utilities, designed to provide secure privilege escalation and user switching on Unix-like systems. It features a custom sudoers parser with formal verification, comprehensive PAM authentication, and robust process execution capabilities including PTY management and security profiles like AppArmor and NOEXEC. The project also includes extensive internationalization support and a cross-platform test framework using Docker containers to ensure compliance with standard behavior on Linux and FreeBSD.

How it got here

2022–2023 — Core implementation and compliance testing

47 changes.

This period focused on the initial implementation of the sudo-rs core, including the sudo, su, and visudo commands, alongside a complete rewrite of the sudoers parser and policy engine. The team established a robust test framework using Docker for cross-platform isolation and expanded comprehensive compliance and end-to-end test coverage to ensure behavioral correctness. Significant work also went into hardening the codebase with secure memory handling, AppArmor integration, and safe system abstractions.

2024–2025 — I/O optimization and internationalization

5 changes.

The project implemented a new bidirectional pipe with ring buffer for efficient PTY I/O handling and established dedicated binary entry points for core tools. It also added comprehensive internationalization support with multiple language translations and compile-time format validation to ensure safety.

Features

Add file locking and temporary directory utilities

The \src/system/file\ module now provides \FileLock\ for acquiring exclusive file locks (with optional non-blocking behavior) and \create\_temporary\_dir\ for generating unique temporary directories using \mkdtemp\. These utilities are exposed as public components within the system file subsystem to support secure file handling and isolation.

src/system/file · high confidence

Add verbose formatting for sudoers entries

Introduces a new \Verbose\ display implementation for sudoers entries, enabling detailed, human-readable output of rule components such as RunAs users/groups, command tags, and options. This supports the \sudo --list --list\ functionality by providing a structured view of the parsed configuration rather than just the raw aliases or commands.

src/sudoers/entry · high confidence

Added internationalization support with new language translations

The sudo-rs application now supports multiple languages. This change adds translation files for German (de), Spanish (es), French (fr), Frisian (fy), Italian (it), Georgian (ka), Dutch (nl), Polish (pl), Romanian (ro), and Simplified Chinese (zh\_CN), along with the base POT template. Users can now see interface messages, error strings, and help text in their preferred language, provided the system locale is configured accordingly.

po · high confidence

Formal verification of sudoers alias resolution logic

Added Why3 proof files for the sudoers module, formally verifying the correctness of the \find\_item\ function and the \get\_aliases\ alias table expansion. The proofs establish invariants and postconditions for matching items against aliases, ensuring that the alias resolution logic behaves as specified in the model.

proofs · high confidence

Implement sudoedit and enhanced sudo -l listing

Users can now edit files directly using the \sudo -e\ (sudoedit) command, which securely opens files for editing via a configured editor after verifying permissions and handling symbolic links. Additionally, the \sudo -l\ (list) command has been improved to display detailed sudoers entries when the verbose flag is used, and it now correctly handles listing permissions for specific commands or other users.

src/sudo/pipeline · high confidence

Initial implementation of sudo-rs core execution and sudoedit support

This change introduces the initial Rust-based implementation of the sudo command-line tool. It adds the core execution pipeline (src/sudo/pipeline.rs) which handles sudoers parsing, authentication via PAM (src/sudo/pam.rs), and command execution. It also implements the sudoedit functionality (src/sudo/edit.rs) for securely editing files as another user, including file locking and temporary file handling. Additionally, it adds a diagnostic module (src/sudo/diagnostic.rs) for improved error reporting with source file citations and a main entry point (src/sudo/mod.rs) that manages CLI actions like run, validate, list, and edit.

src/sudo · high confidence

Introduce Rust-based visudo implementation with CLI and validation

This change adds a new Rust implementation of the visudo utility (src/visudo), providing a command-line interface that supports the -c/--check, -f/--file, -O/--owner, and -P/--perms flags. The tool validates sudoers file syntax, permissions (mode 0440), and ownership (root:root), and can create new sudoers files with appropriate defaults if they do not exist. It also enforces that visudo is not run as a setuid binary for security.

src/visudo · high confidence

Introduce \`su\` command implementation

This change adds the \su\ (substitute user) command to the product, providing a new capability to switch user identities. The implementation includes CLI parsing for options such as \-l\ (login shell), \-c\ (command), \-s\ (shell), \-g\/\-G\ (groups), and environment preservation flags (\-p\, \-w\). It handles PAM authentication, environment variable management (including whitelisting and login shell resets), and shell validation against \/etc/shells\. The module also supports restricted shell warnings and proper exit codes for command not found or invalid command scenarios.

src/su · high confidence

Introduce safe terminal and file descriptor utilities in cutils

The new \src/cutils\ module provides a set of low-level utilities for handling C strings and file descriptors, including \string\_from\_ptr\ and \os\_string\_from\_ptr\ for safe conversion from C pointers, and \cerr\ for wrapping libc error codes. Crucially, it replaces the standard library's \IsTerminal\ with a custom \safe\_isatty\ implementation that first checks if a file descriptor is a character device before calling \isatty\, preventing potentially unsafe IOCTL calls on user-controlled file descriptors. It also adds \is\_fifo\_or\_sock\ to detect pipes and sockets, and \dynamic\_fill\ for resizing buffers based on libc calls.

src/cutils · high confidence

New execution engine with background mode, umask control, and Linux NOEXEC support

The \src/exec\ module has been rewritten to introduce several new capabilities and behavioral changes. Users can now run commands in the background using the \--background\ flag, which forks the process and exits the parent immediately. The execution environment now supports configurable umask policies (preserve, extend, or override) via the \Umask\ enum, allowing administrators to enforce stricter file permission defaults. On Linux systems, the \noexec\ feature is implemented using a seccomp BPF filter and \seccomp\_unotify\ to prevent the executed command from spawning further processes, enhancing security. The new event-driven architecture also improves signal handling and terminal management, including support for suspending and continuing processes without a PTY.

src/exec · high confidence

New release automation and build utilities

The util directory now includes a suite of scripts to streamline the release process. build-release.sh automates the creation of reproducible, signed tarballs for sudo and su using a pinned Docker builder image (rust:1.85-slim-bookworm) and explicit file permissions. update-version.sh synchronizes version numbers across Cargo.toml, README.md, and man pages while validating changelog dates and license years. Supporting tools include generate-docs.sh for converting Markdown to man pages, make-pot.sh for extracting translation strings, gh-credits.sh for generating release contributor lists, and get-pam-variant.bash for detecting the PAM implementation.

util · high confidence

New test framework APIs for spawning and controlling commands in Docker containers

The test framework now provides a \Command\ builder and \Child\/\Output\ types to execute commands within Docker containers during tests. Users can specify the user or user ID to run as, provide stdin input, and allocate a pseudo-TTY. The framework captures stdout and stderr, offering assertion helpers like \assert\_success\, \assert\_exit\_code\, and \assert\_signal\ to validate command outcomes, with improved error reporting that includes output on failure.

test-framework/sudo-test/src/docker · high confidence

Behavioural changes

Added compile-time format specifier validation for translation macros

The \gettext\ module now includes a new \check.rs\ module that validates translation strings at compile time. When using the \xlat!\ macro, the system ensures that named placeholders (e.g., \{foo}\) in the format string exactly match the provided arguments, preventing runtime errors from mismatched keys. This adds a safety layer to internationalization by catching format specifier mismatches during compilation rather than at execution.

src/gettext · high confidence

Complete rewrite of the sudoers parser and policy engine

The sudoers module has been completely rewritten from scratch, replacing the previous implementation with a new type-driven, recursive-descent parser. This change introduces a new Abstract Syntax Tree (AST) structure (\ast.rs\) and a robust parsing framework (\basic\_parser.rs\, \char\_stream.rs\) that improves error reporting with precise line/column spans. The new engine supports a wider range of sudoers features, including remote sudoers rules (behind the \unstable-remote-sudoers\ feature flag), AppArmor profile enforcement, \NOEXEC\/\SETENV\ tags, \runcwd\ defaults, and umask handling. It also enhances security and usability by allowing non-Western characters in usernames, supporting line continuations, and providing more consistent, user-friendly syntax error messages.

src/sudoers · high confidence

Enforcement of AppArmor security profiles and stricter output handling

The application now enforces AppArmor security profiles on the next exec call when the feature is enabled, dynamically loading the AppArmor library to switch profiles rather than failing if the system lacks support. Additionally, standard print macros are replaced with non-panicking write alternatives in debug builds to prevent crashes on I/O errors, ensuring more robust error handling during execution.

src · high confidence

Implement sudo environment variable handling and filtering

The sudo command now correctly constructs and filters the target environment when executing commands. This includes setting standard sudo variables (SUDO\_COMMAND, SUDO\_UID, SUDO\_GID, SUDO\_USER, SUDO\_HOME), managing HOME, SHELL, LOGNAME, and USER based on the target user and launch type, and applying secure\_path and default PATH/TERM values. It also enforces sudoers policies for env\_keep and env\_check, including specific safety checks for the TZ variable to prevent path traversal or unsafe characters, and filters out potentially dangerous environment variables like those starting with '()'.

src/sudo/env · high confidence

Introduces new system abstraction layer with secure privilege handling and process management

The \src/system\ module has been restructured to provide a safer, more robust foundation for system interactions. It introduces newtype wrappers for \UserId\, \GroupId\, and \ProcessId\ to prevent type confusion, and implements a \sudo\_call\ mechanism in \audit.rs\ that allows temporary privilege escalation with automatic restoration via a guard pattern. The module also adds secure file opening routines (\secure\_open\_sudoers\, \secure\_open\_cookie\_file\) that enforce strict ownership and permission checks, and provides a cross-platform \wait\ interface for child process status monitoring. Additionally, it replaces standard library time types with custom \SystemTime\ and \ProcessCreateTime\ structs backed by \CLOCK\_BOOTTIME\ (Linux) or \CLOCK\_REALTIME\ (FreeBSD) for reliable timestamping.

src/system · high confidence

Introduction of dedicated binary entry points for su, sudo, and visudo

The project now includes explicit main entry points in src/bin for the su, sudo, and visudo commands. These new files delegate execution to the corresponding functions (su\_main, sudo\_main, visudo\_main) within the sudo\_rs library, establishing the standard Cargo binary layout for these tools.

src/bin · high confidence

New CLI help messages and argument parsing for sudoedit and environment variable handling

The sudo CLI now includes dedicated help text for the \sudoedit\ command (via \help\_edit.rs\) alongside the standard \sudo\ help, ensuring users see correct usage information for file editing mode. The argument parser has been updated to correctly handle \--preserve-env\ with specific variable lists and to accept environment variable assignments (e.g., \VAR=value\) directly on the command line, integrating them into the environment passed to the command. Additionally, the CLI now recognizes \sudoedit\ as a valid program name for invoking edit mode.

src/sudo/cli · high confidence

New bidirectional pipe implementation with ring buffer for PTY I/O

The PTY execution subsystem now uses a new \Pipe\ component in \src/exec/use\_pty/pipe\ to manage bidirectional data streaming between the parent process and the child. This change introduces a dedicated \RingBuffer\ (8 KB) to buffer data, allowing the system to handle backpressure by pausing input polling when the buffer is full and resuming it when space is available. The pipe integrates with the event registry to poll file descriptors, ensuring efficient I/O handling without busy-waiting, and includes logic to manage backgrounding the parent process when stdout is a pipe.

_src/exec/use\pty/pipe · high confidence

New defaults configuration system with expanded sudoers options

The \src/defaults\ module has been replaced with a new DSL-based configuration system that defines default values for sudo settings. This change introduces support for several new \Defaults\ options including \rootpw\, \targetpw\, \noexec\, \noninteractive\_auth\, \log\_allowed\, \runcwd\, \apparmor\_profile\, \umask\, \umask\_override\, \env\_editor\, and \setenv\. It also updates existing defaults such as enabling \pwfeedback\ by default, setting \use\_pty\ to true, and defining a platform-specific \editor\ default (using \/usr/bin/editor:/usr/bin/nano:/usr/bin/vi\ on Linux). The system now supports parsing fractional minutes for \passwd\_timeout\ and \timestamp\_timeout\, and includes a comprehensive list of environment variables for \env\_keep\, \env\_check\, and \env\_delete\.

src/defaults · high confidence

Refactored common module with newtypes and binary serialization

The common module has been restructured to improve type safety and security. Newtypes \SudoPath\ and \SudoString\ now enforce UTF-8 encoding and reject interior null bytes, replacing previous \PathBuf\ and \String\ usage in critical paths. A new \bin\_serde\ module provides binary serialization over Unix pipes for inter-process communication. Command resolution logic has been consolidated into \CommandAndArguments\, which handles path canonicalization and argument escaping. The \Context\ struct has been simplified to build directly from options, and hardened enum values have been introduced to mitigate Rowhammer attacks.

src/common · high confidence

Refactored signal handling with per-signal handlers and streaming support

The signal handling subsystem has been restructured to use individual handlers for each signal rather than a single global handler. This change introduces a \SignalStream\ singleton that allows signal information to be streamed to consumers via a Unix socket pair, enabling more granular signal processing. The refactoring also includes improved safety by using \BorrowedFd\ instead of \RawFd\, masking SIGINT and SIGQUIT during PAM authentication, and ensuring proper restoration of original signal actions upon handler drop.

src/system/signal · high confidence

Refactored terminal handling with new PTY and TTY discovery logic

The terminal subsystem has been restructured to improve safety and cross-platform compatibility. A new \Pty\ type manages pseudoterminals, exposing leader and follower sides for process I/O. TTY discovery now probes all standard I/O file descriptors to identify the controlling terminal, replacing previous single-source logic. The \Terminal\ trait introduces \is\_terminal\_for\_pgrp\ to verify terminal ownership relative to process groups, and \SafeTty\ ensures ioctls are only called on verified TTYs. Additionally, \tcsetattr\ operations now handle background process groups by catching \SIGTTOU\, allowing terminal settings to be applied even when the process is not in the foreground.

src/system/term · high confidence

Refactored test framework to use Docker containers for cross-platform isolation

The test framework has been rewritten to execute tests inside isolated Docker (or Podman on FreeBSD) containers rather than on the host system. This change introduces platform-specific constants for paths such as the sudoers file, binaries, and PAM configuration to handle differences between Linux and FreeBSD. The framework now provides APIs to manage container lifecycles, copy files, and execute commands within these environments, ensuring consistent test behavior across operating systems.

test-framework/sudo-test/src · high confidence

Replaced signal-based IPC with binary-serialized backchannel for monitor-parent communication

The \use\_pty\ module now uses a dedicated binary-serialized socket (backchannel) to communicate between the parent process and the PTY monitor, replacing previous signal-based or less structured IPC mechanisms. This change introduces a \BackchannelPair\ that sends structured messages (such as command status, PIDs, and I/O errors) using a custom serialization format, improving reliability and clarity in process lifecycle management. The monitor and parent processes now exchange typed messages (e.g., \CommandStatus::Exit\, \CommandPid\) over this channel, enabling more robust handling of command termination, suspension, and error reporting without relying on signal semantics for control flow.

_src/exec/use\pty · high confidence

Replaces external logging dependencies with a custom internal logging implementation

The logging subsystem has been rewritten to remove dependencies on the \log\ and \env\_logger\ crates, replacing them with a custom \SudoLogger\ architecture. This new implementation supports three distinct output sinks: authentication logs (via syslog), user-facing messages (to stderr), and development logs (to a file, enabled via the \dev\ feature). The dev logger now includes source location information (file and line number) for easier debugging. Additionally, the syslog writer has been optimized to handle message truncation safely, ensuring UTF-8 character boundaries are respected and preventing interleaving or panics during log writes.

src/log · high confidence

Rewritten PAM authentication module with askpass and secure memory support

The PAM authentication layer has been completely rewritten to improve security, portability, and user experience. The new implementation introduces an askpass mechanism that spawns an external program to handle password prompts, allowing for graphical or alternative authentication interfaces. It also features secure memory management for sensitive data like passwords, ensuring they are wiped from memory after use. The module now supports configurable password feedback (showing characters as they are typed), password timeouts, and a bell signal on input errors. Additionally, it handles signal masking during authentication to prevent interruptions and provides more detailed error messages for better debugging and user feedback.

src/pam · high confidence

visudo editor selection and fallback behavior

The visudo command now respects the \Defaults editor\ configuration and environment variables (\SUDO\_EDITOR\, \VISUAL\, \EDITOR\) to determine which editor to launch, with \SUDO\_EDITOR\ taking precedence over \VISUAL\, which takes precedence over \EDITOR\. If the \env\_editor\ default is disabled, environment variables are ignored. The command supports fallback lists for editors (e.g., \Defaults editor=/bad:/good\) and validates that editors are specified by absolute path. It also handles cases where the configured editor is not executable or does not exist, falling back to other options in the list or reporting an error if no usable editor is found.

test-framework/sudo-compliance-tests/src/visudo/sudoers · high confidence

Test coverage

Added FreeBSD CI via Cirrus CI; Added compliance tests for PAM environment variable handling; Added compliance tests for sudo --list behavior; Added compliance tests for sudo --list long format output; Added compliance tests for sudo --list short format; Added compliance tests for sudo password authentication methods; Added compliance tests for sudoedit security and permission checks; Added compliance tests for sudoers env\_keep and env\_check directives; Added comprehensive test suite for sudoers parsing and authorization logic; Added end-to-end tests for su signal handling; Added signal handling compliance tests for child processes; Added snapshot tests for sudo --list long format output; Added snapshot tests for sudo --list short format; Added test scripts for file descriptor access and password retry timing; Added tests for su --pty process and terminal behavior; Compliance test suite for sudo, su, sudoedit, and visudo; Expanded compliance test coverage for su command behavior; Expanded compliance test coverage for sudo CLI, environment, and flags; Expanded compliance test coverage for sudoers configuration; Expanded compliance test coverage for visudo flags and behaviors; Expanded end-to-end test coverage for sudo and su behavior; Updated compliance test snapshots for sudo and visudo.

Dependencies

Initial dependency manifest and lockfile setup for sudo-rs and test framework

The project now includes Cargo.toml and Cargo.lock files for the main sudo-rs crate and the test-framework workspace, establishing the initial dependency graph. The main crate depends on libc (0.2.176) and glob (0.3.0), while the test framework utilizes libraries such as insta, pretty\_assertions, tar, and tempfile. This change formalizes the build configuration and ensures reproducible builds through the committed lockfiles.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 70 → 70 (+0.0)
  • Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.

Lenses

  • Code Health 91 → 91 (-0.1)
  • Architecture 99 → 95 (-4.3)
  • Maturity 59 → 59 (-0.0)
  • Readiness 71 → 72 (+1.0)
  • Security 80 → 85 (+5.0)

Resolved (6)

  • Documentation: no installation or build instructions (README.md)
  • Documentation: no usage examples (README.md)
  • Hotspot: src/pam/rpassword.rs (src/pam/rpassword.rs)
  • Hotspot: src/sudoers/ast.rs (src/sudoers/ast.rs)
  • Off-boarding risk: anonymized user #1
  • Off-boarding risk: anonymized user #2

New (8)

  • Dependency hygiene PARTLY measured — Cargo dependencies read, dependency currency not (crates.io unreachable)
  • Documentation: no licence statement (README.md)
  • Low cohesion: Command (LCOM4 4) (test-framework/sudo-test/src/docker/command.rs)
  • Low cohesion: SudoString (LCOM4 4) (src/common/string.rs)
  • Off-boarding risk: anonymized user #2
  • Off-boarding risk: anonymized user #1
  • Projects may be oversized for their cohesion
  • Two top-level factory methods with nearly identical signatures and return types, differing only by a suffix ('NoImplicit'). The semantic distinction is not obvious from the signature alone and requires external documentation to understand.

Changes since last survey

  • 7 commits — 7 feature/other, 0 fixes

By area

  • (repo) — 2 commits
  • test-framework/Cargo.lock — 2 commits
  • .github/workflows — 1 commit
  • docs/man — 1 commit
  • po/ka.po — 1 commit

Notable commits

  • change: Add missing passwd_timeout to documentation (#1689)
  • change: Bump the ci-dependencies group with 4 updates
  • change: Update getrandom dependency for the test framework
  • change: Update most test framework dependencies
  • change: add missing passwd_timeout entry in man sudoers
  • change: po: Add Georgian translation
  • change: po: Add Georgian translation (#1680)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

trifectatechfoundation/sudo-rs was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 30 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 89bae8a26a1a93b378e45a230d2bbf017b6a3565 — the exact code this score is about.
  • Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-cb25ca4feafa.