pep-0427 edits
This commit is contained in:
parent
c42dc66be1
commit
f1535d9c8c
138
pep-0427.txt
138
pep-0427.txt
|
@ -93,7 +93,7 @@ Recommended installer features
|
||||||
Rewrite ``#!python``.
|
Rewrite ``#!python``.
|
||||||
In wheel, scripts are packaged in
|
In wheel, scripts are packaged in
|
||||||
``{distribution}-{version}.data/scripts/``. If the first line of
|
``{distribution}-{version}.data/scripts/``. If the first line of
|
||||||
a file in ``scripts/`` starts with exactly b'#!python', rewrite to
|
a file in ``scripts/`` starts with exactly ``b'#!python'``, rewrite to
|
||||||
point to the correct interpreter. Unix installers may need to add
|
point to the correct interpreter. Unix installers may need to add
|
||||||
the +x bit to these files if the archive was created on Windows.
|
the +x bit to these files if the archive was created on Windows.
|
||||||
|
|
||||||
|
@ -146,12 +146,26 @@ package's basic interpreter requirements and are detailed in PEP 425.
|
||||||
File contents
|
File contents
|
||||||
'''''''''''''
|
'''''''''''''
|
||||||
|
|
||||||
#. Wheel files contain a folder {distribution}-{version}.dist-info/
|
The conents of a wheel file, where {distribution} is replaced with the
|
||||||
with the PEP 426 metadata (Metadata version 1.3 or greater) and an
|
name of the package, e.g. ``beaglevote`` and {version} is replaced with
|
||||||
additional file WHEEL with metadata about the archive itself.
|
its version, e.g. ``1.0.0``, consist of:
|
||||||
#. The root of a .whl is installed into one of purelib or platlib.
|
|
||||||
#. Wheel files contain metadata about the wheel format itself in
|
#. ``/``, the root of the archive, contains all files to be installed in
|
||||||
``{distribution}-{version}.dist-info/WHEEL``::
|
``purelib`` or ``platlib`` as specified in ``WHEEL``. ``purelib`` and
|
||||||
|
``platlib`` are usually both ``site-packages``.
|
||||||
|
#. ``{distribution}-{version}.dist-info/`` contains metadata.
|
||||||
|
#. ``{distribution}-{version}.data/`` contains one subdirectory
|
||||||
|
for each non-empty install scheme key not already covered, where
|
||||||
|
the subdirectory name is an index into a dictionary of install paths
|
||||||
|
(e.g. ``data``, ``scripts``, ``include``, ``purelib`, ``platlib``).
|
||||||
|
#. Python scripts must appear in ``scripts`` and begin with exactly
|
||||||
|
``b'#!python'`` in order to enjoy script wrapper generation and
|
||||||
|
``#!python`` rewriting at install time. They may have any or no
|
||||||
|
extension.
|
||||||
|
#. ``{distribution}-{version}.dist-info/METADATA`` is Metadata version 1.3
|
||||||
|
(PEP 426) or greater format metadata.
|
||||||
|
#. ``{distribution}-{version}.dist-info/WHEEL`` is metadata about the archive
|
||||||
|
itself::
|
||||||
|
|
||||||
Wheel-Version: 0.1
|
Wheel-Version: 0.1
|
||||||
Generator: bdist_wheel 0.7
|
Generator: bdist_wheel 0.7
|
||||||
|
@ -163,16 +177,17 @@ File contents
|
||||||
directory of the archive should be installed into purelib;
|
directory of the archive should be installed into purelib;
|
||||||
otherwise the root should be installed into platlib.
|
otherwise the root should be installed into platlib.
|
||||||
#. A wheel installer should warn if Wheel-Version is greater than the
|
#. A wheel installer should warn if Wheel-Version is greater than the
|
||||||
version it supports, and fail if Wheel-Version has a greater major
|
version it supports, and must fail if Wheel-Version has a greater
|
||||||
version than the version it supports.
|
major version than the version it supports.
|
||||||
#. If a .whl contains scripts, both purelib and platlib, or any other
|
|
||||||
files that are not installed on ``sys.path``, they are found in
|
|
||||||
``{distribution}-{version}.data/{key}``, where ``{key}`` is an
|
|
||||||
index into a dictionary of install paths.
|
|
||||||
#. Wheel, being an installation format that is intended to work across
|
#. Wheel, being an installation format that is intended to work across
|
||||||
multiple versions of Python, does not generally include .pyc files.
|
multiple versions of Python, does not generally include .pyc files.
|
||||||
#. Wheel does not contain setup.py or setup.cfg.
|
#. Wheel does not contain setup.py or setup.cfg.
|
||||||
|
|
||||||
|
This version of the wheel specification is based on the distutils install
|
||||||
|
schemes and does not define how to install files to other locations.
|
||||||
|
The layout offers a superset of the functionality provided by the existing
|
||||||
|
wininst and egg binary formats.
|
||||||
|
|
||||||
|
|
||||||
The .dist-info directory
|
The .dist-info directory
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -232,10 +247,11 @@ RECORD.jws is not mentioned in RECORD at all. Every other file in the
|
||||||
archive must have a correct hash in RECORD, or the installation will
|
archive must have a correct hash in RECORD, or the installation will
|
||||||
fail.
|
fail.
|
||||||
|
|
||||||
The signature is one or more JSON Web Signature JSON Serialization
|
The signature format is derived from the JSON Web Signatures (JWS)
|
||||||
(JWS-JS) signatures stored in a file RECORD.jws adjacent to RECORD.
|
specification. One or more JSON Web Signature JSON Serialization (JWS-JS)
|
||||||
|
signatures may be stored in a file RECORD.jws adjacent to RECORD.
|
||||||
|
|
||||||
A signature-aware installer can be instructed to check for a
|
A signature-aware installer could be instructed to check for a
|
||||||
particular Ed25519 public key by using an extended "extras" syntax.::
|
particular Ed25519 public key by using an extended "extras" syntax.::
|
||||||
|
|
||||||
# request a normal optional feature "extra", and indicate
|
# request a normal optional feature "extra", and indicate
|
||||||
|
@ -243,43 +259,36 @@ particular Ed25519 public key by using an extended "extras" syntax.::
|
||||||
# urlsafe-b64encode-nopad encoded ed25519 public key:
|
# urlsafe-b64encode-nopad encoded ed25519 public key:
|
||||||
package[extra, ed25519=ouBJlTJJ4SJXoy8Bi1KRlewWLU6JW7HUXTgvU1YRuiA]
|
package[extra, ed25519=ouBJlTJJ4SJXoy8Bi1KRlewWLU6JW7HUXTgvU1YRuiA]
|
||||||
|
|
||||||
An application could distribute a requires.txt file with many such
|
An application could distribute a requires.txt file with many such lines
|
||||||
lines for all its dependencies and their public keys. By installing
|
for all its dependencies and their public keys. By installing from this
|
||||||
from this file an application's users would know whether the
|
file an application's users can know they are getting packages from the
|
||||||
application's dependencies came from the correct publishers.
|
same publishers.
|
||||||
|
|
||||||
Applications that wish to "fail open" for backwards compatibility with
|
Applications that wish to "fail open" for backwards compatibility with
|
||||||
non-signature-aware installers should specify that their package
|
non-signature-aware installers should specify that their package
|
||||||
provides the extra ``ed25519=(key)`` with no associated dependencies.
|
provides the extra ``ed25519=(key)`` with no associated dependencies.
|
||||||
|
|
||||||
Key distribution is outside the scope of this spec. Public wheel
|
|
||||||
signing keys could be signed with the packager's GPG key or stored at
|
|
||||||
an ``https://`` protected URL.
|
|
||||||
|
|
||||||
|
|
||||||
JSON Web Signatures Extensions
|
JSON Web Signatures Extensions
|
||||||
''''''''''''''''''''''''''''''
|
''''''''''''''''''''''''''''''
|
||||||
|
|
||||||
The Ed25519 algorithm is used as an extension to the JSON Web
|
The Ed25519 algorithm is used as an extension to the JSON Web Signatures
|
||||||
Signatures specification. Wheel uses ``alg="Ed25519"`` in the header.
|
specification. Wheel uses ``alg="Ed25519"`` in the header. The key
|
||||||
The key attribute holds the signature's public JSON Web Key. For JSON
|
attribute holds the signature's public JSON Web Key. In JSON Web Key
|
||||||
Web Key / JSON Private Key the verifying (public) key is called vk and
|
/ JSON Private Key the Ed25519 verifying (public) key is called vk and
|
||||||
the signing (private) key is called sk.
|
the signing (private) key is called sk.
|
||||||
|
|
||||||
Example header::
|
Example header::
|
||||||
|
|
||||||
{
|
{
|
||||||
"alg": "Ed25519",
|
"alg": "Ed25519",
|
||||||
"typ": "JWT",
|
"jwk": {
|
||||||
"key": {
|
"alg": "Ed25519",
|
||||||
"alg": "Ed25519",
|
"vk": "tmAYCrSfj8gtJ10v3VkvW7jOndKmQIYE12hgnFu3cvk"
|
||||||
"vk": "tmAYCrSfj8gtJ10v3VkvW7jOndKmQIYE12hgnFu3cvk"
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
A future version of wheel may omit ``typ``.
|
Example payload, always the SHA-256 hash of RECORD::
|
||||||
|
|
||||||
Example payload::
|
|
||||||
|
|
||||||
{ "hash": "sha256=ADD-r2urObZHcxBW3Cr-vDCu5RJwT4CaRTHiFmbcIYY" }
|
{ "hash": "sha256=ADD-r2urObZHcxBW3Cr-vDCu5RJwT4CaRTHiFmbcIYY" }
|
||||||
|
|
||||||
|
@ -292,6 +301,7 @@ See
|
||||||
- http://self-issued.info/docs/draft-jones-jose-jws-json-serialization.html
|
- http://self-issued.info/docs/draft-jones-jose-jws-json-serialization.html
|
||||||
- http://self-issued.info/docs/draft-ietf-jose-json-web-key.html
|
- http://self-issued.info/docs/draft-ietf-jose-json-web-key.html
|
||||||
- http://self-issued.info/docs/draft-jones-jose-json-private-key.html
|
- http://self-issued.info/docs/draft-jones-jose-json-private-key.html
|
||||||
|
- http://ed25519.cr.yp.to/
|
||||||
|
|
||||||
|
|
||||||
Comparison to .egg
|
Comparison to .egg
|
||||||
|
@ -328,29 +338,47 @@ Wheel defines a .data directory. Should I put all my data there?
|
||||||
This specification does not have an opinion on how you should organize
|
This specification does not have an opinion on how you should organize
|
||||||
your code. The .data directory is just a place for any files that are
|
your code. The .data directory is just a place for any files that are
|
||||||
not normally installed inside ``site-packages`` or on the PYTHONPATH.
|
not normally installed inside ``site-packages`` or on the PYTHONPATH.
|
||||||
|
In other words, you may continue to use ``pkgutil.get_data(package,
|
||||||
|
resource)`` even though *those* files will usually not be distributed
|
||||||
|
in *wheel's* ``.data`` directory.
|
||||||
|
|
||||||
Why are you using Ed25519 and JWS instead of PGP, S/MIME, or ECDSA?
|
Why are you using Ed25519 and JWS instead of PGP, S/MIME, or ECDSA?
|
||||||
Wheel's signing scheme is designed to protect against cryptography
|
Wheel's signing scheme is designed to protect against cryptography
|
||||||
that is not used. Wheel tries to encourage signing by making it very
|
that is not used. The system yields a tiny, performant pure-Python
|
||||||
fast and easy. Signature verification is encouraged by including
|
implementation that can just be included with the reference installer.
|
||||||
the signature in the archive itself rather than making it a separate
|
The 32-byte public keys are convienent to share directly in the
|
||||||
download, and by including a Python implementation of the entire
|
same way you would share a SHA-256 digest. Since the signatures
|
||||||
signing system in the reference implementation.
|
are inside the archive itself, they are more likely to be present
|
||||||
|
at install time compared to detached signatures.
|
||||||
|
|
||||||
JWS and Ed25519 yield small, pure-Python implementations. Ed25519
|
Wheel's signing system is designed to be used more like an md5 sum
|
||||||
is fast enough that public-key cryptography can be considered for
|
or a secure hash used to verify the integrity of an archive than
|
||||||
applications where it was traditionally too slow to be used, so
|
something like PGP or X.509 signatures. A secure hash can verify
|
||||||
wheels can be signed without worrying about performance. In Ed25519,
|
the integrity of a single archive, but a wheel signing key verifies
|
||||||
unlike ECDSA, only key generation, but not signing, depends on
|
the signer of all packages signed with that key. Once you know to
|
||||||
a continuing high-quality source of entropy. The combination of
|
expect a particular signing key, a signature-verifying installer
|
||||||
increased performance, convenience, and availability compared to
|
protects you from installing anything but intact packages from the
|
||||||
using a separate program means digital signatures can always be
|
expected signers. It makes no difference whether the wrong packages
|
||||||
enabled in wheel.
|
come from choosing the wrong package index, disk corruption, or an
|
||||||
|
actual attack; if a package is not signed with the expected key,
|
||||||
|
with its file contents matching their hashes in RECORD, then it will
|
||||||
|
not be installed.
|
||||||
|
|
||||||
|
Appendix
|
||||||
|
========
|
||||||
|
|
||||||
|
Example urlsafe-base64-nopad implementation::
|
||||||
|
|
||||||
|
# urlsafe-base64-nopad for Python 3
|
||||||
|
import base64
|
||||||
|
|
||||||
|
def urlsafe_b64encode_nopad(data):
|
||||||
|
return base64.urlsafe_b64encode(data).rstrip(b'=')
|
||||||
|
|
||||||
|
def urlsafe_b64decode_nopad(data):
|
||||||
|
pad = b'=' * (4 - (len(data) & 3))
|
||||||
|
return base64.urlsafe_b64decode(data + pad)
|
||||||
|
|
||||||
Wheel uses simplified keys and a signature system where key generation
|
|
||||||
is about as fast as signing, making it possible to consider signing
|
|
||||||
keys an abundant resource. Keys could represent a build server or
|
|
||||||
a package rather than the publisher's entire digital identity.
|
|
||||||
|
|
||||||
Copyright
|
Copyright
|
||||||
=========
|
=========
|
||||||
|
|
Loading…
Reference in New Issue