Subject: [PATCH 1/2] services: guix: Make /etc/guix/acl really declarative by default.

From: Ludovic Courtès <[email-masked]>
Date: Wed, 21 Oct 2020 17:08:22 +0200

Fixes <https://bugs.gnu.org/39819>.
Reported by Maxim Cournoyer <[email-masked]>.

* gnu/services/base.scm (substitute-key-authorization): Symlink
DEFAULT-ACL to /etc/guix/acl unconditionally.  Add code to optionally
back up /etc/guix/acl if it was possibly modified by hand.
* doc/guix.texi (Base Services): Clarify the effect of setting
'authorize-keys?' to true.  Mention the backup.  Give an example showing
how to authorize substitutes from another server.
---
 doc/guix.texi         | 36 ++++++++++++++++++++++++++++++++++++
 gnu/services/base.scm | 16 ++++++++++++----
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index c161012da5..50d2d9a730 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -14571,11 +14571,26 @@ Whether to authorize the substitute keys listed in
 @code{authorized-keys}---by default that of @code{@value{SUBSTITUTE-SERVER}}
 (@pxref{Substitutes}).
 
+When @code{authorize-keys?} is true, @file{/etc/guix/acl} cannot be
+changed by invoking @command{guix archive --authorize}.  You must
+instead adjust @code{guix-configuration} as you wish and reconfigure the
+system.  This ensures that your operating system configuration file is
+self-contained.
+
+@quotation Note
+When booting or reconfiguring to a system where @code{authorize-keys?}
+is true, the existing @file{/etc/guix/acl} file is backed up as
+@file{/etc/guix/acl.bak} if it was determined to be a manually modified
+file.  This is to facilitate migration from earlier versions, which
+allowed for in-place modifications to @file{/etc/guix/acl}.
+@end quotation
+
 @vindex %default-authorized-guix-keys
 @item @code{authorized-keys} (default: @code{%default-authorized-guix-keys})
 The list of authorized key files for archive imports, as a list of
 string-valued gexps (@pxref{Invoking guix archive}).  By default, it
 contains that of @code{@value{SUBSTITUTE-SERVER}} (@pxref{Substitutes}).
+See @code{substitute-urls} below for an example on how to change it.
 
 @item @code{use-substitutes?} (default: @code{#t})
 Whether to use substitutes.
@@ -14583,6 +14598,27 @@ Whether to use substitutes.
 @item @code{substitute-urls} (default: @code{%default-substitute-urls})
 The list of URLs where to look for substitutes by default.
 
+Support you would like to fetch substitutes from @code{guix.example.org}
+in addition to @code{@value{SUBSTITUTE-SERVER}}.  You will need to do
+two things: (1) add @code{guix.example.org} to @code{substitute-urls},
+and (2) authorize its signing key, having done appropriate checks
+(@pxref{Substitute Server Authorization}).  The configuration below does
+exactly that:
+
+@lisp
+(guix-configuration
+  (substitute-urls
+   (append (list "https://guix.example.org")
+           %default-substitute-urls))
+  (authorized-keys
+   (append (list (local-file "./guix.example.org-key.pub"))
+           %default-authorized-guix-keys)))
+@end lisp
+
+This example assumes that the file @file{./guix.example.org-key.pub}
+contains the public key that @code{guix.example.org} uses to sign
+substitutes.
+
 @item @code{max-silent-time} (default: @code{0})
 @itemx @code{timeout} (default: @code{0})
 The number of seconds of silence and the number of seconds of activity,
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 04bc991356..37b0a13ea7 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -1476,10 +1476,18 @@ archive' public keys, with GUIX."
     #~(begin
         (use-modules (guix build utils))
 
-        (unless (file-exists? "/etc/guix/acl")
-          (mkdir-p "/etc/guix")
-          (copy-file #+default-acl "/etc/guix/acl")
-          (chmod "/etc/guix/acl" #o600)))))
+        ;; If the ACL already exists, move it out of the way.  Create a backup
+        ;; if it's a regular file: it's likely that the user manually updated
+        ;; it with 'guix archive --authorize'.
+        (if (file-exists? "/etc/guix/acl")
+            (if (and (symbolic-link? "/etc/guix/acl")
+                     (store-file-name? (readlink "/etc/guix/acl")))
+                (delete-file "/etc/guix/acl")
+                (rename-file "/etc/guix/acl" "/etc/guix/acl.bak"))
+            (mkdir-p "/etc/guix"))
+
+        ;; Installed the declared ACL.
+        (symlink #+default-acl "/etc/guix/acl"))))
 
 (define %default-authorized-guix-keys
   ;; List of authorized substitute keys.
-- 
2.28.0