From fc0bac34a580373eb8ecdb06887b29eb6c78aeb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Tue, 31 Oct 2023 00:17:13 +0100 Subject: [PATCH] doc: Various improvements --- doc/code-isolation.md | 2 +- doc/configuration.md | 14 ++++-- doc/faq.md | 8 ++-- doc/index.md | 2 +- doc/installation.md | 36 +++++++------- doc/phar-signing.md | 98 +++++++++++++++++++++----------------- doc/reproducible-builds.md | 28 +++++------ doc/requirement-checker.md | 8 ++-- doc/symfony.md | 4 +- doc/usage.md | 2 +- mkdocs.yaml | 4 ++ 11 files changed, 114 insertions(+), 92 deletions(-) diff --git a/doc/code-isolation.md b/doc/code-isolation.md index cb89f6376..d4db45579 100644 --- a/doc/code-isolation.md +++ b/doc/code-isolation.md @@ -14,7 +14,7 @@ conflicts. To illustrate that issue with an example: we are building a console application `myapp.phar` which relies on the library Symfony YAML 2.8.0 which execute a given PHP script. -```bash +```shell # Usage of the application we are building myapp.phar myscript.php ``` diff --git a/doc/configuration.md b/doc/configuration.md index e741ac76e..fe8048dc1 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -770,12 +770,17 @@ available: - `SHA1` - `SHA256` - `SHA512` -- `OPENSSL` +- `OPENSSL` (deprecated) -By default PHARs are `SHA1` signed. +By default, PHARs are `SHA1` signed. The `OPENSSL` algorithm will require to provide [a key][key]. +!!! warning + + The OpenSSL signature has been deprecated as of Box 4.4.0. If you are wondering why check out + [the signing best practices]. + ### The private key (`key`) @@ -825,7 +830,9 @@ With the configuration excerpt: Then the `Phar::getMetadata()` will return `['application_version' => '1.0.0-dev']` array. -**CAUTION**: Your callable function must be readable by your autoloader. +!!! warning + + Your callable function must be readable by your autoloader. That means, for Composer, in previous example, we require to have such kind of declaration in your `composer.json` file. @@ -1044,6 +1051,7 @@ The short commit hash will only be used if no tag is available. [requirement-checker]: requirement-checker.md#requirements-checker [security]: #security [shebang]: #shebang-shebang +[the signing best practices]: ./phar-signing.md#phar-signing-best-practices [stub-stub]: #stub-stub [stub]: #stub [symfony-finder]: https://symfony.com/doc/current//components/finder.html diff --git a/doc/faq.md b/doc/faq.md index a839d73c6..ed1057c64 100644 --- a/doc/faq.md +++ b/doc/faq.md @@ -58,10 +58,10 @@ if (false === in_array(PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) { The shebang `#!/usr/bin/env php` is required to the auto-detection of the type of the script. This allows to use it as follows: -```bash -$ chmod +x bin/acme.php -$ ./bin/acme.php -$ php bin/acme.php # still works +```shell +chmod +x bin/acme.php +./bin/acme.php +php bin/acme.php # still works # Without the shebang line, you can only use the latter ``` diff --git a/doc/index.md b/doc/index.md index 96f699d63..3e8b81331 100644 --- a/doc/index.md +++ b/doc/index.md @@ -55,7 +55,7 @@ box help The project provides a `Makefile` in which the most common commands have been registered such as fixing the coding style or running the test. -```bash +```shell make ``` diff --git a/doc/installation.md b/doc/installation.md index f850d9994..bfda1de55 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -17,14 +17,14 @@ The preferred method of installation is to use the Box PHAR which can be downloa You can install Box with [Phive][phive] -```bash -$ phive install humbug/box +```shell +phive install humbug/box ``` To upgrade `box` use the following command: -```bash -$ phive update humbug/box +```shell +phive update humbug/box ``` @@ -32,39 +32,39 @@ $ phive update humbug/box You can install Box with [Composer][composer]: -```bash -$ composer global require humbug/box +```shell +composer global require humbug/box ``` If you cannot install it because of a dependency conflict or you prefer to install it for your project, we recommend you to take a look at [bamarni/composer-bin-plugin][bamarni/composer-bin-plugin]. Example: -```bash -$ composer require --dev bamarni/composer-bin-plugin -$ composer bin box require --dev humbug/box +```shell +composer require --dev bamarni/composer-bin-plugin +composer bin box require --dev humbug/box -$ vendor/bin/box +vendor/bin/box ``` ## Homebrew To install box using [Homebrew](https://brew.sh), you need to tap the box formula first -```bash -$ brew tap box-project/box -$ brew install box +```shell +brew tap box-project/box +brew install box ``` The `box` command is now available to run from anywhere in the system: -```bash -$ box -v +```shell +box -v ``` To upgrade `box` use the following command: -```bash -$ brew upgrade box +```shell +brew upgrade box ``` ## GitHub @@ -73,7 +73,7 @@ You may download the Box PHAR directly from the [GitHub release][releases] direc You should however beware that it is not as secure as downloading it from the other mediums. Hence, it is recommended to check the signature when doing so: -``` +```shell # Do adjust the URL based on the latest release wget -O box.phar "https://github.com/box-project/box/releases/download/4.4.0/box.phar" wget -O box.phar.asc "https://github.com/box-project/box/releases/download/4.4.0/box.phar.asc" diff --git a/doc/phar-signing.md b/doc/phar-signing.md index 8015f4f6a..685a4f15f 100644 --- a/doc/phar-signing.md +++ b/doc/phar-signing.md @@ -1,16 +1,16 @@ # PHAR signing best practices 1. [Built-in PHAR API](#built-in-phar-api) - 1. [How to sign your PHAR](#how-to-sign-your-phar) - 1. [How it works](#how-it-works) - 1. [Why it is bad](#why-it-is-bad) + 1. [How to sign your PHAR](#how-to-sign-your-phar) + 1. [How it works](#how-it-works) + 1. [Why it is bad](#why-it-is-bad) 1. [How to (properly) sign your PHAR](#how-to-properly-sign-your-phar) - 1. [Create a new GPG-key](#create-a-new-gpg-key) - 1. [Manually signing](#manually-signing) - 1. [Generate the encryption key](#generate-the-encryption-key) - 1. [Secure your encryption key](#secure-your-encryption-key) - 1. [Sign your PHAR](#sign-your-phar) - 1. [Verifying the PHAR signature](#verifying-the-phar-signature) + 1. [Create a new GPG-key](#create-a-new-gpg-key) + 1. [Manually signing](#manually-signing) + 1. [Generate the encryption key](#generate-the-encryption-key) + 1. [Secure your encryption key](#secure-your-encryption-key) + 1. [Sign your PHAR](#sign-your-phar) + 1. [Verifying the PHAR signature](#verifying-the-phar-signature) 1. [Automatically sign in GitHub Actions](#automatically-sign-in-github-actions) There is two idiomatic ways to secure a PHAR: @@ -35,8 +35,8 @@ $phar->setSignatureAlgorithm($algo, $privateKey); There is various algorithm available. The most "secure" one would be `Phar::OPENSSL` with an OpenSSL private key. For instance: -``` -$ openssl genrsa -des3 -out acme-phar-private.pem 4096 +```shell +openssl genrsa -des3 -out acme-phar-private.pem 4096 ``` ```php @@ -94,7 +94,7 @@ there is ways to void the signature: file (the public key), but in the context the attacker could inject code to the PHAR this is unlikely to be a real prevention measure. -So to conclude, **this security mechanism CANNOT prevent modifications of the archive itself.** It is NOT a reliable +So to conclude, **this security mechanism CANNOT prevent modifications of the archive itself.** It is **NOT** a reliable protection measure. The good news, there is a solution. @@ -106,14 +106,15 @@ The good news, there is a solution. The first step is to create a new GPG-key. You can either do that via a GUI or via the CLI like this: -``` -$ gpg --gen-key +```shell +gpg --gen-key ``` It will ask for some questions. It is recommended to use a passphrase (ideally generated and managed by a reputable password manager). In the end, you will end up with something like this: ``` +# $ gpg --gen-key output pub ed25519 2023-10-21 [SC] [expires: 2026-10-20] 96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08 uid Théo Fidry @@ -123,8 +124,8 @@ sub cv25519 2023-10-21 [E] [expires: 2026-10-20] In this case the interesting part is `96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08` which is the key ID. You can also check the list of your GPG keys like so: -``` -$ gpg --list-secret-keys --keyid-format=long +```shell +gpg --list-secret-keys --keyid-format=long # # Other keys displayed too @@ -135,22 +136,24 @@ uid [ultimate] Théo Fidry keys.asc -$ gpg --export-secret-key --armor 96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08 >> keys.asc +```shell +gpg --export --armor 96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08 > keys.asc +gpg --export-secret-key --armor 96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08 >> keys.asc ``` -That will leave the public and private key in a single file. Anyone that has that file can sign on your behalf! So keep -that file secure at all times and make sure it never accidentally shows up in your git repository! +!!! warning + + That will leave the public and private key in a single file. Anyone that has that file can sign on your behalf! So keep + that file secure at all times and make sure it never accidentally shows up in your git repository. ### Secure your encryption key @@ -196,9 +201,9 @@ it is better to not keep that decrypted key around. You first need to encrypt `keys.asc.gpg` into `keys.asc`: -``` +```shell # If you are locally: -$ gpg keys.asc.gpg +gpg keys.asc.gpg # In another environment: CI or other. You should use an environment variable # or a temporary file to avoid printing the password in clear text. echo $DECRYPT_KEY_PASSPHRASE | gpg --passphrase-fd 0 keys.asc.gpg @@ -208,14 +213,14 @@ cat $(.decrypt-key-passphrase) | gpg --passphrase-fd 0 keys.asc.gpg Import the decrypted key if it is not already present on the machine: -``` -$ gpg --batch --yes --import keys.asc +```shell +gpg --batch --yes --import keys.asc ``` Sign your file: -``` -$ gpg \ +```shell +gpg \ --batch \ --passphrase="$GPG_KEY_96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08_PASSPHRASE" \ --local-user 96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08 \ @@ -241,12 +246,12 @@ documentation: gpg --keyserver hkps://keys.openpgp.org --recv-keys 96C8013A3CC293C465EE3FBB03B2F4DF7A20DF08 ``` -However not everyone expose what is their GPG key ID. So sometimes to avoid bad surprises, you +However not everyone exposes what is their GPG key ID. So sometimes to avoid bad surprises, you can look up for similar issuers to the key ID given by the `.asc`: -``` +```shell # Verify the signature -$ gpg --verify bin/command.phar.asc bin/command.phar +gpg --verify bin/command.phar.asc bin/command.phar # Example of output: gpg: Signature made Sat 21 Oct 16:58:05 2023 CEST @@ -256,19 +261,21 @@ gpg: Good signature from "Théo Fidry save($file, Phar::SHA512); Then once your PHAR is built: -``` -$ php resign.php app.phar +```shell +php resign.php app.phar ``` -This is obviously not ideal and should be fixed by Box at some point (see https://github.com/box-project/box/issues/1074). +This is obviously not ideal and should be fixed by Box at some point (see [#1074](https://github.com/box-project/box/issues/1074)).
diff --git a/doc/requirement-checker.md b/doc/requirement-checker.md index 49ffb34e2..fd43095e2 100644 --- a/doc/requirement-checker.md +++ b/doc/requirement-checker.md @@ -130,8 +130,8 @@ When the requirement checker is shipped, you can always skip it by setting the e `BOX_REQUIREMENT_CHECKER` to `0`. For example if you are using the `box.phar` which ships a requirement checker and want to skip it, you can run: -``` -$ BOX_REQUIREMENT_CHECKER=0 php box.phar +```shell +BOX_REQUIREMENT_CHECKER=0 php box.phar ``` @@ -140,8 +140,8 @@ $ BOX_REQUIREMENT_CHECKER=0 php box.phar Since version 3.17.0, box logs the requirements checker output to `stderr` per default (see: [#678](https://github.com/box-project/box/issues/678)). The requirements checker can be configured to output to `stdout` instead by setting `BOX_REQUIREMENTS_CHECKER_LOG_TO_STDOUT=1`: -``` -$ BOX_REQUIREMENTS_CHECKER_LOG_TO_STDOUT=1 php box.phar +```shell +BOX_REQUIREMENTS_CHECKER_LOG_TO_STDOUT=1 php box.phar ``` diff --git a/doc/symfony.md b/doc/symfony.md index 373939750..883db9772 100644 --- a/doc/symfony.md +++ b/doc/symfony.md @@ -55,8 +55,8 @@ To achieve this with the least amount of changes is to: - Create the `.env.local.php` file by running the following command: -``` -$ composer dump-env prod +```shell +composer dump-env prod ``` This will ensure when loading the variables that your application is in production mode. diff --git a/doc/usage.md b/doc/usage.md index 81b6e3061..da07db71d 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -13,7 +13,7 @@ You can then find more advanced configuration settings in [the configuration doc For more information on which command or options is available, you can run: ``` -$ box help +box help ```
diff --git a/mkdocs.yaml b/mkdocs.yaml index 8834f95ab..033ce1438 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -33,6 +33,7 @@ theme: primary: brown accent: amber features: + - content.tabs.link - navigation.tabs - navigation.top custom_dir: doc/overrides @@ -55,8 +56,11 @@ nav: markdown_extensions: - admonition - attr_list + - footnotes - pymdownx.highlight - pymdownx.superfences + - toc: + permalink: true extra_css: - assets/announce.css