greenhouse

kore

my public infrastructure monorepo

git clone [email protected]:kore.git

kore / nixos / roles / git.nix82 lines · 2275B · raw

1{ config, lib, pkgs, ... }:
2
3let
4  inherit (config.kore) identities repos;
5  root = "/srv/git";
6
7  acl = pkgs.writeText "kore-git-acl" (lib.concatLines (lib.concatLists (lib.mapAttrsToList (repo: access:
8    map (id: "${repo} write ${id}") access.write
9    ++ map (id: "${repo} read ${id}") access.read
10  ) repos)));
11
12  kore-git = pkgs.writeShellApplication {
13    name = "kore-git";
14    runtimeInputs = [ pkgs.git pkgs.gnugrep ];
15    text = ''
16      id="$1"
17      cmd="''${SSH_ORIGINAL_COMMAND:-}"
18
19      deny() {
20        echo "kore-git: access denied" >&2
21        exit 1
22      }
23
24      verb="''${cmd%% *}"
25      case "$verb" in
26        git-upload-pack | git-upload-archive) perm="read" ;;
27        git-receive-pack) perm="write" ;;
28        *)
29          echo "kore-git: hi $id, shell access is not provided" >&2
30          exit 1
31          ;;
32      esac
33
34      path="''${cmd#"$verb" }"
35      path="''${path#\'}"
36      path="''${path%\'}"
37      path="''${path#/}"
38      path="''${path%/}"
39      path="''${path%.git}"
40
41      [[ "$path" =~ ^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$ ]] || deny
42
43      grep -qFx "$path write $id" ${acl} \
44        || { [ "$perm" = read ] && grep -qFx "$path read $id" ${acl}; } \
45        || deny
46
47      exec git-shell -c "$verb '${root}/$path.git'"
48    '';
49  };
50
51  members = lib.unique (lib.concatLists (lib.mapAttrsToList (_: access: access.write ++ access.read) repos));
52in {
53  users.groups.git = {};
54  users.users.git = {
55    isSystemUser = true;
56    group = "git";
57    home = root;
58    createHome = true;
59    shell = pkgs.bash;
60
61    openssh.authorizedKeys.keys = lib.concatMap (id:
62      map (key: ''command="${kore-git}/bin/kore-git ${id}",restrict ${key}'') (identities.${id}.sshKeys or [])
63    ) members;
64  };
65
66  systemd.services.kore-git-repos = {
67    wantedBy = [ "multi-user.target" ];
68    after = [ "local-fs.target" ];
69    serviceConfig = {
70      Type = "oneshot";
71      User = "git";
72      Group = "git";
73    };
74    path = [ pkgs.git pkgs.coreutils ];
75    script = lib.concatMapStrings (repo: ''
76      if [ ! -d '${root}/${repo}.git' ]; then
77        mkdir -p "$(dirname '${root}/${repo}.git')"
78        git init --quiet --bare --initial-branch=main '${root}/${repo}.git'
79      fi
80    '') (lib.attrNames repos);
81  };
82}