]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Add PyManager documentation for index signatures (GH-148631) 3.14
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 15 Apr 2026 21:54:01 +0000 (23:54 +0200)
committerGitHub <noreply@github.com>
Wed, 15 Apr 2026 21:54:01 +0000 (21:54 +0000)
(cherry picked from commit 54607eec34b42d377a12fe16697e61a1663a1f42)

Co-authored-by: Steve Dower <steve.dower@python.org>
Doc/using/windows.rst

index 38e6111c765dbe2ed24ac1a58100a892e45e5043..c68e3bbda91282b7d745668e37931437b9c71969 100644 (file)
@@ -780,6 +780,14 @@ directory containing the configuration file that specified them.
      - True to suppress visible warnings when a shebang launches an application
        other than a Python runtime.
 
+   * - ``source_settings``
+     - A mapping from source URL to settings specific to that index.
+       When multiple configuration files include this section, URL settings are
+       added or overwritten, but individual settings are not merged.
+       These settings are currently only for :ref:`index signatures
+       <pymanager-index-signatures>`.
+
+
 .. _install-freethreaded-windows:
 
 Installing free-threaded binaries
@@ -801,6 +809,101 @@ installed, then ``python`` will launch this one. Otherwise, you will need to use
 ``py -V:3.14t ...`` or, if you have added the global aliases directory to your
 :envvar:`PATH` environment variable, the ``python3.14t.exe`` commands.
 
+
+.. _pymanager-index-signatures:
+
+Index signatures
+----------------
+
+.. versionadded:: 26.2
+
+Index files may be signed to detect tampering. A signature is a catalog file
+at the same URL as the index with ``.cat`` added to the filename. The catalog
+file should contain the hash of its matching index file, and should be signed
+with a valid Authenticode signature. This allows standard tooling (on Windows)
+to generate a signature, and any certificate may be used as long as the client
+operating system already trusts its certification authority (root CA).
+
+Index signatures are only downloaded and checked when the local configuration's
+``source_settings`` section includes the index URL and ``requires_signature`` is
+true, or the index JSON contains ``requires_signature`` set to true. When the
+setting exists in local configuration, even when false, settings in the index
+are ignored.
+
+As well as requiring a valid signature, the ``required_root_subject`` and
+``required_publisher_subject`` settings can further restrict acceptable
+signatures based on the certificate Subject fields. Any attribute specified in
+the configuration must match the attribute in the certificate (additional
+attributes in the certificate are ignored). Typical attributes are ``CN=`` for
+the common name, ``O=`` for the organizational unit, and ``C=`` for the
+publisher's country.
+
+Finally, the ``required_publisher_eku`` setting allows requiring that a specific
+Enhanced Key Usage (EKU) has been assigned to the publisher certificate. For
+example, the EKU ``1.3.6.1.5.5.7.3.3`` indicates that the certificate was
+intended for code signing (as opposed to server or client authentication).
+In combination with a specific root CA, this provides another mechanism to
+verify a legitimate signature.
+
+This is an example ``source_settings`` section from a configuration file. In
+this case, the publisher of the feed is uniquely identified by the combination
+of the Microsoft Identity Verification root and the EKU assigned by that root.
+The signature for this case would be found at
+``https://www.python.org/ftp/python/index-windows.json.cat``.
+
+.. code:: json5
+
+   {
+     "source_settings": {
+       "https://www.python.org/ftp/python/index-windows.json": {
+         "requires_signature": true,
+         "required_root_subject": "CN=Microsoft Identity Verification Root Certificate Authority 2020",
+         "required_publisher_subject": "CN=Python Software Foundation",
+         "required_publisher_eku": "1.3.6.1.4.1.311.97.608394634.79987812.305991749.578777327"
+       }
+     }
+   }
+
+The same settings could be specified in the ``index.json`` file instead. In this
+case, the root and EKU are omitted, meaning that the signature must be valid and
+have a specific common name in the publisher's certificate, but no other checks
+are used.
+
+.. code:: json5
+
+   {
+     "requires_signature": true,
+     "required_publisher_subject": "CN=Python Software Foundation",
+     "versions": [
+       // ...
+     ]
+   }
+
+When settings from inside a feed are used, the user is notified and the settings
+are shown in the log file or verbose output. It is recommended to copy these
+settings into a local configuration file for feeds that will be used frequently,
+so that unauthorised modifications to the feed cannot disable verification.
+
+It is not possible to override the location of the signature file in the feed or
+through a configuration file. Administrators can provide their own
+``source_settings`` in a mandatory configuration file (see
+:ref:`pymanager-admin-config`).
+
+If signature validation fails, you will be notified and prompted to continue.
+When interactive confirmation is not allowed (for example, because ``--yes`` was
+specified), it will always abort. To use a feed with invalid configuration in
+this scenario, you must provide a configuration file that disables signature
+checking for that feed.
+
+.. code:: json5
+
+   "source_settings": {
+     "https://www.example.com/feed-with-invalid-signature.json": {
+       "requires_signature": false
+     }
+   }
+
+
 .. _pymanager-troubleshoot:
 
 Troubleshooting