Skip to content

Releases: atayoez/sentinel

Sentinel 0.14.0

Choose a tag to compare

@atayoez atayoez released this 05 Jul 10:24

Sentinel 0.14.0

An auth-path hardening release: a batch of fail-closed fixes on both the
polkit and terminal paths, a safer uninstaller, and one opt-in feature —
remember_scope = "program" for multi-command tools.

If you remember one thing: several ways a dialog could show one thing and
the policy/remember machinery match another are closed — the "remember"
checkbox, [policy] allow, and polkit identity selection now all
fail closed.

Fixed — polkit path

  • An auth for another identity can no longer be satisfied by a single
    click.
    When the running user's own uid wasn't among the identities
    polkit offered, the agent silently picked the first offered unix-user —
    so one Allow click could satisfy an auth_admin action as root/another
    admin with no credential. It now fails closed: if your uid isn't
    offered, the agent declines and polkit falls back to its password
    prompt. Non-breaking in practice (install.sh makes the logged-in user
    a polkit administrator, so your uid is offered for actions you can
    perform).
  • The confirmation dialog is killed on cancel and bounded by a
    timeout.
    CancelAuthentication no longer orphans the dialog on
    screen, and a wedged helper can't block every future auth by holding
    the agent's serialization guard forever.
  • A CancelAuthentication racing session startup now aborts it
    reliably
    , and a pre-approval left behind by a failed helper hand-off
    is dropped so a later auth can't claim it.

Fixed — terminal path

  • The "remember" checkbox is no longer offered for requests that can
    never be remembered
    (sudo -v, su, shells and other ineligible
    gateways). Previously the dialog showed the checkbox but the tick was
    silently dropped — e.g. topgrade's leading sudo -v cred-cache prompt
    pretended to be rememberable.
  • [policy] allow can no longer be tricked into passwordlessly
    granting a root shell.
    For a bare-elevation request (sudo -i/-s/
    -v, su) the dialog shows the originating tool (e.g. topgrade),
    but policy now matches on a separate policy_exe that is unset for
    those requests — an allow = ["topgrade"] entry no longer matches the
    root shell that tool spawns. Such requests always go to the dialog.
  • sudo -R/--chroot <dir> is parsed correctly. The chroot
    directory was previously mistaken for the elevated command, so the
    dialog showed the wrong program and a deny entry could be evaded.
  • Remember grants are never keyed on the "no audit session"
    sentinel.
    Two sessions that both lack a loginuid/sessionid could
    otherwise collide on one grant; such requests are now never remembered.

Fixed — uninstaller

  • uninstall.sh can no longer delete a distro PAM stack. In the
    state-file-less fallback, a shared PAM stack (polkit-1, sudo,
    sudo-i, su) with no .pre-sentinel.bak backup was removed
    outright — which can lock you out of that service (e.g. no more sudo
    auth). The fallback now restores the backup if present, else strips
    only Sentinel's pam_sentinel.so line, and never deletes the file.

Added

  • remember_scope = "command" | "program" ([general] or per
    service): opt-in granularity for remember grants. The default
    ("command") keeps 0.12's full-command binding; "program" binds a
    grant to the program token only, so multi-command tools (topgrade's
    zypper refresh + zypper dist-upgrade) prompt once per window
    instead of once per distinct command line. Shell/interpreter exclusions
    and session binding are unchanged.

Changed

  • cxx-qt stack bumped to 0.9. No source changes, but cxx-qt-build 0.9
    no longer auto-discovers Qt: building the helper now requires QMAKE
    to point at the system qmake6. CI, install.sh, and
    scripts/release-local.sh set/detect it automatically; for a manual
    build use QMAKE=$(command -v qmake6) cargo build -p sentinel-helper-kde.

Upgrading

  • Reinstall (or upgrade the package) to pick up the fixed
    uninstaller and helper. No config migration; remember_scope is
    opt-in and defaults to the existing behavior.

Sentinel v0.13.0

Choose a tag to compare

