Skip to content

Conversation

samrose
Copy link
Collaborator

@samrose samrose commented Aug 25, 2025

What kind of change does this PR introduce?

  • passes in an arg to use go 1.24 since that is not the default go version we're using in nixpkgs in this flake
  • packages gatekeeper by using the https://flake.parts/ pattern of creating a module with configuration for the package at nix/packages/gatekeeper.nix and then uses the package in nix/packages/default.nix

I will follow up with an explanation as to why we use this flake-parts approach soon.

The fundamental reasons are discussed at https://flake.parts/index.html

@samrose samrose requested review from a team as code owners August 25, 2025 19:31
@steve-chavez
Copy link
Member

packages gatekeeper by using the https://flake.parts/ pattern of creating a module with configuration for the package at nix/packages/gatekeeper.nix and then uses the package in nix/packages/default.nix

@samrose What's the advantage of the above compared to callPackage? Overall looks like the flake way is much more verbose.

@samrose
Copy link
Collaborator Author

samrose commented Aug 26, 2025

packages gatekeeper by using the https://flake.parts/ pattern of creating a module with configuration for the package at nix/packages/gatekeeper.nix and then uses the package in nix/packages/default.nix

@samrose What's the advantage of the above compared to callPackage? Overall looks like the flake way is much more verbose.

@steve-chavez for what it's worth, here are the advantages to using flakes, and the flake-parts framework https://gist.github.com/samrose/a9a19b7fad0aed8fd8355bdf0b87df08

@staaldraad
Copy link
Member

this and #1765 are directly related. I don't feel like merging the two into one version though, as the change in 1765 is pretty significant already.

@samrose
Copy link
Collaborator Author

samrose commented Aug 31, 2025

this and #1765 are directly related. I don't feel like merging the two into one version though, as the change in 1765 is pretty significant already.

@staaldraad I personally support whatever works best for you. I only created this PR to trigger some of the tests and builds and checks that let us know things are working as desired + give a simpler way to see changs. But thought you could either use this PR, or move work as you see fit.

@samrose samrose changed the title Sam/custom pam custom pam Sep 10, 2025
@samrose
Copy link
Collaborator Author

samrose commented Sep 10, 2025

@staaldraad I believe it is the case that you are not yet ready to merge this correct?

@staaldraad
Copy link
Member

@staaldraad I believe it is the case that you are not yet ready to merge this correct?

I'm ready, I've not been available to Shepard it through. And wanted to wait on the PG upgrade PR. 👍🏼

@samrose
Copy link
Collaborator Author

samrose commented Sep 12, 2025

@staaldraad I believe it is the case that you are not yet ready to merge this correct?

I'm ready, I've not been available to Shepard it through. And wanted to wait on the PG upgrade PR. 👍🏼

@staaldraad not trying to be an unreasonable blocker, but checking in as we're being extra careful lately:

Do you think this has been thoroughly tested against latest release in our local infra?

@staaldraad
Copy link
Member

@staaldraad I believe it is the case that you are not yet ready to merge this correct?

I'm ready, I've not been available to Shepard it through. And wanted to wait on the PG upgrade PR. 👍🏼

@staaldraad not trying to be an unreasonable blocker, but checking in as we're being extra careful lately:

Do you think this has been thoroughly tested against latest release in our local infra?

Great call out @samrose fully understood and you aren't being a blocker. It has been tested and it default off, the trigger for enabling it hasn't been enabled yet in the API. We can wait for Monday, I'll give it an extra set of testing

@samrose
Copy link
Collaborator Author

samrose commented Sep 12, 2025

@staaldraad is it true that this package should not be installed on a pg 15 image?

@samrose
Copy link
Collaborator Author

samrose commented Sep 12, 2025

@staaldraad did a rebase on develop since we have launched pg 17.6 and 15.14 since the time you started this work.

@hunleyd hunleyd requested a review from staaldraad September 16, 2025 13:10
@staaldraad
Copy link
Member

@samrose who hits the merge button on this one? 😄

@samrose
Copy link
Collaborator Author

samrose commented Sep 26, 2025

@staaldraad I'll ping a few folks to do one last review, and we can merge on Monday, deploy on Tue

- name: Setup SSH for deploy key
run: |
mkdir -p ~/.ssh
echo "${{ secrets.GK_DEPLOY_KEY }}" > ~/.ssh/id_ed25519
Copy link
Collaborator

Choose a reason for hiding this comment

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

I might miss context here, it is not clear to me why this private key is required and how it is related to this PR. It might be a leftover from that commit 7f2fd90 ?

set_fact:
is_psql_15: "{{ psql_version in ['psql_15'] }}"

- name: create placeholder pam config
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need to create an empty file here ? Is there another process relying on the presence of this file ?

Copy link
Member

Choose a reason for hiding this comment

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

