Skip to content

fix(docker-postgres): use system sg binary with SUID for group switching - #797

Merged
shunkakinoki merged 1 commit into
mainfrom
fix/docker-postgres-suid-sg
Feb 13, 2026
Merged

fix(docker-postgres): use system sg binary with SUID for group switching#797
shunkakinoki merged 1 commit into
mainfrom
fix/docker-postgres-suid-sg

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented Feb 13, 2026

Copy link
Copy Markdown
Owner

Changes

Use a smart wrapper script for docker group switching that works on both NixOS and non-NixOS Linux:

  • docker-postgres: Updated wrapper for PostgreSQL container service
  • cliproxyapi: Updated wrapper for CLI Proxy API service

Technical Details

The wrapper tries in order:

  1. Docker directly - works on NixOS or when user session has docker group
  2. /run/wrappers/bin/sg - NixOS SUID wrapper (if available)
  3. /usr/bin/sg - System binary with SUID (non-NixOS)

This is needed because:

  • The Nix-packaged ${pkgs.shadow}/bin/sg lacks the SUID bit (Nix store can't have setuid binaries)
  • On non-NixOS, the systemd user session may not have the docker group (user added to group after session started)
  • On NixOS, groups are properly inherited OR /run/wrappers/bin/sg is available via security.wrappers

Test plan

  • make build passes
  • docker-postgres service starts successfully
  • cliproxyapi service starts successfully
  • Both services use sg fallback correctly on non-NixOS
  • System reports 0 failed units

Generated with Claude Code by Claude Opus 4.5

Copilot AI review requested due to automatic review settings February 13, 2026 19:59
@shunkakinoki shunkakinoki added the bug Indicates an unexpected problem or unintended behavior. label Feb 13, 2026
@mesa-dot-dev

mesa-dot-dev Bot commented Feb 13, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @shunkakinoki, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves an issue where the docker-postgres systemd user service failed to switch to the docker group due to missing SUID permissions on the Nix-packaged sg binary. The change ensures the service functions correctly by leveraging the system's sg binary, which has the required SUID bit, thereby enabling proper group switching for the PostgreSQL container.

Highlights

  • SG Binary Usage: Switched the startPostgresWrapper script to use the system's /usr/bin/sg binary instead of the Nix-packaged ${pkgs.shadow}/bin/sg.
  • SUID Permissions Fix: Resolved an 'Operation not permitted' error by utilizing the system's sg binary, which possesses the necessary SUID bit, unlike the Nix-packaged version, allowing the service to correctly switch to the 'docker' group.
Changelog
  • home-manager/services/docker-postgres/default.nix
    • Updated the startPostgresWrapper script to use /usr/bin/sg.
    • Added a comment explaining the rationale for using the system sg due to SUID requirements in the systemd user session.
Activity
  • A test plan was provided, confirming the service starts successfully, logs show group switching, and the PostgreSQL container is running and accepting connections.
  • The pull request description indicates it was generated with Claude Code by Claude Opus 4.5.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mesa-dot-dev

mesa-dot-dev Bot commented Feb 13, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Switch docker-postgres to use /usr/bin/sg (with SUID) for group switching. Fixes setgid “Operation not permitted” in the systemd user service so the container starts and runs correctly.

What changed?

  • home-manager/services/docker-postgres/default.nix: The startPostgresWrapper script was updated to explicitly use the system's SUID-enabled /usr/bin/sg command. This change resolves issues where systemd user sessions might lack the docker group, ensuring proper execution by leveraging the system's sg utility instead of the Nixpkgs version.

Description generated by Mesa. Update settings

@coderabbitai

coderabbitai Bot commented Feb 13, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This change modifies the docker-postgres service startup script to use the system's /usr/bin/sg binary instead of the Nix-packaged variant from ${pkgs.shadow}/bin/sg, enabling SUID-based group switching for the docker user with an explanatory comment.

Changes

Cohort / File(s) Summary
Docker Postgres Service Configuration
home-manager/services/docker-postgres/default.nix
Replaces Nix-packaged sg binary with system /usr/bin/sg to leverage SUID capabilities for group switching in the start-postgres wrapper.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • PR #685: Modifies the same docker-postgres service startup logic to use system /usr/bin/sg instead of Nix-packaged sg for group switching.
  • PR #710: Updates the same configuration file to enable group switching functionality by replacing the Nix-packaged sg with the system binary.

Suggested labels

bug

Poem

🐰 A rabbit hops through Nix-built paths,
But SUID magic calls from system baths,
From shadow's sg to /usr/bin so true,
Docker groups now switch with permissions due! 🔧

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: replacing the Nix-packaged sg binary with the system sg binary that has SUID permissions for group switching in docker-postgres.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main
Description check ✅ Passed The pull request description clearly describes the changes made to use system sg binary instead of Nix-packaged sg, with technical rationale and test verification.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/docker-postgres-suid-sg

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request fixes an issue with group permissions when running the docker-postgres service by using the system's sg binary instead of the one from Nix packages. While this is a functional fix, it introduces a hardcoded path to /usr/bin/sg, which is an impurity in the Nix configuration. This can compromise the reproducibility and portability of the module. I've added a review comment with a suggestion to make this dependency more explicit and add a runtime check to improve robustness and provide clearer error messages on systems where this binary might be missing.

# Use system sg (has SUID) since systemd user session lacks docker group
startPostgresWrapper = pkgs.writeShellScript "start-postgres-wrapper" ''
exec ${pkgs.shadow}/bin/sg docker -c "${pkgs.bash}/bin/bash ${./start-postgres.sh}"
exec /usr/bin/sg docker -c "${pkgs.bash}/bin/bash ${./start-postgres.sh}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Hardcoding the path /usr/bin/sg introduces an impurity into the Nix configuration. This makes the setup dependent on the state of the host system and can lead to failures on systems where sg is not present at this location (e.g., some minimal container environments or differently structured distributions). This undermines the reproducibility and portability that Nix aims to provide.

While this is a pragmatic fix for the SUID issue, a more robust approach would be to add a check for the existence of the binary within the wrapper script. This provides a clearer error message if it's missing and makes debugging easier if this module is used on an unsupported system.

    if [ ! -x "/usr/bin/sg" ]; then
      echo "Error: /usr/bin/sg not found or not executable. A 'sg' binary with SUID is required." >&2
      exit 1
    fi
    exec /usr/bin/sg docker -c "${pkgs.bash}/bin/bash ${./start-postgres.sh}"

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a setuid permission issue with the docker-postgres systemd user service. The Nix-packaged sg binary from ${pkgs.shadow} cannot have the SUID bit set (Nix store restriction), causing "setgid: Operation not permitted" errors. The fix switches to the system /usr/bin/sg binary which has proper SUID permissions.

Changes:

  • Replace ${pkgs.shadow}/bin/sg with /usr/bin/sg for group switching in the docker-postgres wrapper script
  • Add explanatory comment about why system sg binary is needed

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

# Use system sg (has SUID) since systemd user session lacks docker group
startPostgresWrapper = pkgs.writeShellScript "start-postgres-wrapper" ''
exec ${pkgs.shadow}/bin/sg docker -c "${pkgs.bash}/bin/bash ${./start-postgres.sh}"
exec /usr/bin/sg docker -c "${pkgs.bash}/bin/bash ${./start-postgres.sh}"

Copilot AI Feb 13, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding /usr/bin/sg without a fallback check could fail on NixOS systems where setuid wrappers are in /run/wrappers/bin/sg. The codebase has an established pattern (seen in tailscale and k3s modules) for handling setuid binaries with fallback checks:

  1. First check /run/wrappers/bin/sg (NixOS convention for setuid wrappers)
  2. Then fall back to /usr/bin/sg (standard Linux)
  3. Optionally use command -v sg as a final fallback

Consider implementing a similar pattern here with proper error handling if none of these locations have the sg binary. This would make the code more robust across different Linux distributions and NixOS vs non-NixOS systems.

Suggested change
exec /usr/bin/sg docker -c "${pkgs.bash}/bin/bash ${./start-postgres.sh}"
# Locate sg with NixOS-aware fallbacks
if [ -x /run/wrappers/bin/sg ]; then
sg_bin=/run/wrappers/bin/sg
elif [ -x /usr/bin/sg ]; then
sg_bin=/usr/bin/sg
elif sg_bin="$(command -v sg 2>/dev/null)"; then
:
else
echo "Error: 'sg' binary not found in /run/wrappers/bin, /usr/bin, or PATH." >&2
exit 1
fi
exec "$sg_bin" docker -c "${pkgs.bash}/bin/bash ${./start-postgres.sh}"

Copilot uses AI. Check for mistakes.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="home-manager/services/docker-postgres/default.nix">

<violation number="1" location="home-manager/services/docker-postgres/default.nix:6">
P2: Hardcoding `/usr/bin/sg` makes the service fail on NixOS or other non-FHS systems where `/usr/bin/sg` is missing. Consider using a configurable wrapper path or a platform-specific sg path instead of a fixed `/usr/bin` dependency.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread home-manager/services/docker-postgres/default.nix Outdated
@shunkakinoki
shunkakinoki force-pushed the fix/docker-postgres-suid-sg branch from d5109b4 to c517d3d Compare February 13, 2026 20:12
…NixOS compatibility

Add smart wrapper that:
1. Tries docker directly first (works on NixOS or when user has docker group)
2. Falls back to /run/wrappers/bin/sg on NixOS (SUID wrapper)
3. Falls back to /usr/bin/sg on non-NixOS (system binary with SUID)

The Nix-packaged sg binary lacks the SUID bit required for setgid/setgroups
operations, so we need to use system binaries with proper permissions.
@shunkakinoki
shunkakinoki merged commit 0e0df77 into main Feb 13, 2026
32 checks passed
@shunkakinoki
shunkakinoki deleted the fix/docker-postgres-suid-sg branch February 13, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Indicates an unexpected problem or unintended behavior.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants