Skip to content

Commit 0a6bc08

Browse files
Add PyManager documentation for index signatures (GH-148631)
(cherry picked from commit 54607ee) Co-authored-by: Steve Dower <steve.dower@python.org>
1 parent 0d2101d commit 0a6bc08

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

Doc/using/windows.rst

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,14 @@ directory containing the configuration file that specified them.
780780
- True to suppress visible warnings when a shebang launches an application
781781
other than a Python runtime.
782782

783+
* - ``source_settings``
784+
- A mapping from source URL to settings specific to that index.
785+
When multiple configuration files include this section, URL settings are
786+
added or overwritten, but individual settings are not merged.
787+
These settings are currently only for :ref:`index signatures
788+
<pymanager-index-signatures>`.
789+
790+
783791
.. _install-freethreaded-windows:
784792

785793
Installing free-threaded binaries
@@ -801,6 +809,101 @@ installed, then ``python`` will launch this one. Otherwise, you will need to use
801809
``py -V:3.14t ...`` or, if you have added the global aliases directory to your
802810
:envvar:`PATH` environment variable, the ``python3.14t.exe`` commands.
803811

812+
813+
.. _pymanager-index-signatures:
814+
815+
Index signatures
816+
----------------
817+
818+
.. versionadded:: 26.2
819+
820+
Index files may be signed to detect tampering. A signature is a catalog file
821+
at the same URL as the index with ``.cat`` added to the filename. The catalog
822+
file should contain the hash of its matching index file, and should be signed
823+
with a valid Authenticode signature. This allows standard tooling (on Windows)
824+
to generate a signature, and any certificate may be used as long as the client
825+
operating system already trusts its certification authority (root CA).
826+
827+
Index signatures are only downloaded and checked when the local configuration's
828+
``source_settings`` section includes the index URL and ``requires_signature`` is
829+
true, or the index JSON contains ``requires_signature`` set to true. When the
830+
setting exists in local configuration, even when false, settings in the index
831+
are ignored.
832+
833+
As well as requiring a valid signature, the ``required_root_subject`` and
834+
``required_publisher_subject`` settings can further restrict acceptable
835+
signatures based on the certificate Subject fields. Any attribute specified in
836+
the configuration must match the attribute in the certificate (additional
837+
attributes in the certificate are ignored). Typical attributes are ``CN=`` for
838+
the common name, ``O=`` for the organizational unit, and ``C=`` for the
839+
publisher's country.
840+
841+
Finally, the ``required_publisher_eku`` setting allows requiring that a specific
842+
Enhanced Key Usage (EKU) has been assigned to the publisher certificate. For
843+
example, the EKU ``1.3.6.1.5.5.7.3.3`` indicates that the certificate was
844+
intended for code signing (as opposed to server or client authentication).
845+
In combination with a specific root CA, this provides another mechanism to
846+
verify a legitimate signature.
847+
848+
This is an example ``source_settings`` section from a configuration file. In
849+
this case, the publisher of the feed is uniquely identified by the combination
850+
of the Microsoft Identity Verification root and the EKU assigned by that root.
851+
The signature for this case would be found at
852+
``https://www.python.org/ftp/python/index-windows.json.cat``.
853+
854+
.. code:: json5
855+
856+
{
857+
"source_settings": {
858+
"https://www.python.org/ftp/python/index-windows.json": {
859+
"requires_signature": true,
860+
"required_root_subject": "CN=Microsoft Identity Verification Root Certificate Authority 2020",
861+
"required_publisher_subject": "CN=Python Software Foundation",
862+
"required_publisher_eku": "1.3.6.1.4.1.311.97.608394634.79987812.305991749.578777327"
863+
}
864+
}
865+
}
866+
867+
The same settings could be specified in the ``index.json`` file instead. In this
868+
case, the root and EKU are omitted, meaning that the signature must be valid and
869+
have a specific common name in the publisher's certificate, but no other checks
870+
are used.
871+
872+
.. code:: json5
873+
874+
{
875+
"requires_signature": true,
876+
"required_publisher_subject": "CN=Python Software Foundation",
877+
"versions": [
878+
// ...
879+
]
880+
}
881+
882+
When settings from inside a feed are used, the user is notified and the settings
883+
are shown in the log file or verbose output. It is recommended to copy these
884+
settings into a local configuration file for feeds that will be used frequently,
885+
so that unauthorised modifications to the feed cannot disable verification.
886+
887+
It is not possible to override the location of the signature file in the feed or
888+
through a configuration file. Administrators can provide their own
889+
``source_settings`` in a mandatory configuration file (see
890+
:ref:`pymanager-admin-config`).
891+
892+
If signature validation fails, you will be notified and prompted to continue.
893+
When interactive confirmation is not allowed (for example, because ``--yes`` was
894+
specified), it will always abort. To use a feed with invalid configuration in
895+
this scenario, you must provide a configuration file that disables signature
896+
checking for that feed.
897+
898+
.. code:: json5
899+
900+
"source_settings": {
901+
"https://www.example.com/feed-with-invalid-signature.json": {
902+
"requires_signature": false
903+
}
904+
}
905+
906+
804907
.. _pymanager-troubleshoot:
805908

806909
Troubleshooting

0 commit comments

Comments
 (0)