@github-actions github-actions released this 28 Jun 07:31

Sentinel 0.13.0

KDE-only. Sentinel now ships a single frontend — the KDE Plasma helper —
and the COSMIC frontend has been removed.

This is a packaging/structure change. The shared authentication backend
(PAM module, polkit agent, privilege-separation broker) is unchanged, and
there is no change to configuration or the auth path.

Removed

  • The COSMIC frontend (sentinel-helper, libcosmic) and its locale
    bundles.
  • The COSMIC root install.sh / uninstall.sh — the KDE installer at
    packaging-kde/install.sh is now the only installer.
  • The sentinel-cosmic Arch/AUR package and the build-cosmic /
    publish-aur-cosmic release jobs.
  • The entire libcosmic dependency tree, along with its deny.toml and
    cargo audit advisory/license carve-outs.

Unchanged

  • The KDE helper (sentinel-helper-kde) and its AUR package
    (sentinel-kde) keep their names — existing users are unaffected.
  • The PAM module, polkit agent, and broker — and all 0.12.0 behavior
    (per-command remember, sudo credential-cache control, the broker, …).

For users

  • KDE users: nothing to do. sentinel-kde continues as before.
  • COSMIC users: sentinel-cosmic is discontinued; its last release is
    0.12.0.

For packagers

  • Build the helper with cargo build -p sentinel-helper-kde; the auth-path
    backend (pam-sentinel, sentinel-polkit-agent, sentinel-broker)
    builds with a bare cargo build.

Sentinel v0.12.0

Choose a tag to compare

@github-actions github-actions released this 27 Jun 21:18

Sentinel 0.12.0

A security-architecture release: the "remember" decision and its grant
store move out of the root PAM module into a sandboxed, unprivileged
broker; the remember window is reworked so every grant is bound to the
exact command; and the root unsafe surface is locked down.

If you remember one thing: a remembered grant now covers only the exact
command you approved — sudo pacman -Syu can never wave through
sudo pacman -U /tmp/evil, and pkexec id never covers pkexec rm.

Highlights

  • Per-command remember, on both the polkit and sudo/su paths. Grants
    are keyed by the whole elevated command, not the program name.
  • Privilege-separation broker. The root PAM module no longer holds any
    grant state; it relays to an unprivileged, in-memory, root-only daemon.
  • sudo's own credential cache is disabled by the installer, so
    Sentinel's per-command window is the single source of truth for sudo.
  • pam-sentinel is now #![deny(unsafe_code)] apart from two
    documented, narrowly-scoped sites.

Remember window

  • Shown by default on the polkit/GUI dialog ([general].remember_seconds
    defaults to 300). The box defaults unchecked — nothing is auto-allowed
    unless you tick it on that prompt. (#22)
  • Grants bind to the full command. This fixes a real bug: the polkit
    path previously keyed grants on (action, exe), command-blind, so one
    ticked pkexec could silently auto-allow any later pkexec command. The
    key is now the whole command on both paths, and pkexec is remembered
    per command like everything else (no blanket carve-out).
  • Per-service window. [services.<name>].remember_seconds is the knob;
    the compiled default is 300 for polkit-1 and 0 for terminal
    services, but the shipped config opts sudo/sudo-i/su into 300.
    Set a service to 0 to require confirmation every time. Unknown
    [services.*] keys are now a hard parse error.
  • Arbitrary-code gateways never qualify (both paths): shells,
    interpreters, and shell-escapers (editors, pagers, find, …) as the
    elevated command, plus bare-elevation root shells (sudo -s/-i/-v,
    su) on the terminal path, always re-prompt.

Privilege-separation broker

Following the pam_sss / OpenSSH-monitor model, the remember decision and
grant store now live in sentinel-broker — a long-lived, unprivileged
daemon (systemd DynamicUser=) that serves only root peers over a Unix
socket (SO_PEERCRED uid-0 gate) and holds grants in memory. There is
no on-disk artifact to forge or roll back, and grants evaporate when the
daemon stops. pam_sentinel relays over a typed, length-bounded postcard
protocol (sentinel-broker-proto), and is fail-closed: an unreachable
broker means "show the dialog", never "let in". The old root
/run/sentinel/ts timestamp store is removed. Both broker crates are
#![forbid(unsafe_code)]; the unit is hardened (seccomp @system-service,
no capabilities, ProtectSystem=strict, AF_UNIX-only).

Hardening

  • Root unsafe surface locked down. pam-sentinel is
    #![deny(unsafe_code)]; hand-rolled extern "C" syscall shims are
    replaced with safe nix wrappers, leaving only fork(2) and post-fork
    set_var behind SAFETY-documented #[allow(unsafe_code)].
  • Fuzz harnesses (cargo-fuzz) for the untrusted inputs that cross
    into the auth path — Verdict::from_str, strip_elevation_prefix,
    format_message, and the broker wire protocol — smoke-fuzzed in CI.

Installer

  • Ships and enables the broker (KDE installer), tearing it down on
    uninstall.
  • Disables sudo's own credential cache. sudo's timestamp_timeout
    (~5 min) let a back-to-back sudo skip the PAM stack entirely, bypassing
    Sentinel. The installer drops a Defaults timestamp_timeout=0 snippet so
    every sudo runs PAM and Sentinel's per-command window is the only
    cache (honored by classic sudo and sudo-rs). Detection covers
    /etc/sudoers, openSUSE's /usr/etc/sudoers, and sudo-rs's
    /etc/sudoers-rs, writing only into a drop-in dir that config actually
    includes (visudo-validated, recorded for uninstall, never a vendor
    dir). Skipped with a warning where there's no safe drop-in (e.g. NixOS);
    --no-sudo opts out.

Upgrading

  • Reinstall to pick up the broker and the updated config. The KDE
    installer's reinstall is in-place and reversible.
  • Terminal sudo/su now remember per command out of the box (shipped
    config). Set [services.<name>].remember_seconds = 0 to keep the strict
    "confirm every time" behavior for a service.
  • sudo's built-in 5-minute grace is turned off so Sentinel is the
    only sudo cache. Remove /etc/sudoers.d/sentinel-timestamp (or
    uninstall) to restore it.
  • polkit's own auth_admin_keep / auth_self_keep caching is unchanged —
    Sentinel does not override it. pkexec does not use keep, so it is
    re-confirmed every time.

Sentinel v0.11.1

Choose a tag to compare

@github-actions github-actions released this 20 Jun 21:44

Sentinel 0.11.1

A packaging hotfix for 0.11.0 — no runtime, configuration, or auth-path
changes.

Fixes

  • sentinel-kde now installs from the AUR. package() installed the
    systemd user service and the polkit admin rule from packaging/ (repo
    root), but after the monorepo merge the KDE-specific assets live under
    packaging-kde/packaging/ — those files don't exist at the root, so
    makepkg failed in package(). All KDE packaging assets are now sourced
    from packaging-kde/packaging/ consistently. (CI builds release tarballs
    but never runs package(), which is why this only surfaced on a real
    install.)

  • Quieted the cxx-qt build output. GCC 16's new -Wsfinae-incomplete
    diagnostic fires inside Qt6's own qchar.h while compiling the generated
    cxx-qt bridge — not our code. It's now suppressed via CXXFLAGS in the
    KDE helper's build.rs.

Packaging hygiene

  • The AUR repositories no longer track release source tarballs (an
    updpkgsums side-effect had been committing them every release); the
    existing ones were removed and a .gitignore added.

Sentinel v0.11.0

Choose a tag to compare

@github-actions github-actions released this 20 Jun 20:55

Sentinel 0.11.0

A packaging-only release — no changes to runtime behaviour, configuration,
or the PAM/polkit auth path. It fixes the AUR build and stops the KDE
package from compiling the COSMIC GUI stack it never uses.

Fixes

  • AUR build was broken — the KDE package() installed config/su, a
    PAM reference doc that was never committed, so sentinel-kde 0.10.0
    failed in package() for everyone. The file is now shipped (it mirrors
    config/sudo).

  • KDE package compiled the entire COSMIC/libcosmic stack — both
    PKGBUILDs selected crates with --workspace --exclude <other-helper>,
    and the KDE check() combined --workspace with -p, where
    --workspace overrode the -p filter and pulled the whole workspace
    (including the libcosmic frontend) into the test build. build() now
    uses explicit per-frontend -p target lists, so each package compiles
    only its own frontend plus the shared backend.

  • Removed the in-package test stepcheck() is gone from both
    PKGBUILDs. cargo fmt/clippy/test already run in CI on every push
    and the AUR publish is gated on a green release, so re-running the test
    suite on every user's machine was redundant build time.

Sentinel v0.10.0

Choose a tag to compare

@github-actions github-actions released this 20 Jun 16:10

Sentinel 0.10.0

Four new opt-in capabilities (all default off — existing configs and
behaviour are unchanged until you turn them on), plus a packaging fix.

What's new

  • Policy allow/deny lists ([policy]) — auto-allow or auto-deny a
    request before the dialog, matched on the requesting program's
    resolved executable path (/proc/<pid>/exe — never the spoofable
    argv[0]), its basename, or the polkit action id. deny wins over
    allow. An allow entry is passwordless elevation, so treat it like a
    sudoers NOPASSWD line.

  • "Remember" checkbox ([general].remember_seconds) — set a non-zero
    window and the dialog grows a "Remember for N min" checkbox. Tick
    it and Allow, and repeat requests from the same login session for
    the same service + binary skip the dialog until the window lapses —
    opt-in per request, not a silent global. Grants are bound to your
    loginuid + kernel audit sessionid, use a boot-time clock
    (rollback-proof), live in a root-owned /run/sentinel/ts store for
    sudo/su (and an in-memory agent cache for polkit), never survive a
    reboot, and are hard-capped at 900 s. Both the KDE and COSMIC dialogs
    render the checkbox.

  • Desktop notifications ([notifications])on_deny / on_timeout
    post a notify-send notification on the polkit/GUI path, including the
    silent [policy] denials where no dialog appears. Terminal sudo/su
    denials are already visible in the terminal, so they're out of scope.

  • Full KDE-helper localization — the Plasma helper now localizes its
    UI chrome across all 12 locales (en, de, es, fr, it, ja, nl, pl, pt,
    ru, tr, zh), matching the COSMIC helper.

Fixes

  • packaging-kde/install.sh now works from a source checkout
    (pkexec ./packaging-kde/install.sh); it had resolved target/ and
    the shared config/ relative to the wrong directory after the
    monorepo move.

See the configuration reference
for the new [policy], [notifications], and remember_seconds keys.

Install

Arch (AUR)

paru -S sentinel-kde       # KDE Plasma
paru -S sentinel-cosmic    # COSMIC

From source

git clone https://github.com/atayozcan/sentinel.git
cd sentinel
pkexec ./install.sh                 # COSMIC frontend
pkexec ./packaging-kde/install.sh   # KDE Plasma frontend

Prebuilt bundle

Download sentinel-0.10.0-<arch>-linux.tar.gz (COSMIC) or
sentinel-kde-0.10.0-<arch>-linux.tar.gz (KDE), extract, then:

sudo SENTINEL_SKIP_BUILD=1 ./install.sh

Sentinel v0.9.0

Choose a tag to compare

@github-actions github-actions released this 20 Jun 10:31

Sentinel 0.9.0

Monorepo release. sentinel-kde and sentinel-cosmic are now one
project — both frontends share a single backend. This is the first release
cut from the unified sentinel repository.

What changed

  • One shared backend. The PAM module (pam-sentinel), the polkit agent
    (sentinel-polkit-agent), and the shared library (sentinel-shared) are
    now a single source of truth, built once and used by both frontends.
    No more mirroring fixes across two repos.
  • Two frontends, one tag. sentinel-helper (COSMIC / libcosmic) and
    sentinel-helper-kde (Plasma / Kirigami) are released together at the
    same version.
  • COSMIC now uses the D-Bus bypass. The agent's pre-approval channel is
    the system D-Bus (org.sentinel.Agent), replacing COSMIC's old unix
    socket. The socket path was blocked by SELinux (policykit_t may
    dbus send_msg but not write an arbitrary socket), so this fixes the
    bypass on SELinux systems
    (e.g. openSUSE Tumbleweed). The COSMIC package
    now ships the org.sentinel.Agent.conf system-bus policy.

Install

Arch (AUR)

paru -S sentinel-kde       # KDE Plasma
paru -S sentinel-cosmic    # COSMIC

From source (any distro)

git clone https://github.com/atayozcan/sentinel.git
cd sentinel
sudo ./install.sh            # COSMIC frontend
# or the KDE frontend:
sudo ./packaging-kde/install.sh

From the binary bundle

Download the bundle for your desktop + arch
(sentinel-0.9.0-<arch>-linux.tar.gz for COSMIC,
sentinel-kde-0.9.0-<arch>-linux.tar.gz for KDE), extract, then:

sudo SENTINEL_SKIP_BUILD=1 ./install.sh

No Rust toolchain needed.

Sentinel-COSMIC v0.8.1

Choose a tag to compare

@github-actions github-actions released this 20 Jun 05:47

Sentinel-COSMIC 0.8.1

Maintenance release. No behavioural changes — dependency refresh and CI
housekeeping since 0.8.0. Drop-in upgrade: same PAM stack, same services,
same dialog.

Changes

  • Dependency updates (via Dependabot): pam-bindings 0.1 → 0.3, log
    0.4.x refresh, and assorted patch/minor crate bumps.
  • CI / GitHub Actions bumped to current major versions
    (attest-build-provenance, configure-pages, deploy-pages,
    upload-pages-artifact).
  • CI fixes: mold added to the agent-integration job's install set;
    REUSE lint brought back to 100% compliant.

Install

Arch (AUR)

paru -S sentinel-cosmic       # stable
paru -S sentinel-cosmic-git   # main HEAD

From source (any distro)

git clone https://github.com/atayozcan/sentinel-cosmic.git
cd sentinel-cosmic
sudo ./install.sh          # transactional; rolls back on error

From the binary bundle

Download sentinel-0.8.1-<arch>-linux.tar.gz, extract, then:

sudo SENTINEL_SKIP_BUILD=1 ./install.sh

No Rust toolchain needed.

Sentinel v0.8.0

Choose a tag to compare

@github-actions github-actions released this 04 May 05:06

Build-pipeline maintenance: smaller binaries, faster CI

A maintenance release focused entirely on the build pipeline. No
behaviour or config changes for end users — existing
/etc/security/sentinel.conf and /etc/pam.d/polkit-1 keep working
unchanged.

What changed

Fat LTO across the workspace

[profile.release] switched from lto = "thin" to "fat". Measured
against the v0.7.0 baseline:

binary v0.7.0 v0.8.0 delta
pam_sentinel.so 756 KB 720 KB −4.8%
sentinel-polkit-agent 3.13 MB 2.94 MB −6.1%
sentinel-helper 13.99 MB 12.68 MB −9.3%
total (workspace) 17.84 MB 16.31 MB −8.6%

Adds roughly 5 minutes to release-build wall time (consumed by CI on
tag push). codegen-units stays at 1 so fat LTO has the full graph
to work with.

AUR baseline: x86-64-v3

The Arch package now compiles with -C target-cpu=x86-64-v3
(Haswell / Zen 1+ — AVX2, BMI1/2, FMA, F16C). Aligns with how
ALHP / CachyOS distribute microarch-tuned binaries. Size impact is
roughly neutral (the helper grows ~1.4% from wider SIMD lanes; the
smaller bins shrink ~1%); the lever here is potential runtime perf
on AVX2 paths in fluent-bundle / clap / zbus parsing.

The portable .deb / .rpm / source-tarball builds are unchanged —
they still target the x86-64 baseline. Pre-Haswell users (~2013
CPUs) would SIGILL on the AUR package; in 2026 that's a vanishing
slice of users running a modern Wayland compositor. If you're
affected, install from .deb / .rpm or build from source.

CI: mold linker

Both ci.yml and release.yml install mold and use it via
RUSTFLAGS=-C link-arg=-fuse-ld=mold at the workflow level. Doesn't
affect the produced binary beyond build-id; trims wall-clock off the
link step. First CI run after this lands will redo the
Swatinem/rust-cache@v2 cache (RUSTFLAGS change invalidates cache
keys); subsequent runs cache normally.

Honest tokio cleanup

crates/sentinel-polkit-agent/Cargo.toml no longer declares the
rt-multi-thread tokio feature: main.rs builds the runtime via
Builder::new_current_thread(), so the multi-thread scheduler was
dead code in the agent's own dependency graph.

Workspace feature unification (libcosmic via the helper still pulls
in rt-multi-thread) means the shipped binary doesn't shrink today
in --workspace builds — but the agent's manifest now expresses
exactly what the binary needs. Becomes a free size win the day
libcosmic's tokio surface changes.

Verify

# Compare binary sizes against v0.7.0:
gh release download v0.7.0 -p '*x86_64-linux.tar.gz' -D /tmp/v07
gh release download v0.8.0 -p '*x86_64-linux.tar.gz' -D /tmp/v08
ls -l /tmp/v0{7,8}/sentinel-*/usr/lib/sentinel-*

# Verify a v0.8.0 attestation:
gh attestation verify sentinel_0.8.0-1_amd64.deb \
    --repo atayozcan/sentinel

Skipped from the optimisation sweep (with rationale)

  • PGO / BOLT: sentinel-helper runs for ~10 seconds per
    invocation; instrumentation overhead exceeds steady-state gains
    for that lifetime.
  • opt-level = "z"/"s" on the helper: would trade startup
    latency for size; the helper is an interactive auth dialog where
    startup matters more than disk footprint.
  • sccache in CI: pairing it with Swatinem/rust-cache@v2
    doubles the caching layer for marginal gain, and cargo install sccache adds ~3 minutes per cold CI run, eating the speedup.
    sccache is recommended as a local-dev tool instead.
  • x86-64-v4 (AVX-512): the project does no SIMD-heavy work,
    and the helper's bottleneck is GPU-side rendering via wgpu — v4
    would shrink hardware compatibility (Zen 3 has no AVX-512)
    without measurable perf benefit.

Docs

https://atayozcan.github.io/sentinel/

Sentinel v0.7.0

Choose a tag to compare

@github-actions github-actions released this 03 May 23:36

Bigger release: dialog UX, supply-chain integrity, docs site

A substantial follow-up to v0.6.1: one user-discovered bug fix
(topgrade / paru showed sudo-rs instead of the originator), plus
seven items from a comparison sweep against Soteria, hyprpolkitagent,
cosmic-osd, polkit-kde-agent-1, lxqt-policykit, mate-polkit, and
agama. No config-format changes, no PAM stack changes — your
existing /etc/security/sentinel.conf and /etc/pam.d/polkit-1
keep working.

What changed

Dialog process names — final piece

v0.6.1 fixed sudo true (showed sudo-rs) and gparted (showed
bash). v0.7.0 closes the last common case:

  • sudo -v (cred-cache, used by topgrade / paru /
    aurutils)
    has no command after the wrapper, so
    strip_elevation_prefix returned empty and the dialog fell back
    to sudo-rs. The PAM module now walks up to PPid in that case
    and shows the user-facing originator (paru, topgrade, your
    shell) in the dialog and audit log.

    Verified with event=auth.allow ... process=paru after running
    topgrade.

Supply-chain: Sigstore artifact attestations

Every release artifact (deb, rpm, tarball, both arches) is now
accompanied by a Sigstore-signed attestation binding its sha256 to
the release.yml workflow run that produced it. Verify locally:

gh attestation verify sentinel_0.7.0-1_amd64.deb \
    --repo atayozcan/sentinel

Downstream packagers (AUR prepare() hooks, Debian / Fedora build
farms) can run this same command in their build pipeline. The
threat-model section of SECURITY.md documents what this guarantees.

Threat model written down

SECURITY.md now has an explicit Threat Model section: the two
trust boundaries (PAM module + per-user agent), what each one
trusts, what each will refuse, and why we deliberately don't ship
a systemd --user unit (would lose the compositor's sessionid).
Also notes the 2026 polkit-agent-helper-1 SUID-stripping that
Arch and Debian are rolling out — Sentinel's design isn't affected.

Docs site at https://atayozcan.github.io/sentinel/

The wiki content has been migrated into docs/ (mdBook), built and
deployed by .github/workflows/docs.yml to GitHub Pages. New
benefits:

  • PR-reviewable docs (the wiki couldn't take PRs).
  • Versioned with the code.
  • Searchable.
  • Edit-on-GitHub link on every page.

The old wiki is preserved as historical reference until v1.0.

REUSE / SPDX compliance

Every file in the repo carries an SPDX license header (or is mapped
by the new REUSE.toml). A reuse CI job enforces this on every
PR. New [![REUSE compliant]](https://api.reuse.software/info/github.com/atayozcan/sentinel)
badge in README; helps Debian / Fedora legal review and prevents
license drift as contributors add files.

OpenSSF Scorecard

New .github/workflows/scorecard.yml runs the OpenSSF Scorecard
weekly + on push, publishes results to scorecard.dev, and lands the
SARIF in the repo's Security tab. Badge in README. Sentinel was
already passing most of the checks (cargo-audit / cargo-deny,
dependabot, signed releases, branch protection); the badge just
makes the security posture legible.

Compositor compatibility issue template

New .github/ISSUE_TEMPLATE/compositor_compat.yml — structured
report form so users can contribute to the README compatibility
table directly. Dropdowns for compositor / result, fields for
distro / version / XDG_CURRENT_DESKTOP. Both "worked" and
"didn't work" reports are useful.

Agent integration test

crates/sentinel-polkit-agent/tests/agent_flow.rs drives the
session state machine (Allow / Deny / Timeout / cancel-drain)
end-to-end with mock helper + mock helper-1 via env-var test seams.
The agent crate now also exposes a library target so integration
tests can import session::run directly without spawning the
binary. New CI job agent-integration runs it on every PR.

Test coverage went from 100 → 102 cases. The full
python-dbusmock harness (covers the zbus dispatch + cookie
validation against real polkitd messages) is a v0.8 candidate.

Verify locally

sudo -v
journalctl -t pam_sentinel --since "1 minute ago" --no-pager \
    | grep "event=auth"
# Should show `process=<your shell>` (or `process=topgrade`,
# `process=paru`, etc.) — not `process=sudo-rs`.

# Verify an artifact's attestation:
gh attestation verify sentinel_0.7.0-1_amd64.deb \
    --repo atayozcan/sentinel

Skipped from the comparison sweep (with rationale)

  • zeroize / secrecy for password buffers: N/A — Sentinel is an
    Allow/Deny dialog. No password input handled in-process; pam_unix
    takes over the password prompt when our auth falls through.
  • systemd --user unit: would conflict with the deliberate XDG
    autostart + X-systemd-skip=true design (sessionid mismatch).
    Documented in the new threat-model section.
  • Existing NixOS module: nix/module.nix was already there; no
    change needed.

Wiki

The wiki has been preserved as historical reference. New
contributions go to docs/ in the repo, deploy to
https://atayozcan.github.io/sentinel/.