From 020f1a60491d27a6ab9bd6913989163dbf2a9762 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Wed, 11 Mar 2026 21:42:21 +0100 Subject: [PATCH] Initial guix-sops configuration This allows us to deploy secrets without making them publicly accessible in the store. --- .gitattributes | 1 + guix/.sops.yaml | 10 ++++++++++ guix/README.md | 30 ++++++++++++++++++++++++++++++ guix/machines/turing.scm | 20 ++++++++++++++++++-- guix/resources/age-key | Bin 0 -> 211 bytes guix/secrets.yaml | Bin 0 -> 2968 bytes 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 guix/.sops.yaml create mode 100644 guix/resources/age-key create mode 100644 guix/secrets.yaml diff --git a/.gitattributes b/.gitattributes index 79674dd6..fe992d37 100644 --- a/.gitattributes +++ b/.gitattributes @@ -5,3 +5,4 @@ secret.yaml filter=git-crypt diff=git-crypt secret.yml filter=git-crypt diff=git-crypt ghcr-pull-secrets.yaml filter=git-crypt diff=git-crypt ssh-secrets.yaml filter=git-crypt diff=git-crypt +guix/resources/age-key filter=git-crypt diff=git-crypt diff --git a/guix/.sops.yaml b/guix/.sops.yaml new file mode 100644 index 00000000..97b287c7 --- /dev/null +++ b/guix/.sops.yaml @@ -0,0 +1,10 @@ +keys: + - &user_pydis age1knt932vn0rgunzh9zzjs8cf7yjdx233gy2dt3w3uzm3apkp3g3qsralf2e + - &host_turing age1gtw67lnhtcxnut3dl2keqm684zxy27cydc42xj5fazaq56uclvrslf6vta + +creation_rules: + - path_regex: .*secrets\.yaml$ + key_groups: + - age: + - *user_pydis + - *host_turing diff --git a/guix/README.md b/guix/README.md index 9f5b1c3b..9f2b706d 100644 --- a/guix/README.md +++ b/guix/README.md @@ -16,9 +16,39 @@ as a playground for ideas. --generate-key` as root. - This is needed for the remote Guix instance to accept packages we build locally. +- `sops-guix` configured as a channel. For this, add: + + ```scheme + (cons* (channel + (name 'sops-guix) + (url "https://github.com/fishinthecalculator/sops-guix.git") + (branch "main") + ;; Enable signature verification: + (introduction + (make-channel-introduction + "0bbaf1fdd25266c7df790f65640aaa01e6d2dbc9" + (openpgp-fingerprint + "8D10 60B9 6BB8 292E 829B 7249 AED4 1CC1 93B7 01E2")))) + %default-channels) + ``` + + to your `~/.config/guix/channels.scm`. After adding it, run `guix pull`. +- [`sops`](https://github.com/getsops/sops) installed locally, along with + [`age`](https://github.com/FiloSottile/age). + + +**Host prerequisites** + +One-time setup for Turing: + +- `sudo age-keygen -o /root/pydis.txt` + +Note down the public key and add it to `.sops.yaml`. **Testing** +It is recommended to test building the image locally first to catch errors. + ```sh # Note that you presently need to run this as root, see # https://codeberg.org/guix/guix/issues/4788 diff --git a/guix/machines/turing.scm b/guix/machines/turing.scm index 2373822a..cd679c5f 100644 --- a/guix/machines/turing.scm +++ b/guix/machines/turing.scm @@ -4,6 +4,7 @@ (use-modules (gnu) (guix) (gnu packages databases) + (gnu packages golang-crypto) (gnu packages linux) (gnu packages tmux) (gnu packages vim) @@ -11,7 +12,9 @@ (gnu services certbot) (gnu services databases) (gnu services networking) - (gnu services web)) + (gnu services web) + (sops secrets) + (sops services sops)) (use-service-modules networking ssh) (use-package-modules bootloaders) @@ -29,6 +32,8 @@ (define %guix-dir (dirname (dirname (canonicalize-path (current-filename))))) +(define %secrets-yaml (local-file (string-append %guix-dir "/secrets.yaml"))) + (define (resource path) (local-file (string-append %guix-dir "/resources/" path))) @@ -119,6 +124,17 @@ ; (uri "/.well-known") ; (body (list "root /var/www; ")))))))))) ; + (service sops-secrets-service-type + (sops-service-configuration + (generate-key? #f) + (secrets + (list + (sops-secret + (key '("good")) + (file %secrets-yaml) + (user "root") + (group "root") + (permissions #o400)))))) (service certbot-service-type (certbot-configuration (email "ops@owlcorp.uk") @@ -171,7 +187,7 @@ (home-directory "/home/j") (supplementary-groups '("wheel" "netdev" "audio" "video"))) %base-user-accounts)) - (packages (cons* %base-packages)) + (packages (cons* age %base-packages)) (sudoers-file (plain-file "sudoers" "root ALL=(ALL) ALL %wheel ALL=NOPASSWD: ALL ")) diff --git a/guix/resources/age-key b/guix/resources/age-key new file mode 100644 index 0000000000000000000000000000000000000000..62ed26537dc76ca2a1542bd7563a7ff17d250e39 GIT binary patch literal 211 zcmV;^04)CiM@dveQdv+`0E8(MrN(@y$mg;`DMrHGRIJw+wMzS3}>L^@@DlkPQW*ormHG7NOdU8 z4r~84ucGEuc|>`oVvO6M7`@D)=i)8UaaFlSfK4@P7#b%jTi{Ynz4NQHIys3IGwJ{+ zwJs2yNtq->Bw<(?6eR}_mt`@inQ_#`m{4VVjXJznXiFZ3qJ(^q3j$svlddwPNy~&? NtMZ8ml!fzyNxcN_U||3N literal 0 HcmV?d00001 diff --git a/guix/secrets.yaml b/guix/secrets.yaml new file mode 100644 index 0000000000000000000000000000000000000000..09c3e401f0b456400e2018b01e201ab6da7b7331 GIT binary patch literal 2968 zcmV;J3up8IM@dveQdv+`0IjAxgl@-z?WSZIjFXAzA zyPNWOWgc^WFIjqhZGQ=O+02jXh!!z!HcsrtySFDnP&cRXAwL6B$#-~SB?*tY{lx)V`&X6@=ne`ec7w2JtT3bL_6gNS0w|JUpyL(x=%8eary_sm`ozTe@xaIa} z?2mJZRxr)937P*$=!AM)buBuR_S|j`l>$7v;X|KfH-eqoS+PyaH#3_UG6+a8C!wYe z`p5^$Lov|tJK&8C8)I^J0R?9%!m5|^Nr1_a2X{}40J5g&<~bxtZo0J+S?P%XJ&Hlr zX`6A8t~#j_LP?31_6Z8~^g1*XnY$irqtmx0anO)*B8wmsk5(L;jD+CqT(z~0;YVgg z4$Pk_#;gFwQFyV!zqdYVSzEtL*p z=Yr=9mCRoCX-XbZrty5gY=8Ex)F+6VVxQlb{gxJyhB9FS743mRP*pXxz)591+VZi4 zG4`~0o!K+|Km?Y+mlXMH(jXAvJs(O{p2a@~F*`aERN?!@k~NFI>aqu^!toXV^*K|x z$Ig$<_?P?$3r8N!( z+W{zQ-dl+xR<@~hppK+3Zqy_Sqi|ckaQQe8ndVJH<6qm~$P8eyRB&jY;dxDX&8J)- z^E%tPdf(JmS!(X4Xi8PvJXo$*#5@Ax{PL62gnN{!K;mMG+3E4BH%vbarXYxRJvyM2 zg=*glO$!Y+D67P6=czMDS}^o-5}GYr_S>wxu+jytH((`B0yC%rrDcVjcfYP&Z*NM* zNZ<-G7FRam_}`hNOIs7~$$3<=IcJ>gr<^Q1%a={dGf2)v?JPr>vuHx1z=|YY0FQP} zXl01Tf3cNG78{We2e<3jocRxo|YAt=BIIBa5)xF&j-^hBGOMWt74p? zHO`B5Q!_b2S6uDl`DypWLzL6(Hms2b;}O_h!Ir@4Zyk!A^b&~!TA$AYm6QLCfFVCB zeIAu(FO0xo%93x=X_yGR*b^Rk+a3mJSyLWfB+2-o401Pl0?}9~6^px$n%gPtl&# z96_6-#rRgl3TqP-DWIdrC4(r+Xkt139JYf!@7MqRVOCT?m`r+SD5+G$46jXJ0*1o<`@l!BB1f8`yGmH{G;L;mwIhECUIETA;EULXHLOh|}wICq= zEEZEomr`#cHD!gsa*EWW0M5v@@Ot8hR*5e^2HZ~N{Fwwr z8^?(~xaky}*Gy0_y~L+yKc|%HgE41Ln<43saBv7z1^qnl!WE?Ue0OWsEyZVhz~VrLqF;E`ca64rK#(}Py!G&LY-A7B@qa7BycIT=VbXc4=h6>Ep7Mwq zj-Gzgx%7=*qXj`gu{7hLC8#S2!yU-{zfaG44(J-UB%TJ>%4%9M^)%8PM4~dtS(3&r z=p&tKe8Ws#kX*K`tB>gr$$Bb&&GI>0wDnkH$2ND8E#*mO1)K@e1dI{p{WxNptdiS= z(n`5_t%X7n1;Bq+i8GLUYK0aH4Hkt2V9UQ&;UWEZa(HRDl7_m5=U&n+AwC9>P_fc? zH6B6Q7r*|xc+%|#oYtB!v0FI>2^oDKr;F@v_#wt&@ao$qth3tb$4NiQ$GLw|YUp@K znnJ8Glykfgfq+_kO$~)%|3lAXAZx$?w9ul0jFWxAw=+GoD?_?)%t*94!@O7`zHj?z zPBj2zZRY%N^SjrHAK^KLm@N7Op_#jF(=Tc7j;NJ_OgXcvZPsmFN>WnNF@oj%foij) zP?zq6q)q<0;{Ca~9c!0gl*OOvR1%x?lfjIe z%@w5Vb-7%O!!V~NKNn0nq|qB_!4SA%%Cf069;>P~y*~0Ox>Uhg#8{1c2b-J6yZ?e~ zXk2ULTXy6m|1Kq=;ft7um%#cY5yI12)v#eq`}5mm07XuC7R#DfXI@>b_pZr0?pH2Y z36HOiz7|B?212jXR!fPuh=Cp{y{Q@g@y&*@bzqhGwgK!PeA=%vI#Ycnto>EH3I5bu z-LR{qOw^X+LVo_eTGfXwtySW(7ep}b9s!4_)U4m%2RPbIl+|JJt_wwNA3!wF)|x1O OzvE1kEOLycdV}`z)x!1w literal 0 HcmV?d00001