yes, supabase-admin-api expects this file to be read-writeable. it is also the default name Postgres will use to lookup PAM rules when pg_hba lists pam as the login service

Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to declare the package here if the same package is publicly available in https://github.com/supabase/jit-db-gatekeeper/blob/ac9c0ddef7a31f4143674a095e5bd96aee984685/default.nix ?
We could use it as an input to this flake and specify the version we rely on in the flake input parameters.

src = pkgs.fetchFromGitHub {
owner = "supabase";
repo = "jit-db-gatekeeper";
rev = "refs/heads/main";
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would be explicit here about the exact ref (revision or tag) we use.
It would be cool if the tag of the version we use, would be available upstream to rely on it.

buildGoModule = pkgs.buildGoModule.override { go = go124; };
in

buildGoModule {
Copy link
Collaborator

Choose a reason for hiding this comment

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

As jit-db-gatekeeper contains unittest, it might be worth adding a check to run them:

  checkPhase = ''
    runHook preCheck
    go test -v ./...
    runHook postCheck
  '';

try:
pg_major_version = int(result["stdout"].strip())
except ValueError:
pass
Copy link
Collaborator

Choose a reason for hiding this comment

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

We want to know if we cannot parse the postgresql version. We should fail instead of using a default value.

- name: Create symbolic link for linux-pam to find pam_jit_pg.so
become: yes
shell: |
sudo ln -s /var/lib/postgresql/.nix-profile/lib/security/pam_jit_pg.so $(find /nix/store -type d -path "/nix/store/*-linux-pam-*/lib/security" -print -quit)/pam_jit_pg.so
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are we trying to write in the store here ? Did you mean /usr/lib/x86_64-linux-gnu/security/pam_jit_pg.so where all the other pam modules are deployed in distribution like Ubuntu ?

Do we really need to copy that module if we can specify the full module path in the pam configuration (/etc/pam.d/postgresql) ?

auth required /var/lib/postgresql/.nix-profile/lib/security/pam_jwt_pg.so jwks=https://auth.supabase.green/auth/v1/.well-known/jwks.json mappings=/tmp/users.yaml
account required /var/lib/postgresql/.nix-profile/lib/security/pam_jwt_pg.so jwks=https://auth.supabase.green/auth/v1/.well-known/jwks.json mappings=/tmp/users.yaml

Copy link
Member

Choose a reason for hiding this comment

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

did not try with the full path, nice!

Did you mean /usr/lib/x86_64-linux-gnu/security/pam_jit_pg.so

Yes original intention was to use that location, but during testing pam was failing to lookup the module and was looking in the store instead. Full paths would solve this

# Check if the symlink exists in the Linux PAM security directory
result = run_ssh_command(
host["ssh"],
"find /nix/store -type f -path '*/lib/security/pam_jit_pg.so' 2>/dev/null | head -5",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Might be related to a previous comment but this will return the lib in the gatekeeper package like this: /nix/store/miwaglm79i2vpilmp8rxd2mymjs7nibz-gatekeeper-0.1.0/lib/security/pam_jit_pg.so. I guess we want to check that /usr/lib/x86_64-linux-gnu/security/pam_jit_pg.so exists instead ?

# Check if gatekeeper is in the postgres user's Nix profile
result = run_ssh_command(
host["ssh"],
"sudo -u postgres nix profile list 2>/dev/null | grep -i gatekeeper",
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would rather do: nix profile list --json | jq -r '.elements.gatekeeper.storePaths[0]' to find the store path and use that path in the next check (running find on the nix-store can take a while).

print(f"\nJIT PAM module dependencies:\n{result['stdout']}")

# Check for required libraries
required_libs = ["libpam", "libc"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note that these dynamic dependencies/libraries are not coming from Ubuntu but from Nix which could cause problem as Nix and Ubuntu might not use the same PAM version. In the following test, we see that the module is loading PAM 1.6.0 but that version of Ubuntu is using PAM 1.5.3:

$ ldd /var/lib/postgresql/.nix-profile/lib/security/pam_jit_pg.so
        linux-vdso.so.1 (0x00007fffa3338000)
        libpam.so.0 => /nix/store/k491acz8rcfhrpivv0rg6q83a14zss2j-linux-pam-1.6.0/lib/libpam.so.0 (0x00007fe0c901c000)
        libpthread.so.0 => /nix/store/ddwyrxif62r8n6xclvskjyy6szdhvj60-glibc-2.39-5/lib/libpthread.so.0 (0x00007fe0c9017000)
        libresolv.so.2 => /nix/store/ddwyrxif62r8n6xclvskjyy6szdhvj60-glibc-2.39-5/lib/libresolv.so.2 (0x00007fe0c9006000)
        libc.so.6 => /nix/store/ddwyrxif62r8n6xclvskjyy6szdhvj60-glibc-2.39-5/lib/libc.so.6 (0x00007fe0c8613000)
        libaudit.so.1 => /nix/store/0i8hhak73jnlilfgfsh1wh0fd53pb0r9-audit-3.1.2/lib/libaudit.so.1 (0x00007fe0c8fd1000)
$ patchelf --print-rpath /root/.nix-profile/lib/security/pam_jit_pg.so
/nix/store/k491acz8rcfhrpivv0rg6q83a14zss2j-linux-pam-1.6.0/lib:/nix/store/ddwyrxif62r8n6xclvskjyy6szdhvj60-glibc-2.39-5/lib
$ dpkg -l libpam-runtime
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version          Architecture Description
+++-==============-================-============-===================================
ii  libpam-runtime 1.5.3-5ubuntu5.4 all          Runtime support for the PAM library

We can instead remove the rpath and let the dynamic linker do its job (without looking at other nix libraries):

$ cp /var/lib/postgres/.nix-profile/lib/security/pam_jit_pg.so /usr/lib/x86_64-linux-gnu/security/
$ patchelf --remove-rpath /usr/lib/x86_64-linux-gnu/security/pam_jit_pg.so
$ ldd /usr/lib/x86_64-linux-gnu/security/pam_jit_pg.so
        linux-vdso.so.1 (0x00007fff3179e000)
        libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x000078aa645ea000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x000078aa645e5000)
        libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x000078aa645d2000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000078aa63a00000)
        libaudit.so.1 => /lib/x86_64-linux-gnu/libaudit.so.1 (0x000078aa645a4000)
        /lib64/ld-linux-x86-64.so.2 (0x000078aa64602000)
        libcap-ng.so.0 => /lib/x86_64-linux-gnu/libcap-ng.so.0 (0x000078aa6459a000)

We could remove that rpath after the build of the package:

  postFixup = ''
    patchelf --remove-rpath $out/lib/security/pam_jit_pg.so
  '';

But still there might be other surprises as the gatekeeper module has been build based on PAM 1.6.0.
Usually PAM has a good backward compatibility and the amount of dyn symbols used by gatekeeper is rather limited:

$ objdump -T /var/lib/postgres/.nix-profile/lib/security/pam_jit_pg.so | grep PAM
0000000000000000      DF *UND*  0000000000000000 (LIBPAM_1.0) pam_strerror
0000000000000000      DF *UND*  0000000000000000 (LIBPAM_EXTENSION_1.0) pam_syslog
0000000000000000      DF *UND*  0000000000000000 (LIBPAM_1.0) pam_get_item
0000000000000000      DF *UND*  0000000000000000 (LIBPAM_1.0) pam_get_user
0000000000000000      DF *UND*  0000000000000000 (LIBPAM_EXTENSION_1.1) pam_get_authtok

If (and only if) we face issue (I would test if further first), I would build it against the same version using https://lazamar.co.uk/nix-versions/?package=linux-pam&version=1.5.3&fullName=linux-pam-1.5.3&keyName=linux-pam&revision=7a339d87931bba829f68e94621536cad9132971a&channel=nixpkgs-unstable#instructions

We might want to create an automated test that exercice the module using pamtester just to verify that we don't get any dlopen errors in the logs.

Copy link
Member

Choose a reason for hiding this comment

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

we were/are building against 1.6.0 because of postgresql having been built against it (and hence also the hackery of copying the .so to /nix/store/*-linux-pam-*/lib/security because the linker looks for the modules there instead of the default Ubuntu path)

$ patchelf --print-rpath /nix/store/2x79j9fi9j13hhf5n0yc9825qa4nynv3-postgresql-and-plugins-17.6/bin/.postgres-wrapped
/nix/store/bvjhqzpwbzmfi350nir8gf7h45igvp5z-libxml2-2.12.6/lib:/nix/store/wcwqdhl9jpwgj1fdr0pw9dbaf5m43f17-lz4-1.9.4/lib:/nix/store/mxvqrp4jj6zklxc1i32ra8iapnzynyzc-zstd-1.5.5/lib:/nix/store/ram2bh4rs56rp8sr0gcdb108wcc609si-icu4c-73.2/lib:/nix/store/ymav8nb29vsdryddi435xcig3pk7i00q-zlib-1.3.1/lib:/nix/store/0kfbzhd8qdsxsd4qf9dkpcd3f916krvr-openssl-3.0.13/lib:/nix/store/ss6bfrdx69ng9f448d5hq1683hkpxcng-systemd-255.4/lib:/nix/store/vaz0prypndg3y6zxmdcpabinwg9dmmq9-libkrb5-1.21.2/lib:/nix/store/4rdpzzfssknp4k4cn59wc7xcdiyv9j53-linux-pam-1.6.0/lib:/nix/store/10pd749c2v3m35d4hk5xdfylyfr1hzqz-glibc-2.39-5/lib

-->

/nix/store/4rdpzzfssknp4k4cn59wc7xcdiyv9j53-linux-pam-1.6.0/lib

Tried modifying the rpath on postgres-wrapped but that leads to problems looking up libaudit.so.1 (even though it is in the new rpath and when specifying the path manually to the location in the store)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants