unofficial mirror of guix-patches@gnu.org 
 help / color / Atom feed
* [bug#42048] [PATCH 0/6] Authenticated channels for everyone!
@ 2020-06-25 21:04 Ludovic Courtès
  2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
  2020-07-01  9:35 ` [bug#42048] [PATCH 0/6] Authenticated channels for everyone! zimoun
  0 siblings, 2 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-25 21:04 UTC (permalink / raw)
  To: 42048; +Cc: Ludovic Courtès

Hello Guix!

This patch series follows up on channel authentication support:

  https://issues.guix.gnu.org/41767

This time the goal is to expose and document the authentication
mechanism so that third-party channel authors can use it.  This
should be the last series on this theme in the foreseeable
future.  :-)

The most visible effect is that channel introductions are now
part of the API and shown by ‘guix describe’.  It becomes a long-term
commitment because we want to be able to pass the output of
‘guix describe -C channels’ or /run/current-system/channels.scm
to ‘guix pull’ and ‘guix time-machine’ in the future.

Contrary to what I initially proposed¹, channel introductions are
stripped to the bare minimum: a commit/fingerprint pair (as is
currently the case on master, internally).  I figured it doesn’t
buy us much to have the commit/fingerprint pair signed; what
matters is that users obtain the introduction from a trusted
source, and the signature wouldn’t help with that.  I also got
rid of the idea of rendering introductions are opaque base64 blobs.

In the manual I tried to distinguish instructions for users
(“what do I need to put in my channels.scm file?”) from
instructions for channel authors (“how do I allow users of my
channel to authenticate it?”).

If people have a channel that they’d like to make “authenticable”,
please do try and report back!  You can even test with master,
you only need to add ‘@@’ to access (guix channels) internals
to create the introduction.

Feedback welcome!

Thanks,
Ludo’.

¹ https://issues.guix.gnu.org/issue/22883#69



Ludovic Courtès (6):
  channels: Add 'openpgp-fingerprint->bytevector'.
  channels: Make channel introductions public.
  channels: Remove 'signature' from <channel-introduction>.
  channels: Save and interpret 'introduction' field in provenance data.
  guix describe: Display channel introductions and add
    'channels-sans-intro'.
  services: provenance: Save channel introductions.

 doc/guix.texi             | 130 +++++++++++++++++++++++++++++++++++++-
 gnu/services.scm          |  26 ++++++--
 guix/channels.scm         |  86 +++++++++++++++++++------
 guix/scripts/describe.scm |  56 +++++++++++++---
 guix/scripts/system.scm   |   4 +-
 tests/channels.scm        |  10 ++-
 6 files changed, 269 insertions(+), 43 deletions(-)

-- 
2.26.2





^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector'.
  2020-06-25 21:04 [bug#42048] [PATCH 0/6] Authenticated channels for everyone! Ludovic Courtès
@ 2020-06-25 21:16 ` Ludovic Courtès
  2020-06-25 21:16   ` [bug#42048] [PATCH 2/6] channels: Make channel introductions public Ludovic Courtès
                     ` (4 more replies)
  2020-07-01  9:35 ` [bug#42048] [PATCH 0/6] Authenticated channels for everyone! zimoun
  1 sibling, 5 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-25 21:16 UTC (permalink / raw)
  To: 42048; +Cc: Ludovic Courtès

* guix/channels.scm (openpgp-fingerprint->bytevector): New procedure.
(openpgp-fingerprint): New macro.
(%guix-channel-introduction): Use it.
---
 guix/channels.scm | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/guix/channels.scm b/guix/channels.scm
index 3eec5df883..1d4b50aa48 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -71,6 +71,9 @@
             channel-introduction?
             ;; <channel-introduction> accessors purposefully omitted for now.
 
+            openpgp-fingerprint->bytevector
+            openpgp-fingerprint
+
             %default-channels
             guix-channel?
 
@@ -134,6 +137,23 @@
   (first-commit-signer  channel-introduction-first-commit-signer) ;bytevector
   (signature            channel-introduction-signature))          ;string
 
+(define (openpgp-fingerprint->bytevector str)
+  "Convert STR, an OpenPGP fingerprint (hexadecimal string with whitespace),
+to the corresponding bytevector."
+  (base16-string->bytevector
+   (string-downcase (string-filter char-set:hex-digit str))))
+
+(define-syntax openpgp-fingerprint
+  (lambda (s)
+    "Convert STR, an OpenPGP fingerprint (hexadecimal string with whitespace),
+to the corresponding bytevector."
+    (syntax-case s ()
+      ((_ str)
+       (string? (syntax->datum #'str))
+       (openpgp-fingerprint->bytevector (syntax->datum #'str)))
+      ((_ str)
+       #'(openpgp-fingerprint->bytevector str)))))
+
 (define %guix-channel-introduction
   ;; Introduction of the official 'guix channel.  The chosen commit is the
   ;; first one that introduces '.guix-authorizations' on the 'staging'
@@ -142,11 +162,8 @@
   ;; & co.
   (make-channel-introduction
    "9edb3f66fd807b096b48283debdcddccfea34bad"     ;2020-05-26
-   (base16-string->bytevector
-    (string-downcase
-     (string-filter char-set:hex-digit            ;mbakke
-                    "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))
-   #f))                   ;TODO: Add an intro signature so it can be exported.
+   (openpgp-fingerprint                           ;mbakke
+    "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))
 
 (define %default-channel-url
   ;; URL of the default 'guix' channel.
-- 
2.26.2





^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 2/6] channels: Make channel introductions public.
  2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
@ 2020-06-25 21:16   ` Ludovic Courtès
  2020-06-25 22:32     ` Kyle Meyer
  2020-06-25 21:16   ` [bug#42048] [PATCH 3/6] channels: Remove 'signature' from <channel-introduction> Ludovic Courtès
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-25 21:16 UTC (permalink / raw)
  To: 42048; +Cc: Ludovic Courtès

* guix/channels.scm (<channel-introduction>): Rename constructor to
'%make-channel-introduction'.
(make-channel-introduction): New procedure.
* tests/channels.scm ("authenticate-channel, wrong first commit signer")
("authenticate-channel, .guix-authorizations"): Use
'make-channel-introduction' without '@@' and without third argument.
* doc/guix.texi (Channels)[Channel Authentication, Specifying Channel
Authorizations]: New subsections.
---
 doc/guix.texi      | 117 ++++++++++++++++++++++++++++++++++++++++++++-
 guix/channels.scm  |  14 ++++--
 tests/channels.scm |  10 ++--
 3 files changed, 130 insertions(+), 11 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 5b854ccbd4..a4bb52bb24 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -3975,8 +3975,52 @@ deploys Guix itself from the official GNU@tie{}Guix repository.  This can be
 customized by defining @dfn{channels} in the
 @file{~/.config/guix/channels.scm} file.  A channel specifies a URL and branch
 of a Git repository to be deployed, and @command{guix pull} can be instructed
-to pull from one or more channels.  In other words, channels can be used to
-@emph{customize} and to @emph{extend} Guix, as we will see below.
+to pull from one or more channels.  In other words, channels can be used
+to @emph{customize} and to @emph{extend} Guix, as we will see below.
+Before that, some security considerations.
+
+@subsection Channel Authentication
+
+@cindex authentication, of channel code
+The @command{guix pull} and @command{guix time-machine} commands
+@dfn{authenticate} the code retrieved from channels: they make sure each
+commit that is fetched is signed by an authorized developer.  The goal
+is to protect from unauthorized modifications to the channel that would
+lead users to run malicious code.
+
+As a user, you must be @dfn{introduced} to a channel so you can start
+pulling from it and authenticate its code.  The @dfn{channel
+introduction} tells Guix how to authenticate the first commit of that
+channel:
+
+As a user, you must provide a @dfn{channel introduction} in your
+channels file so that Guix knows how to authenticate its first commit.
+A channel specification, including its introduction, looks something
+along these lines:
+
+@lisp
+(channel
+  (name 'my-channel)
+  (url "https://example.org/my-channel.git")
+  (introduction
+   (make-channel-introduction
+    "6f0d8cc0d88abb59c324b2990bfee2876016bb86"
+    (openpgp-fingerprint
+     "CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"))))
+@end lisp
+
+The specification above shows the name and URL of the channel.  The call
+to @code{make-channel-introduction} above specifies that authentication
+of this channel starts at commit @code{6f0d8cc@dots{}}, which is signed
+by the OpenPGP key with fingerprint @code{CABB A931@dots{}}.
+
+For the main channel, called @code{guix}, you automatically get that
+information from your Guix installation.  For other channels, include
+the channel introduction provided by the channel authors in your
+@file{channels.scm} file.  Make sure you retrieve the channel
+introduction from a trusted source since that is the root of your trust.
+
+If you're curious about the authentication mechanics, read on!
 
 @subsection Using a Custom Guix Channel
 
@@ -4150,6 +4194,75 @@ add a meta-data file @file{.guix-channel} that contains:
   (directory "guix"))
 @end lisp
 
+@cindex channel authorizations
+@subsection Specifying Channel Authorizations
+
+As we saw above, Guix ensures the source code it pulls from channels
+comes from authorized developers.  As a channel author, you need to
+specify the list of authorized developers in the
+@file{.guix-authorizations} file in the channel's Git repository.  The
+authentication rule is simple: each commit must be signed by a key
+listed in the @file{.guix-authorizations} file of its parent
+commit(s)@footnote{Git commits form a @dfn{directed acyclic graph}
+(DAG).  Each commit can have zero or more parents; ``regular'' commits
+have one parent and merge commits have two parent commits.  Read
+@uref{https://eagain.net/articles/git-for-computer-scientists/, @i{Git
+for Computer Scientists}} for a great overview.}  The
+@file{.guix-authorizations} file looks like this:
+
+@lisp
+;; Example '.guix-authorizations' file.
+
+(authorizations
+ (version 0)               ;current file format version
+
+ (("AD17 A21E F8AE D8F1 CC02  DBD9 F8AE D8F1 765C 61E3"
+   (name "alice"))
+  ("2A39 3FFF 68F4 EF7A 3D29  12AF 68F4 EF7A 22FB B2D5"
+   (name "bob"))
+  ("CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"
+   (name "charlie"))))
+@end lisp
+
+Each fingerprint is followed by optional key/value pairs, as in the
+example above.  Currently these key/value pairs are ignored.
+
+This authentication rule creates a chicken-and-egg issue: how do we
+authenticate the first commit?  Related to that: how do we deal with
+channels whose repository history contains unsigned commits and lack
+@file{.guix-authorizations}?  And how do we fork existing channels?
+
+@cindex channel introduction
+Channel introductions answer these questions by describing the first
+commit of a channel that should be authenticated.  The first time a
+channel is fetched with @command{guix pull} or @command{guix
+time-machine}, the command looks up the introductory commit and verifies
+that it is signed by the specified OpenPGP key.  From then on, it
+authenticates commits according to the rule above.
+
+To summarize, as the author of a channel, there are two things you have
+to do to allow users to authenticate your code:
+
+@enumerate
+@item
+Introduce an initial @file{.guix-authorizations} in the channel's
+repository.  Do that in a signed commit (@pxref{Commit Access}, for
+information on how to sign Git commits.)
+
+@item
+Advertise the channel introduction, for instance on your channel's web
+page.  The channel introduction, as we saw above, is the commit/key
+pair---i.e., the commit that introduced @file{.guix-authorizations}, and
+the fingerprint of the OpenPGP used to sign it.
+@end enumerate
+
+Publishing a signed channel requires discipline: any mistake, such as an
+unsigned commit or a commit signed by an unauthorized key, will prevent
+users from pulling from your channel---well, that's the whole point of
+authentication!  Pay attention to merges in particular: merge commits
+are considered authentic if and only if they are signed by a key present
+in the @file{.guix-authorizations} file of @emph{both} branches.
+
 @cindex primary URL, channels
 @subsection Primary URL
 
diff --git a/guix/channels.scm b/guix/channels.scm
index 1d4b50aa48..9859bfdda8 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -69,7 +69,9 @@
             channel-location
 
             channel-introduction?
-            ;; <channel-introduction> accessors purposefully omitted for now.
+            make-channel-introduction
+            channel-introduction-first-signed-commit
+            channel-introduction-first-commit-signer
 
             openpgp-fingerprint->bytevector
             openpgp-fingerprint
@@ -130,13 +132,19 @@
 ;; commit so that only them may emit this introduction.  Introductions are
 ;; used to bootstrap trust in a channel.
 (define-record-type <channel-introduction>
-  (make-channel-introduction first-signed-commit first-commit-signer
-                             signature)
+  (%make-channel-introduction first-signed-commit first-commit-signer
+                              signature)
   channel-introduction?
   (first-signed-commit  channel-introduction-first-signed-commit) ;hex string
   (first-commit-signer  channel-introduction-first-commit-signer) ;bytevector
   (signature            channel-introduction-signature))          ;string
 
+(define (make-channel-introduction commit signer)
+  "Return a new channel introduction: COMMIT is the introductory where
+authentication starts, and SIGNER is the OpenPGP fingerprint (a bytevector) of
+the signer of that commit."
+  (%make-channel-introduction commit signer #f))
+
 (define (openpgp-fingerprint->bytevector str)
   "Convert STR, an OpenPGP fingerprint (hexadecimal string with whitespace),
 to the corresponding bytevector."
diff --git a/tests/channels.scm b/tests/channels.scm
index 3a2c1d429b..016c3ad9db 100644
--- a/tests/channels.scm
+++ b/tests/channels.scm
@@ -430,12 +430,11 @@
       (with-repository directory repository
         (let* ((commit1 (find-commit repository "first"))
                (commit2 (find-commit repository "second"))
-               (intro   ((@@ (guix channels) make-channel-introduction)
+               (intro   (make-channel-introduction
                          (commit-id-string commit1)
                          (openpgp-public-key-fingerprint
                           (read-openpgp-packet
-                           %ed25519bis-public-key-file)) ;different key
-                         #f))                     ;no signature
+                           %ed25519bis-public-key-file)))) ;different key
                (channel (channel (name 'example)
                                  (url (string-append "file://" directory))
                                  (introduction intro))))
@@ -486,12 +485,11 @@
         (let* ((commit1 (find-commit repository "first"))
                (commit2 (find-commit repository "second"))
                (commit3 (find-commit repository "third"))
-               (intro   ((@@ (guix channels) make-channel-introduction)
+               (intro   (make-channel-introduction
                          (commit-id-string commit1)
                          (openpgp-public-key-fingerprint
                           (read-openpgp-packet
-                           %ed25519-public-key-file))
-                         #f))                     ;no signature
+                           %ed25519-public-key-file))))
                (channel (channel (name 'example)
                                  (url (string-append "file://" directory))
                                  (introduction intro))))
-- 
2.26.2





^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 3/6] channels: Remove 'signature' from <channel-introduction>.
  2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
  2020-06-25 21:16   ` [bug#42048] [PATCH 2/6] channels: Make channel introductions public Ludovic Courtès
@ 2020-06-25 21:16   ` Ludovic Courtès
  2020-06-30 14:35     ` Ricardo Wurmus
  2020-06-25 21:16   ` [bug#42048] [PATCH 4/6] channels: Save and interpret 'introduction' field in provenance data Ludovic Courtès
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-25 21:16 UTC (permalink / raw)
  To: 42048; +Cc: Ludovic Courtès

In the end signing the commit/key pair does not buy us much.  Someone
publishing a valid but different commit/key pair would effectively be
publishing a different channel, which could be a fork (made by a former
authorized developer) or simply a mirror.  In the latter case, there's
nothing to be gained by publishing a different commit/key pair.

* guix/channels.scm (<channel-introduction>)[signature]: Remove.
(make-channel-introduction): Adjust accordingly.
---
 guix/channels.scm | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/guix/channels.scm b/guix/channels.scm
index 9859bfdda8..05b2661445 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -128,22 +128,19 @@
 
 ;; Channel introductions.  A "channel introduction" provides a commit/signer
 ;; pair that specifies the first commit of the authentication process as well
-;; as its signer's fingerprint.  The pair must be signed by the signer of that
-;; commit so that only them may emit this introduction.  Introductions are
-;; used to bootstrap trust in a channel.
+;; as its signer's fingerprint.  Introductions are used to bootstrap trust in
+;; a channel.
 (define-record-type <channel-introduction>
-  (%make-channel-introduction first-signed-commit first-commit-signer
-                              signature)
+  (%make-channel-introduction first-signed-commit first-commit-signer)
   channel-introduction?
-  (first-signed-commit  channel-introduction-first-signed-commit) ;hex string
-  (first-commit-signer  channel-introduction-first-commit-signer) ;bytevector
-  (signature            channel-introduction-signature))          ;string
+  (first-signed-commit  channel-introduction-first-signed-commit)  ;hex string
+  (first-commit-signer  channel-introduction-first-commit-signer)) ;bytevector
 
 (define (make-channel-introduction commit signer)
   "Return a new channel introduction: COMMIT is the introductory where
 authentication starts, and SIGNER is the OpenPGP fingerprint (a bytevector) of
 the signer of that commit."
-  (%make-channel-introduction commit signer #f))
+  (%make-channel-introduction commit signer))
 
 (define (openpgp-fingerprint->bytevector str)
   "Convert STR, an OpenPGP fingerprint (hexadecimal string with whitespace),
-- 
2.26.2





^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 4/6] channels: Save and interpret 'introduction' field in provenance data.
  2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
  2020-06-25 21:16   ` [bug#42048] [PATCH 2/6] channels: Make channel introductions public Ludovic Courtès
  2020-06-25 21:16   ` [bug#42048] [PATCH 3/6] channels: Remove 'signature' from <channel-introduction> Ludovic Courtès
@ 2020-06-25 21:16   ` Ludovic Courtès
  2020-06-25 21:16   ` [bug#42048] [PATCH 5/6] guix describe: Display channel introductions and add 'channels-sans-intro' Ludovic Courtès
  2020-06-25 21:16   ` [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions Ludovic Courtès
  4 siblings, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-25 21:16 UTC (permalink / raw)
  To: 42048; +Cc: Ludovic Courtès

With this change, profiles created by 'guix pull' & co. include channel
introductions as part of the channel metadata of each manifest entry.

* guix/channels.scm (channel-instances->manifest)[instance->entry]: Add
'introduction' field when CHANNEL has an introduction.
(profile-channels)[sexp->channel-introduction]: New procedure.
Use it to initialize the 'introduction' field.
---
 guix/channels.scm | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/guix/channels.scm b/guix/channels.scm
index 05b2661445..02800733dd 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -844,8 +844,9 @@ derivation."
   "Return a profile manifest with entries for all of INSTANCES, a list of
 channel instances."
   (define (instance->entry instance drv)
-    (let ((commit  (channel-instance-commit instance))
-          (channel (channel-instance-channel instance)))
+    (let* ((commit  (channel-instance-commit instance))
+           (channel (channel-instance-channel instance))
+           (intro   (channel-introduction channel)))
       (manifest-entry
         (name (symbol->string (channel-name channel)))
         (version (string-take commit 7))
@@ -860,7 +861,19 @@ channel instances."
                     (version 0)
                     (url ,(channel-url channel))
                     (branch ,(channel-branch channel))
-                    (commit ,commit))))))))
+                    (commit ,commit)
+                    ,@(if intro
+                          `((introduction
+                             (channel-introduction
+                              (version 0)
+                              (commit
+                               ,(channel-introduction-first-signed-commit
+                                 intro))
+                              (signer
+                               ,(openpgp-format-fingerprint
+                                 (channel-introduction-first-commit-signer
+                                  intro))))))
+                          '()))))))))
 
   (mlet* %store-monad ((derivations (channel-instance-derivations instances))
                        (entries ->  (map instance->entry instances derivations)))
@@ -928,17 +941,30 @@ to 'latest-channel-instances'."
 (define (profile-channels profile)
   "Return the list of channels corresponding to entries in PROFILE.  If
 PROFILE is not a profile created by 'guix pull', return the empty list."
+  (define sexp->channel-introduction
+    (match-lambda
+      (('channel-introduction ('version 0)
+                              ('commit commit) ('signer signer)
+                              _ ...)
+       (make-channel-introduction commit (openpgp-fingerprint signer)))
+      (x #f)))
+
   (filter-map (lambda (entry)
                 (match (assq 'source (manifest-entry-properties entry))
                   (('source ('repository ('version 0)
                                          ('url url)
                                          ('branch branch)
                                          ('commit commit)
-                                         _ ...))
+                                         rest ...))
                    (channel (name (string->symbol
                                    (manifest-entry-name entry)))
                             (url url)
-                            (commit commit)))
+                            (commit commit)
+                            (introduction
+                             (match (assq 'introduction rest)
+                               (#f #f)
+                               (('introduction intro)
+                                (sexp->channel-introduction intro))))))
 
                   ;; No channel information for this manifest entry.
                   ;; XXX: Pre-0.15.0 Guix did not provide that information,
-- 
2.26.2





^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 5/6] guix describe: Display channel introductions and add 'channels-sans-intro'.
  2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
                     ` (2 preceding siblings ...)
  2020-06-25 21:16   ` [bug#42048] [PATCH 4/6] channels: Save and interpret 'introduction' field in provenance data Ludovic Courtès
@ 2020-06-25 21:16   ` Ludovic Courtès
  2020-06-25 21:16   ` [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions Ludovic Courtès
  4 siblings, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-25 21:16 UTC (permalink / raw)
  To: 42048; +Cc: Ludovic Courtès

* guix/scripts/describe.scm (%available-formats): Add "channels-sans-intro".
(channel->sexp): Add #:include-introduction?.  Emit CHANNEL's intro if
INCLUDE-INTRODUCTION? is true and CHANNEL has an introduction.
(channel->json): Include CHANNEL's introduction, if any.
(channel->recutils): Likewise.
(display-profile-info): Add 'channels-sans-intro' case.
* doc/guix.texi (Invoking guix describe): Add introduction in example.
Add 'channels-sans-intro' case.
---
 doc/guix.texi             | 13 ++++++++-
 guix/scripts/describe.scm | 56 ++++++++++++++++++++++++++++++++-------
 2 files changed, 58 insertions(+), 11 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index a4bb52bb24..fcf67bd718 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -4613,7 +4613,12 @@ $ guix describe -f channels
         (name 'guix)
         (url "https://git.savannah.gnu.org/git/guix.git")
         (commit
-          "e0fa68c7718fffd33d81af415279d6ddb518f727")))
+          "e0fa68c7718fffd33d81af415279d6ddb518f727")
+        (introduction
+          (make-channel-introduction
+            "9edb3f66fd807b096b48283debdcddccfea34bad"
+            (openpgp-fingerprint
+              "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))))
 @end example
 
 @noindent
@@ -4639,6 +4644,12 @@ produce human-readable output;
 produce a list of channel specifications that can be passed to @command{guix
 pull -C} or installed as @file{~/.config/guix/channels.scm} (@pxref{Invoking
 guix pull});
+@item channels-sans-intro
+like @code{channels}, but omit the @code{introduction} field; use it to
+produce a channel specification suitable for Guix version 1.1.0 or
+earlier---the @code{introduction} field has to do with channel
+authentication (@pxref{Channels, Channel Authentication}) and is not
+supported by these older versions;
 @item json
 @cindex JSON
 produce a list of channel specifications in JSON format;
diff --git a/guix/scripts/describe.scm b/guix/scripts/describe.scm
index 7a2dbc453a..39e096a9a4 100644
--- a/guix/scripts/describe.scm
+++ b/guix/scripts/describe.scm
@@ -26,9 +26,11 @@
   #:use-module (guix scripts)
   #:use-module (guix describe)
   #:use-module (guix profiles)
+  #:autoload   (guix openpgp) (openpgp-format-fingerprint)
   #:use-module (git)
   #:use-module (json)
   #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-26)
   #:use-module (srfi srfi-37)
   #:use-module (ice-9 match)
   #:autoload   (ice-9 pretty-print) (pretty-print)
@@ -42,7 +44,8 @@
 ;;;
 ;;; Command-line options.
 ;;;
-(define %available-formats '("human" "channels" "json" "recutils"))
+(define %available-formats
+  '("human" "channels" "channels-sans-intro" "json" "recutils"))
 
 (define (list-formats)
   (display (G_ "The available formats are:\n"))
@@ -109,21 +112,50 @@ Display information about the channels currently in use.\n"))
        (_
         (warning (G_ "'GUIX_PACKAGE_PATH' is set but it is not captured~%")))))))
 
-(define (channel->sexp channel)
-  `(channel
-    (name ',(channel-name channel))
-    (url ,(channel-url channel))
-    (commit ,(channel-commit channel))))
+(define* (channel->sexp channel #:key (include-introduction? #t))
+  (let ((intro (and include-introduction?
+                    (channel-introduction channel))))
+    `(channel
+      (name ',(channel-name channel))
+      (url ,(channel-url channel))
+      (commit ,(channel-commit channel))
+      ,@(if intro
+            `((introduction (make-channel-introduction
+                             ,(channel-introduction-first-signed-commit intro)
+                             (openpgp-fingerprint
+                              ,(openpgp-format-fingerprint
+                                (channel-introduction-first-commit-signer
+                                 intro))))))
+            '()))))
 
 (define (channel->json channel)
-  (scm->json-string `((name . ,(channel-name channel))
-                      (url . ,(channel-url channel))
-                      (commit . ,(channel-commit channel)))))
+  (scm->json-string
+   (let ((intro (channel-introduction channel)))
+     `((name . ,(channel-name channel))
+       (url . ,(channel-url channel))
+       (commit . ,(channel-commit channel))
+       ,@(if intro
+             `((introduction
+                . ((commit . ,(channel-introduction-first-signed-commit
+                               intro))
+                   (signer . ,(openpgp-format-fingerprint
+                               (channel-introduction-first-commit-signer
+                                intro))))))
+             '())))))
 
 (define (channel->recutils channel port)
+  (define intro
+    (channel-introduction channel))
+
   (format port "name: ~a~%" (channel-name channel))
   (format port "url: ~a~%" (channel-url channel))
-  (format port "commit: ~a~%" (channel-commit channel)))
+  (format port "commit: ~a~%" (channel-commit channel))
+  (when intro
+    (format port "introductioncommit: ~a~%"
+            (channel-introduction-first-signed-commit intro))
+    (format port "introductionsigner: ~a~%"
+            (openpgp-format-fingerprint
+             (channel-introduction-first-commit-signer intro)))))
 
 (define (display-checkout-info fmt)
   "Display information about the current checkout according to FMT, a symbol
@@ -181,6 +213,10 @@ in the format specified by FMT."
      (display-profile-content profile number))
     ('channels
      (pretty-print `(list ,@(map channel->sexp channels))))
+    ('channels-sans-intro
+     (pretty-print `(list ,@(map (cut channel->sexp <>
+                                      #:include-introduction? #f)
+                                 channels))))
     ('json
      (format #t "[~a]~%" (string-join (map channel->json channels) ",")))
     ('recutils
-- 
2.26.2





^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
                     ` (3 preceding siblings ...)
  2020-06-25 21:16   ` [bug#42048] [PATCH 5/6] guix describe: Display channel introductions and add 'channels-sans-intro' Ludovic Courtès
@ 2020-06-25 21:16   ` Ludovic Courtès
  2020-06-30 15:53     ` Ricardo Wurmus
  4 siblings, 1 reply; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-25 21:16 UTC (permalink / raw)
  To: 42048; +Cc: Ludovic Courtès

* gnu/services.scm (channel->code): Include CHANNEL's introduction, if
any, unless CHANNEL is the singleton %DEFAULT-CHANNELS.
(channel->sexp): Add comment.
* guix/scripts/system.scm (sexp->channel): Change pattern to allow for
extensibility.
---
 gnu/services.scm        | 26 ++++++++++++++++++++++----
 guix/scripts/system.scm |  4 +++-
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/gnu/services.scm b/gnu/services.scm
index 27e5558231..f6dc56d940 100644
--- a/gnu/services.scm
+++ b/gnu/services.scm
@@ -31,6 +31,7 @@
   #:use-module (guix sets)
   #:use-module (guix ui)
   #:use-module ((guix utils) #:select (source-properties->location))
+  #:autoload   (guix openpgp) (openpgp-format-fingerprint)
   #:use-module (guix modules)
   #:use-module (gnu packages base)
   #:use-module (gnu packages bash)
@@ -392,14 +393,31 @@ by the initrd once the root file system is mounted.")))
 (define (channel->code channel)
   "Return code to build CHANNEL, ready to be dropped in a 'channels.scm'
 file."
-  `(channel (name ',(channel-name channel))
-            (url ,(channel-url channel))
-            (branch ,(channel-branch channel))
-            (commit ,(channel-commit channel))))
+  ;; Since the 'introduction' field is backward-incompatible, and since it's
+  ;; optional when using the "official" 'guix channel, include it if and only
+  ;; if we're referring to a different channel.
+  (let ((intro (and (not (equal? (list channel) %default-channels))
+                    (channel-introduction channel))))
+    `(channel (name ',(channel-name channel))
+              (url ,(channel-url channel))
+              (branch ,(channel-branch channel))
+              (commit ,(channel-commit channel))
+              ,@(if intro
+                    `((introduction
+                       (make-channel-introduction
+                        ,(channel-introduction-first-signed-commit intro)
+                        (openpgp-fingerprint
+                         ,(openpgp-format-fingerprint
+                           (channel-introduction-first-commit-signer
+                            intro))))))
+                    '()))))
 
 (define (channel->sexp channel)
   "Return an sexp describing CHANNEL.  The sexp is _not_ code and is meant to
 be parsed by tools; it's potentially more future-proof than code."
+  ;; TODO: Add CHANNEL's introduction.  Currently we can't do that because
+  ;; older 'guix system describe' expect exactly name/url/branch/commit
+  ;; without any additional fields.
   `(channel (name ,(channel-name channel))
             (url ,(channel-url channel))
             (branch ,(channel-branch channel))
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index 212b49f008..cfefe8a8a8 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -452,7 +452,9 @@ list of services."
     (('channel ('name name)
                ('url url)
                ('branch branch)
-               ('commit commit))
+               ('commit commit)
+               rest ...)
+     ;; XXX: In the future REST may include a channel introduction.
      (channel (name name) (url url)
               (branch branch) (commit commit)))))
 
-- 
2.26.2





^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 2/6] channels: Make channel introductions public.
  2020-06-25 21:16   ` [bug#42048] [PATCH 2/6] channels: Make channel introductions public Ludovic Courtès
@ 2020-06-25 22:32     ` Kyle Meyer
  2020-06-26  8:17       ` Ludovic Courtès
  2020-06-27 17:07       ` Ludovic Courtès
  0 siblings, 2 replies; 24+ messages in thread
From: Kyle Meyer @ 2020-06-25 22:32 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 42048

Ludovic Courtès writes:

> diff --git a/doc/guix.texi b/doc/guix.texi
[...]
> +As a user, you must be @dfn{introduced} to a channel so you can start
> +pulling from it and authenticate its code.  The @dfn{channel
> +introduction} tells Guix how to authenticate the first commit of that
> +channel:

Given the colon, it looks like something is missing here.  Based on what
comes next...

> +
> +As a user, you must provide a @dfn{channel introduction} in your
> +channels file so that Guix knows how to authenticate its first commit.
> +A channel specification, including its introduction, looks something
> +along these lines:
> +
> +@lisp
> +(channel
> +  (name 'my-channel)
> +  (url "https://example.org/my-channel.git")
> +  (introduction
> +   (make-channel-introduction
> +    "6f0d8cc0d88abb59c324b2990bfee2876016bb86"
> +    (openpgp-fingerprint
> +     "CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"))))
> +@end lisp

... perhaps the second "As a user" paragraph was supposed to replace the
first?




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 2/6] channels: Make channel introductions public.
  2020-06-25 22:32     ` Kyle Meyer
@ 2020-06-26  8:17       ` Ludovic Courtès
  2020-06-27 17:07       ` Ludovic Courtès
  1 sibling, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-26  8:17 UTC (permalink / raw)
  To: Kyle Meyer; +Cc: 42048

Hello Kyle,

Kyle Meyer <kyle@kyleam.com> skribis:

> Ludovic Courtès writes:
>
>> diff --git a/doc/guix.texi b/doc/guix.texi
> [...]
>> +As a user, you must be @dfn{introduced} to a channel so you can start
>> +pulling from it and authenticate its code.  The @dfn{channel
>> +introduction} tells Guix how to authenticate the first commit of that
>> +channel:
>
> Given the colon, it looks like something is missing here.  Based on what
> comes next...
>
>> +
>> +As a user, you must provide a @dfn{channel introduction} in your
>> +channels file so that Guix knows how to authenticate its first commit.
>> +A channel specification, including its introduction, looks something
>> +along these lines:
>> +
>> +@lisp
>> +(channel
>> +  (name 'my-channel)
>> +  (url "https://example.org/my-channel.git")
>> +  (introduction
>> +   (make-channel-introduction
>> +    "6f0d8cc0d88abb59c324b2990bfee2876016bb86"
>> +    (openpgp-fingerprint
>> +     "CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"))))
>> +@end lisp
>
> ... perhaps the second "As a user" paragraph was supposed to replace the
> first?

Oops, thanks for the heads-up.  I guess I got distracted as I was
reorganizing this.  I’ll post a v2 soonish!

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 2/6] channels: Make channel introductions public.
  2020-06-25 22:32     ` Kyle Meyer
  2020-06-26  8:17       ` Ludovic Courtès
@ 2020-06-27 17:07       ` Ludovic Courtès
  1 sibling, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-27 17:07 UTC (permalink / raw)
  To: Kyle Meyer; +Cc: 42048

Kyle Meyer <kyle@kyleam.com> skribis:

> Ludovic Courtès writes:
>
>> diff --git a/doc/guix.texi b/doc/guix.texi
> [...]
>> +As a user, you must be @dfn{introduced} to a channel so you can start
>> +pulling from it and authenticate its code.  The @dfn{channel
>> +introduction} tells Guix how to authenticate the first commit of that
>> +channel:
>
> Given the colon, it looks like something is missing here.  Based on what
> comes next...
>
>> +
>> +As a user, you must provide a @dfn{channel introduction} in your
>> +channels file so that Guix knows how to authenticate its first commit.
>> +A channel specification, including its introduction, looks something
>> +along these lines:
>> +
>> +@lisp
>> +(channel
>> +  (name 'my-channel)
>> +  (url "https://example.org/my-channel.git")
>> +  (introduction
>> +   (make-channel-introduction
>> +    "6f0d8cc0d88abb59c324b2990bfee2876016bb86"
>> +    (openpgp-fingerprint
>> +     "CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"))))
>> +@end lisp
>
> ... perhaps the second "As a user" paragraph was supposed to replace the
> first?

Yes, you were right.  I’ve changed it locally (not resending the whole
series).

Thanks!

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 3/6] channels: Remove 'signature' from <channel-introduction>.
  2020-06-25 21:16   ` [bug#42048] [PATCH 3/6] channels: Remove 'signature' from <channel-introduction> Ludovic Courtès
@ 2020-06-30 14:35     ` Ricardo Wurmus
  2020-06-30 15:15       ` Ludovic Courtès
  0 siblings, 1 reply; 24+ messages in thread
From: Ricardo Wurmus @ 2020-06-30 14:35 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 42048


Ludovic Courtès <ludo@gnu.org> writes:

> In the end signing the commit/key pair does not buy us much.  Someone
> publishing a valid but different commit/key pair would effectively be
> publishing a different channel, which could be a fork (made by a former
> authorized developer) or simply a mirror.  In the latter case, there's
> nothing to be gained by publishing a different commit/key pair.
>
> * guix/channels.scm (<channel-introduction>)[signature]: Remove.
> (make-channel-introduction): Adjust accordingly.
> ---
[…]
>  (define (make-channel-introduction commit signer)
>    "Return a new channel introduction: COMMIT is the introductory where
>  authentication starts, and SIGNER is the OpenPGP fingerprint (a bytevector) of
>  the signer of that commit."
> -  (%make-channel-introduction commit signer #f))
> +  (%make-channel-introduction commit signer))

Do we still need this procedure at all?  Looks like
%make-channel-introduction could simply be renamed to make-channel-introduction.

-- 
Ricardo




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 3/6] channels: Remove 'signature' from <channel-introduction>.
  2020-06-30 14:35     ` Ricardo Wurmus
@ 2020-06-30 15:15       ` Ludovic Courtès
  0 siblings, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-30 15:15 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: 42048

Hi,

Ricardo Wurmus <rekado@elephly.net> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:
>
>> In the end signing the commit/key pair does not buy us much.  Someone
>> publishing a valid but different commit/key pair would effectively be
>> publishing a different channel, which could be a fork (made by a former
>> authorized developer) or simply a mirror.  In the latter case, there's
>> nothing to be gained by publishing a different commit/key pair.
>>
>> * guix/channels.scm (<channel-introduction>)[signature]: Remove.
>> (make-channel-introduction): Adjust accordingly.
>> ---
> […]
>>  (define (make-channel-introduction commit signer)
>>    "Return a new channel introduction: COMMIT is the introductory where
>>  authentication starts, and SIGNER is the OpenPGP fingerprint (a bytevector) of
>>  the signer of that commit."
>> -  (%make-channel-introduction commit signer #f))
>> +  (%make-channel-introduction commit signer))
>
> Do we still need this procedure at all?  Looks like
> %make-channel-introduction could simply be renamed to make-channel-introduction.

‘%make-channel-introduction’ is actually a macro, which is thus inlined.
Exporting a procedure makes it easier to preserve ABI compatibility and
allow for future extensions (keyword parameters, for instance).

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-06-25 21:16   ` [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions Ludovic Courtès
@ 2020-06-30 15:53     ` Ricardo Wurmus
  2020-06-30 20:28       ` Ludovic Courtès
  0 siblings, 1 reply; 24+ messages in thread
From: Ricardo Wurmus @ 2020-06-30 15:53 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 42048

I looked through the changes and while I don’t fully understand the need
for adding the introduction to the provenance data, it looks good to
me.  Thank you!

One thing that I worry about is authentication of channels that are
added as dependencies of user-selected channels.  Let’s say my channel
“guix-bimsb” depends on “guix-past”.  How will users of “guix-bimsb”
authenticate the commits of “guix-past” when they don’t know about
“guix-past” (they only care about “guix-bimsb”), and don’t explicitly
add introduction information to their channels file?

Is there something that the authors of “guix-bimsb” can do to not only
indicate the dependency on “guix-past”, but also to attach introduction
information?  Will the format of the “.guix-channel” need to be
adjusted?

-- 
Ricardo




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-06-30 15:53     ` Ricardo Wurmus
@ 2020-06-30 20:28       ` Ludovic Courtès
  2020-07-01  8:51         ` zimoun
  2020-07-01 12:25         ` Ricardo Wurmus
  0 siblings, 2 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-06-30 20:28 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: 42048

Hi Ricardo,

Ricardo Wurmus <rekado@elephly.net> skribis:

> I looked through the changes and while I don’t fully understand the need
> for adding the introduction to the provenance data, it looks good to
> me.  Thank you!

Overall the idea is that a channel spec should always come with its
introduction; together they identify the channel and thus should not be
separated.

Adding the introduction to the provenance data allows ‘guix describe’ to
show the introduction, to ensure it’s not lost in transit.

Does that make sense?

> One thing that I worry about is authentication of channels that are
> added as dependencies of user-selected channels.  Let’s say my channel
> “guix-bimsb” depends on “guix-past”.  How will users of “guix-bimsb”
> authenticate the commits of “guix-past” when they don’t know about
> “guix-past” (they only care about “guix-bimsb”), and don’t explicitly
> add introduction information to their channels file?
>
> Is there something that the authors of “guix-bimsb” can do to not only
> indicate the dependency on “guix-past”, but also to attach introduction
> information?  Will the format of the “.guix-channel” need to be
> adjusted?

That’s a very good question and I had completely overlooked it.

With this patch set, someone pulling guix-bimsb would just end up
pulling guix-past unauthenticated; there’s not even a warning.

(There’s currently a warning in (guix channels), but only when pulling
an unauthenticated 'guix channel.  It’s perhaps too early to have that
warning enabled for all channels.  WDYT?)

So yes, I suppose we would need to extend the ‘.guix-channel’ format for
dependencies.  Luckily it should be quite simply because that format is
extensible; older Guix versions would ignore the ‘introduction’ field.
It would look something like this:

     (channel
      (version 0)
      (dependencies
       (channel
        (name some-collection)
        (url "https://example.org/first-collection.git")
        (introduction (channel-introduction
                        (version 0)
                        (commit "…")
                        (signer "…"))))
       (channel
        (name some-other-collection)
        (url "https://example.org/second-collection.git")
        (branch "testing"))))   ;not an authenticated channel

It does mean that a channel can indirectly trick you into turning off
authentication for a dependent channel.  But I think that’s within the
expectations for channels: when you choose a channel, you trust it
enough to run its code.

WDYT?

Thanks for reviewing!

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-06-30 20:28       ` Ludovic Courtès
@ 2020-07-01  8:51         ` zimoun
  2020-07-01 12:12           ` Ludovic Courtès
  2020-07-01 12:25         ` Ricardo Wurmus
  1 sibling, 1 reply; 24+ messages in thread
From: zimoun @ 2020-07-01  8:51 UTC (permalink / raw)
  To: Ludovic Courtès, Ricardo Wurmus; +Cc: 42048

Hi,

On Tue, 30 Jun 2020 at 22:28, Ludovic Courtès <ludo@gnu.org> wrote:

>> One thing that I worry about is authentication of channels that are
>> added as dependencies of user-selected channels.  Let’s say my channel
>> “guix-bimsb” depends on “guix-past”.  How will users of “guix-bimsb”
>> authenticate the commits of “guix-past” when they don’t know about
>> “guix-past” (they only care about “guix-bimsb”), and don’t explicitly
>> add introduction information to their channels file?
>>
>> Is there something that the authors of “guix-bimsb” can do to not only
>> indicate the dependency on “guix-past”, but also to attach introduction
>> information?  Will the format of the “.guix-channel” need to be
>> adjusted?
>
> That’s a very good question and I had completely overlooked it.

Héhé, yet I had the same question one month ago. :-)

--8<---------------cut here---------------start------------->8---
> The question about recursive still applies. ;-)
> Currently, if the local channel file points to a channel A which
> contains the file '.guix-channel' which points to another channel B,
> then when one runs "guix pull" well the channel A will be pulled and
> then the channel B, even if this channel B is not explicit in the
> initial local channel.  (Even, there is bug about recursive implicit
> pulls, see http://issues.guix.gnu.org/issue/41069; well another
> story.)
>What happens for such situation?

Nothing special, I guess: each channel would be authenticated (or not,if
it’s an unsigned channel).  I think it’s completely orthogonal.
--8<---------------cut here---------------end--------------->8---

http://issues.guix.gnu.org/issue/22883#75


> With this patch set, someone pulling guix-bimsb would just end up
> pulling guix-past unauthenticated; there’s not even a warning.
>
> (There’s currently a warning in (guix channels), but only when pulling
> an unauthenticated 'guix channel.  It’s perhaps too early to have that
> warning enabled for all channels.  WDYT?)

Enable the warning appears to me a good idea because this dependency is
like "doing something I am not necessary aware in my back".

For example, the first time I pulled the channel "guix-bimsb-non-free" which
depends on "guix-bimsb", it took me some time to understand why
"guix-bimsb" was pulled twice and once with a name I do not have in my
local channels.scm file.  Anyway.

> So yes, I suppose we would need to extend the ‘.guix-channel’ format for
> dependencies.  Luckily it should be quite simply because that format is
> extensible; older Guix versions would ignore the ‘introduction’ field.
> It would look something like this:
>
>      (channel
>       (version 0)
>       (dependencies
>        (channel
>         (name some-collection)
>         (url "https://example.org/first-collection.git")
>         (introduction (channel-introduction
>                         (version 0)
>                         (commit "…")
>                         (signer "…"))))
>        (channel
>         (name some-other-collection)
>         (url "https://example.org/second-collection.git")
>         (branch "testing"))))   ;not an authenticated channel
>
> It does mean that a channel can indirectly trick you into turning off
> authentication for a dependent channel.  But I think that’s within the
> expectations for channels: when you choose a channel, you trust it
> enough to run its code.

Sound good to me.

When I choose a channel, I trust the people enough to run their code.
But I do not trust the URL which serves it.  I mean, it is the point of
all this new authentication mechanism, isn't it?

However, I agree.  Channel should stay easy to fork and add something
(then maybe send a pull-request) without going in all the GPG signature
dance and/or running the options --allow-downgrades or
--disable-authentication (I do not remember the exact name).


Cheers,
simon




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 0/6] Authenticated channels for everyone!
  2020-06-25 21:04 [bug#42048] [PATCH 0/6] Authenticated channels for everyone! Ludovic Courtès
  2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
@ 2020-07-01  9:35 ` zimoun
  2020-07-01 12:17   ` Ludovic Courtès
  1 sibling, 1 reply; 24+ messages in thread
From: zimoun @ 2020-07-01  9:35 UTC (permalink / raw)
  To: Ludovic Courtès, 42048; +Cc: Ludovic Courtès

Hi Ludo,

On Thu, 25 Jun 2020 at 23:04, Ludovic Courtès <ludo@gnu.org> wrote:

> The most visible effect is that channel introductions are now
> part of the API and shown by ‘guix describe’.  It becomes a long-term
> commitment because we want to be able to pass the output of
> ‘guix describe -C channels’ or /run/current-system/channels.scm
> to ‘guix pull’ and ‘guix time-machine’ in the future.

How could I test this machinery with "guix time-machine"?

> Contrary to what I initially proposed¹, channel introductions are
> stripped to the bare minimum: a commit/fingerprint pair (as is
> currently the case on master, internally).  I figured it doesn’t
> buy us much to have the commit/fingerprint pair signed; what
> matters is that users obtain the introduction from a trusted
> source, and the signature wouldn’t help with that.  I also got
> rid of the idea of rendering introductions are opaque base64 blobs.

What happens when traveling in time if the key used by the signature has
been compromised?

Today, everything is fine, I sign and I do in introduction.  Couple of
months (or even years) later, my key will be compromised and so I will
revoke it.  What happens if I do "guix time-machine -C"?

Well, the question even applies to %default-channel?  Maybe you already
answered and I missed it.


Cheers,
simon




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-07-01  8:51         ` zimoun
@ 2020-07-01 12:12           ` Ludovic Courtès
  2020-07-01 12:49             ` zimoun
  0 siblings, 1 reply; 24+ messages in thread
From: Ludovic Courtès @ 2020-07-01 12:12 UTC (permalink / raw)
  To: zimoun; +Cc: Ricardo Wurmus, 42048

Hi Simon,

zimoun <zimon.toutoune@gmail.com> skribis:

> On Tue, 30 Jun 2020 at 22:28, Ludovic Courtès <ludo@gnu.org> wrote:
>
>>> One thing that I worry about is authentication of channels that are
>>> added as dependencies of user-selected channels.  Let’s say my channel
>>> “guix-bimsb” depends on “guix-past”.  How will users of “guix-bimsb”
>>> authenticate the commits of “guix-past” when they don’t know about
>>> “guix-past” (they only care about “guix-bimsb”), and don’t explicitly
>>> add introduction information to their channels file?
>>>
>>> Is there something that the authors of “guix-bimsb” can do to not only
>>> indicate the dependency on “guix-past”, but also to attach introduction
>>> information?  Will the format of the “.guix-channel” need to be
>>> adjusted?
>>
>> That’s a very good question and I had completely overlooked it.
>
> Héhé, yet I had the same question one month ago. :-)

Oh I’m sorry, I think I misunderstood your question back then!

>> With this patch set, someone pulling guix-bimsb would just end up
>> pulling guix-past unauthenticated; there’s not even a warning.
>>
>> (There’s currently a warning in (guix channels), but only when pulling
>> an unauthenticated 'guix channel.  It’s perhaps too early to have that
>> warning enabled for all channels.  WDYT?)
>
> Enable the warning appears to me a good idea because this dependency is
> like "doing something I am not necessary aware in my back".

I’m talking about the warning that says “this channel is
unauthenticated”, which is mostly orthogonal to the discussion at hand.
The reason I said it’s perhaps too early to enable it is that people
haven’t had a chance to make their channel “authenticable” yet.

>> So yes, I suppose we would need to extend the ‘.guix-channel’ format for
>> dependencies.  Luckily it should be quite simply because that format is
>> extensible; older Guix versions would ignore the ‘introduction’ field.
>> It would look something like this:
>>
>>      (channel
>>       (version 0)
>>       (dependencies
>>        (channel
>>         (name some-collection)
>>         (url "https://example.org/first-collection.git")
>>         (introduction (channel-introduction
>>                         (version 0)
>>                         (commit "…")
>>                         (signer "…"))))
>>        (channel
>>         (name some-other-collection)
>>         (url "https://example.org/second-collection.git")
>>         (branch "testing"))))   ;not an authenticated channel
>>
>> It does mean that a channel can indirectly trick you into turning off
>> authentication for a dependent channel.  But I think that’s within the
>> expectations for channels: when you choose a channel, you trust it
>> enough to run its code.
>
> Sound good to me.

Alright, I’ll do that as a followup.

Thanks!

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 0/6] Authenticated channels for everyone!
  2020-07-01  9:35 ` [bug#42048] [PATCH 0/6] Authenticated channels for everyone! zimoun
@ 2020-07-01 12:17   ` Ludovic Courtès
  2020-07-01 13:09     ` zimoun
  0 siblings, 1 reply; 24+ messages in thread
From: Ludovic Courtès @ 2020-07-01 12:17 UTC (permalink / raw)
  To: zimoun; +Cc: 42048

Hi,

zimoun <zimon.toutoune@gmail.com> skribis:

> On Thu, 25 Jun 2020 at 23:04, Ludovic Courtès <ludo@gnu.org> wrote:
>
>> The most visible effect is that channel introductions are now
>> part of the API and shown by ‘guix describe’.  It becomes a long-term
>> commitment because we want to be able to pass the output of
>> ‘guix describe -C channels’ or /run/current-system/channels.scm
>> to ‘guix pull’ and ‘guix time-machine’ in the future.
>
> How could I test this machinery with "guix time-machine"?

The normal way.  :-)

But of course, the new ‘introduction’ field of <channel> won’t be
recognized by older Guix versions.  In that case, you should use the
output of ‘guix describe -f channels-sans-intro’ as I wrote in the
manual.

>> Contrary to what I initially proposed¹, channel introductions are
>> stripped to the bare minimum: a commit/fingerprint pair (as is
>> currently the case on master, internally).  I figured it doesn’t
>> buy us much to have the commit/fingerprint pair signed; what
>> matters is that users obtain the introduction from a trusted
>> source, and the signature wouldn’t help with that.  I also got
>> rid of the idea of rendering introductions are opaque base64 blobs.
>
> What happens when traveling in time if the key used by the signature has
> been compromised?

In general, when a developer loses control over their key, another
committer should remove it right away form ‘.guix-authorizations’.  (I
did that today following Brett’s message, for example.)

Signatures on past commits can still be verified and everything is fine.
The (guix openpgp) code ignores key expiration and revocation; it “just”
verifies signatures.

> Today, everything is fine, I sign and I do in introduction.  Couple of
> months (or even years) later, my key will be compromised and so I will
> revoke it.  What happens if I do "guix time-machine -C"?

That’s OK.  The keyring is distributed along with the channel still
contains your key, with or without a revocation certificate, but that
doesn’t prevent us from verifying signatures on past commits.  (This is
different from what gpg does.)

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-06-30 20:28       ` Ludovic Courtès
  2020-07-01  8:51         ` zimoun
@ 2020-07-01 12:25         ` Ricardo Wurmus
  2020-07-01 21:50           ` bug#42048: " Ludovic Courtès
  1 sibling, 1 reply; 24+ messages in thread
From: Ricardo Wurmus @ 2020-07-01 12:25 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 42048


Ludovic Courtès <ludo@gnu.org> writes:

> So yes, I suppose we would need to extend the ‘.guix-channel’ format for
> dependencies.  Luckily it should be quite simply because that format is
> extensible; older Guix versions would ignore the ‘introduction’ field.
> It would look something like this:
>
>      (channel
>       (version 0)
>       (dependencies
>        (channel
>         (name some-collection)
>         (url "https://example.org/first-collection.git")
>         (introduction (channel-introduction
>                         (version 0)
>                         (commit "…")
>                         (signer "…"))))
>        (channel
>         (name some-other-collection)
>         (url "https://example.org/second-collection.git")
>         (branch "testing"))))   ;not an authenticated channel
>
> It does mean that a channel can indirectly trick you into turning off
> authentication for a dependent channel.  But I think that’s within the
> expectations for channels: when you choose a channel, you trust it
> enough to run its code.
>
> WDYT?

This sounds reasonable.  I agree that you’ve got to trust the channel
authors anyway, so allowing them to provide the introduction is fair.

-- 
Ricardo




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-07-01 12:12           ` Ludovic Courtès
@ 2020-07-01 12:49             ` zimoun
  2020-07-01 17:05               ` Ludovic Courtès
  0 siblings, 1 reply; 24+ messages in thread
From: zimoun @ 2020-07-01 12:49 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: Ricardo Wurmus, 42048


On Wed, 01 Jul 2020 at 14:12, Ludovic Courtès <ludo@gnu.org> wrote:

> Oh I’m sorry, I think I misunderstood your question back then!

My poor English does not help either. :-)

>>> With this patch set, someone pulling guix-bimsb would just end up
>>> pulling guix-past unauthenticated; there’s not even a warning.
>>>
>>> (There’s currently a warning in (guix channels), but only when pulling
>>> an unauthenticated 'guix channel.  It’s perhaps too early to have that
>>> warning enabled for all channels.  WDYT?)
>>
>> Enable the warning appears to me a good idea because this dependency is
>> like "doing something I am not necessary aware in my back".
>
> I’m talking about the warning that says “this channel is
> unauthenticated”, which is mostly orthogonal to the discussion at hand.
> The reason I said it’s perhaps too early to enable it is that people
> haven’t had a chance to make their channel “authenticable” yet.

Well, the possible scenarii are: when pulling guix-bimsb which ends up
to pull guix-past:

 1- unauthenticated guix-bimsb and unauthenticated guix-past
 2- authenticated guix-bimsb and unauthenticated guix-past
 3- unauthenticated guix-bimsb and authenticated guix-past
 4- authenticated guix-bimsb and authenticated guix-past

The #1 and #4 do not deserve a warning.
The point #3 neither and even the authentication of guix-past should be
turned off, at least now.

The point #2 requires a warning.  Because if I am pulling a
authenticated channel, I expect that all the code it pulls is
authenticated which will not be the case, so IMHO it deserves a
warning.

Then it is up to the guix-bimsb channel to add an introduction for the
dependency using the format you described.

Cheers,
simon




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 0/6] Authenticated channels for everyone!
  2020-07-01 12:17   ` Ludovic Courtès
@ 2020-07-01 13:09     ` zimoun
  2020-07-01 15:54       ` Ludovic Courtès
  0 siblings, 1 reply; 24+ messages in thread
From: zimoun @ 2020-07-01 13:09 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 42048

On Wed, 01 Jul 2020 at 14:17, Ludovic Courtès <ludo@gnu.org> wrote:

> But of course, the new ‘introduction’ field of <channel> won’t be
> recognized by older Guix versions.  In that case, you should use the
> output of ‘guix describe -f channels-sans-intro’ as I wrote in the
> manual.

Older Guix versions means the Scheme lib and not Inferiors, right?

I mean, if I run using a Guix post-'introduction' "guix describe -f
channels", then I can run with another Guix post-'introduction' "guix
time-machine -C channels.scm", everything is fine.

However, I cannot use this post-'introduction' channels.scm file with a
pre-'introduction' Guix and "guix time-machine -C channels.scm" fails,
right? 


> In general, when a developer loses control over their key, another
> committer should remove it right away form ‘.guix-authorizations’.  (I
> did that today following Brett’s message, for example.)
>
> Signatures on past commits can still be verified and everything is fine.
> The (guix openpgp) code ignores key expiration and revocation; it “just”
> verifies signatures.
>
>> Today, everything is fine, I sign and I do in introduction.  Couple of
>> months (or even years) later, my key will be compromised and so I will
>> revoke it.  What happens if I do "guix time-machine -C"?
>
> That’s OK.  The keyring is distributed along with the channel still
> contains your key, with or without a revocation certificate, but that
> doesn’t prevent us from verifying signatures on past commits.  (This is
> different from what gpg does.)

It answers to my question about time-machine.  Thank you.
Now I have another one. :-)

Well, if now Eve has the control of an authorized key (for example the
Brett's one) then you cannot distinguish between past valid signatures
to current malicious ones, even if the key is revoked, right?

(It is not a practical issue but it is a possible scenario.)

Cheers,
simon




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 0/6] Authenticated channels for everyone!
  2020-07-01 13:09     ` zimoun
@ 2020-07-01 15:54       ` Ludovic Courtès
  0 siblings, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-07-01 15:54 UTC (permalink / raw)
  To: zimoun; +Cc: 42048

zimoun <zimon.toutoune@gmail.com> skribis:

> On Wed, 01 Jul 2020 at 14:17, Ludovic Courtès <ludo@gnu.org> wrote:
>
>> But of course, the new ‘introduction’ field of <channel> won’t be
>> recognized by older Guix versions.  In that case, you should use the
>> output of ‘guix describe -f channels-sans-intro’ as I wrote in the
>> manual.
>
> Older Guix versions means the Scheme lib and not Inferiors, right?
>
> I mean, if I run using a Guix post-'introduction' "guix describe -f
> channels", then I can run with another Guix post-'introduction' "guix
> time-machine -C channels.scm", everything is fine.
>
> However, I cannot use this post-'introduction' channels.scm file with a
> pre-'introduction' Guix and "guix time-machine -C channels.scm" fails,
> right? 

Yup!

> Well, if now Eve has the control of an authorized key (for example the
> Brett's one) then you cannot distinguish between past valid signatures
> to current malicious ones, even if the key is revoked, right?

Revocation in the OpenPGP sense doesn’t not matter at all.  What matters
is whether the key is in ‘.guix-authorizations’.  If we remove if from
there in commit X, then any commit descending from X that is signed by
that key will be rejected.  Past commits (ancestors of X) signed by that
key are still considered authentic.

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions.
  2020-07-01 12:49             ` zimoun
@ 2020-07-01 17:05               ` Ludovic Courtès
  0 siblings, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-07-01 17:05 UTC (permalink / raw)
  To: zimoun; +Cc: Ricardo Wurmus, 42048

zimoun <zimon.toutoune@gmail.com> skribis:

> On Wed, 01 Jul 2020 at 14:12, Ludovic Courtès <ludo@gnu.org> wrote:

[...]

>> I’m talking about the warning that says “this channel is
>> unauthenticated”, which is mostly orthogonal to the discussion at hand.
>> The reason I said it’s perhaps too early to enable it is that people
>> haven’t had a chance to make their channel “authenticable” yet.

To be clear, I’m referring to this:

  https://git.savannah.gnu.org/cgit/guix.git/tree/guix/channels.scm?id=9f5f3932debc72a57a830fc6ca5ab980f6db4941#n406

> Well, the possible scenarii are: when pulling guix-bimsb which ends up
> to pull guix-past:
>
>  1- unauthenticated guix-bimsb and unauthenticated guix-past
>  2- authenticated guix-bimsb and unauthenticated guix-past
>  3- unauthenticated guix-bimsb and authenticated guix-past
>  4- authenticated guix-bimsb and authenticated guix-past
>
> The #1 and #4 do not deserve a warning.
> The point #3 neither and even the authentication of guix-past should be
> turned off, at least now.
>
> The point #2 requires a warning.  Because if I am pulling a
> authenticated channel, I expect that all the code it pulls is
> authenticated which will not be the case, so IMHO it deserves a
> warning.
>
> Then it is up to the guix-bimsb channel to add an introduction for the
> dependency using the format you described.

Exactly.  I agree that #2 is problematic, but if the authors of
guix-bimsb are aware that guix-past can also be authenticated, then I
think it’s their responsibility to update their ‘.guix-channel’
dependencies accordingly.

Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#42048: [PATCH 6/6] services: provenance: Save channel introductions.
  2020-07-01 12:25         ` Ricardo Wurmus
@ 2020-07-01 21:50           ` Ludovic Courtès
  0 siblings, 0 replies; 24+ messages in thread
From: Ludovic Courtès @ 2020-07-01 21:50 UTC (permalink / raw)
  To: Ricardo Wurmus; +Cc: 42048-done

Hi,

Ricardo Wurmus <rekado@elephly.net> skribis:

> Ludovic Courtès <ludo@gnu.org> writes:
>
>> So yes, I suppose we would need to extend the ‘.guix-channel’ format for
>> dependencies.  Luckily it should be quite simply because that format is
>> extensible; older Guix versions would ignore the ‘introduction’ field.
>> It would look something like this:
>>
>>      (channel
>>       (version 0)
>>       (dependencies
>>        (channel
>>         (name some-collection)
>>         (url "https://example.org/first-collection.git")
>>         (introduction (channel-introduction
>>                         (version 0)
>>                         (commit "…")
>>                         (signer "…"))))
>>        (channel
>>         (name some-other-collection)
>>         (url "https://example.org/second-collection.git")
>>         (branch "testing"))))   ;not an authenticated channel
>>
>> It does mean that a channel can indirectly trick you into turning off
>> authentication for a dependent channel.  But I think that’s within the
>> expectations for channels: when you choose a channel, you trust it
>> enough to run its code.
>>
>> WDYT?
>
> This sounds reasonable.  I agree that you’ve got to trust the channel
> authors anyway, so allowing them to provide the introduction is fair.

I went ahead and did that:

  https://git.savannah.gnu.org/cgit/guix.git/commit/?id=d774c7b1218a3cc20079b19812da119f9ed26b54

Let me know what you think!

The whole series is now pushed:

  d774c7b121 channels: Dependencies listed in '.guix-channel' can have an introduction.
  884df77640 channels: Properly diagnose test failure.
  eb5cf39e66 services: provenance: Save channel introductions.
  6d39f0cb77 guix describe: Display channel introductions and add 'channels-sans-intro'.
  471550c28c channels: Save and interpret 'introduction' field in provenance data.
  22a9699257 channels: Remove 'signature' from <channel-introduction>.
  8b7d982e6a channels: Make channel introductions public.
  6577682a6c channels: Add 'openpgp-fingerprint->bytevector'.

Thanks for your feedback,
Ludo’.




^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, back to index

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-25 21:04 [bug#42048] [PATCH 0/6] Authenticated channels for everyone! Ludovic Courtès
2020-06-25 21:16 ` [bug#42048] [PATCH 1/6] channels: Add 'openpgp-fingerprint->bytevector' Ludovic Courtès
2020-06-25 21:16   ` [bug#42048] [PATCH 2/6] channels: Make channel introductions public Ludovic Courtès
2020-06-25 22:32     ` Kyle Meyer
2020-06-26  8:17       ` Ludovic Courtès
2020-06-27 17:07       ` Ludovic Courtès
2020-06-25 21:16   ` [bug#42048] [PATCH 3/6] channels: Remove 'signature' from <channel-introduction> Ludovic Courtès
2020-06-30 14:35     ` Ricardo Wurmus
2020-06-30 15:15       ` Ludovic Courtès
2020-06-25 21:16   ` [bug#42048] [PATCH 4/6] channels: Save and interpret 'introduction' field in provenance data Ludovic Courtès
2020-06-25 21:16   ` [bug#42048] [PATCH 5/6] guix describe: Display channel introductions and add 'channels-sans-intro' Ludovic Courtès
2020-06-25 21:16   ` [bug#42048] [PATCH 6/6] services: provenance: Save channel introductions Ludovic Courtès
2020-06-30 15:53     ` Ricardo Wurmus
2020-06-30 20:28       ` Ludovic Courtès
2020-07-01  8:51         ` zimoun
2020-07-01 12:12           ` Ludovic Courtès
2020-07-01 12:49             ` zimoun
2020-07-01 17:05               ` Ludovic Courtès
2020-07-01 12:25         ` Ricardo Wurmus
2020-07-01 21:50           ` bug#42048: " Ludovic Courtès
2020-07-01  9:35 ` [bug#42048] [PATCH 0/6] Authenticated channels for everyone! zimoun
2020-07-01 12:17   ` Ludovic Courtès
2020-07-01 13:09     ` zimoun
2020-07-01 15:54       ` Ludovic Courtès

unofficial mirror of guix-patches@gnu.org 

Archives are clonable:
	git clone --mirror https://yhetil.org/guix-patches/1 guix-patches/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 guix-patches guix-patches/ https://yhetil.org/guix-patches \
		guix-patches@gnu.org
	public-inbox-index guix-patches

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://news.yhetil.org/yhetil.gnu.guix.patches


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git