From 558c7de0ddf84198296bdc0c28cf3cfc04028516 Mon Sep 17 00:00:00 2001 From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com> Date: Sun, 15 Feb 2026 17:29:34 -0800 Subject: [PATCH 01/51] feat: add build architecture article (#296) --- content/articles/BUILD_ARCHITECTURE.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 content/articles/BUILD_ARCHITECTURE.md diff --git a/content/articles/BUILD_ARCHITECTURE.md b/content/articles/BUILD_ARCHITECTURE.md new file mode 100644 index 0000000..0be25f2 --- /dev/null +++ b/content/articles/BUILD_ARCHITECTURE.md @@ -0,0 +1,25 @@ +--- +title: "Build Architecture | secureblue" +description: "Build architecture for secureblue" +permalink: /articles/build-architecture +--- + +# Build Architecture + +Supply chain security is a priority for secureblue. During the the build process, we use complementary security mechanisms to protect against a variety of supply chain attack vectors. The documentation below covers each of these mechanisms, the protections they provide, and where secureblue uses these mechanisms. + +## Definitions + +| Security mechanism | Implementation tooling | Threat vectors | Mitigation logic | Scope | +|------------|---------------------------------------|-------------------------|--------------|---------------------------------| +| Provenance | [SLSA](https://slsa.dev) |
+
From 0b7c26f308c882e3a10c4d15de8915b8afc21dc4 Mon Sep 17 00:00:00 2001
From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com>
Date: Sun, 15 Feb 2026 17:37:34 -0800
Subject: [PATCH 02/51] fix
---
content/articles/ARTICLES.md | 1 +
content/articles/BUILD_ARCHITECTURE.md | 11 +++++------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/content/articles/ARTICLES.md b/content/articles/ARTICLES.md
index 233d41d..342b8ad 100644
--- a/content/articles/ARTICLES.md
+++ b/content/articles/ARTICLES.md
@@ -13,3 +13,4 @@ Other articles on assorted topics related to secureblue:
- [User Namespaces](/articles/userns) - Brief overview of unprivileged User Namespaces, the security risk they enabled and how secureblue handles that risk.
- [Kernel Arguments](/articles/kargs) - List and brief explanation of the hardening kargs that the `ujust set-kargs-hardening` command can set.
- [Flatpak](/articles/flatpak) - Flatpak: the good, the bad, the ugly.
+- [Build Architecture](/articles/build-architecutre) - Build architecture for secureblue
diff --git a/content/articles/BUILD_ARCHITECTURE.md b/content/articles/BUILD_ARCHITECTURE.md
index 0be25f2..cfb5efe 100644
--- a/content/articles/BUILD_ARCHITECTURE.md
+++ b/content/articles/BUILD_ARCHITECTURE.md
@@ -8,15 +8,14 @@ permalink: /articles/build-architecture
Supply chain security is a priority for secureblue. During the the build process, we use complementary security mechanisms to protect against a variety of supply chain attack vectors. The documentation below covers each of these mechanisms, the protections they provide, and where secureblue uses these mechanisms.
-## Definitions
+## Security mechanisms
| Security mechanism | Implementation tooling | Threat vectors | Mitigation logic | Scope |
|------------|---------------------------------------|-------------------------|--------------|---------------------------------|
-| Provenance | [SLSA](https://slsa.dev) | zincati.service before rebasing to securecore.' %}
| Name | Base | NVIDIA Support | ZFS Support | ARM64 Support |
@@ -92,6 +98,7 @@ Note that there are no ISOs available for experimental images. If you want to tr
| `securecore-zfs-nvidia-open-hardened` | CoreOS | Yes, open drivers | Yes | No |
### [IoT](#iot)
+{: #iot}
| Name | Base | NVIDIA Support | ZFS Support | ARM64 Support |
|------------------------------------|-----------|-------------------------|-------------|------------------------|
diff --git a/content/INDEX.md b/content/INDEX.md
index 05dccb8..385b25d 100644
--- a/content/INDEX.md
+++ b/content/INDEX.md
@@ -5,13 +5,16 @@ permalink: /
---
## [About](#about)
+{: #about}
secureblue is a security-focused desktop and server Linux operating system, developed as an open-source project. It is shipped as a set of [OCI](https://en.wikipedia.org/wiki/Open_Container_Initiative) bootable container images, which are generated with [BlueBuild](https://blue-build.org/), using [Fedora Atomic Desktop](https://fedoraproject.org/atomic-desktops/)'s [base images](https://pagure.io/workstation-ostree-config) as a starting point. Fedora is one of the few Linux distributions that ships with SELinux and associated tooling built-in and enabled by default. This makes it advantageous as a starting point for building a secure desktop system. However, the security architecture of desktop Linux is broadly and significantly lacking. The goal of secureblue is to build a maximally secure Linux operating system by proactively increasing defenses against the exploitation of both known and unknown vulnerabilities, while avoiding sacrificing usability for most use cases where possible. For more details, see the [features list](/features).
## [Who is secureblue for?](#who-is-secureblue-for)
+{: #who-is-secureblue-for}
secureblue is for those whose first priority is using Linux, and second priority is security. secureblue does not claim to be the most secure option available on the desktop. We are limited in that regard by the current state of desktop Linux standardization, tooling, and upstream security development. What we aim for instead is to be the most secure option for those who already intend to use Linux. As such, if security is your first priority, secureblue may not be the best option for you.
## [Support and community](#support-and-community)
+{: #support-and-community}
Both [GitHub issues](https://github.com/secureblue/secureblue/issues) and [Discord](https://discord.gg/qMTv5cKfbF) are available for support from the secureblue community.
diff --git a/content/articles/BUILD_ARCHITECTURE.md b/content/articles/BUILD_ARCHITECTURE.md
index cfb5efe..eb68001 100644
--- a/content/articles/BUILD_ARCHITECTURE.md
+++ b/content/articles/BUILD_ARCHITECTURE.md
@@ -4,11 +4,22 @@ description: "Build architecture for secureblue"
permalink: /articles/build-architecture
---
-# Build Architecture
+# Build architecture
+
+## [Table of Contents](#table-of-contents)
+{: #table-of-contents}
+
+- [Introduction](#introduction)
+- [Security mechanisms](#security-mechanisms)
+- [Build Process](#build-process)
+
+## [Introduction](#introduction)
+{: #introduction}
Supply chain security is a priority for secureblue. During the the build process, we use complementary security mechanisms to protect against a variety of supply chain attack vectors. The documentation below covers each of these mechanisms, the protections they provide, and where secureblue uses these mechanisms.
-## Security mechanisms
+## [Security mechanisms](#security-mechanisms)
+{: #security-mechanisms}
| Security mechanism | Implementation tooling | Threat vectors | Mitigation logic | Scope |
|------------|---------------------------------------|-------------------------|--------------|---------------------------------|
@@ -17,7 +28,8 @@ Supply chain security is a priority for secureblue. During the the build process
| Egress auditing|[StepSecurity Harden-Runner](https://docs.stepsecurity.io/harden-runner)|Maintainer secrets exfiltration, Source code tampering, Dependency tampering, Registry credential theft |StepSecurity Harden-Runner provides network traffic controls and source code integrity monitoring, among other mechanisms. It restricts outbound traffic to a configurable list of authorized outbound domains, and enforces this at multiple levels (DNS, HTTPS, network layer, transport layer). It has several other functions as well, like monitoring the source code as the build progresses to ensure tampering doesn't occur, monitoring for anomalous privileged processes, etc.|All secureblue OCI image builds, Trivalent RPM builds|
| Branch protection | [GitHub Rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets) | Maintainer source code repository credential theft, Rogue maintainers | Branch protection via rulesets prevents any changes being made to secureblue source code without those changes first meeting specific criteria. Among those criteria is a minimum number of code reviews from maintainers, excluding of course the author of the pull request should they be a maintainer. This means that in the event that a maintainer's source code repository credentials were stolen, the thief would be unable to push changes to the repository. This includes the repo owner credentials, since bypassing rulesets is only possible after 2FA has been granted. |All secureblue source code repositories|
-## Build Process
+## [Build Process](#build-process)
+{: #build-process}
diff --git a/content/articles/KARGS.md b/content/articles/KARGS.md
index 773cd1b..ee364b1 100644
--- a/content/articles/KARGS.md
+++ b/content/articles/KARGS.md
@@ -4,8 +4,10 @@ description: "An overview of the hardened boot kargs used in secureblue"
permalink: /articles/kargs
---
-# Table of contents
+# User namespaces
+
+## [Table of Contents](#table-of-contents)
{: #table-of-contents}
- [Introduction](#introduction)
@@ -15,7 +17,8 @@ permalink: /articles/kargs
- [Force disable simultaneous multithreading](#smt)
- [Unstable kargs](#unstable)
-# Introduction
+## [Introduction](#introduction)
+{: #introduction}
On secureblue and other systems that use `rpm-ostree`, kernel arguments (kargs)
can be managed using `rpm-ostree kargs`. Run `rpm-ostree kargs --help` for usage
@@ -29,7 +32,8 @@ To remove all kernel arguments that secureblue adds, you can run
For details on what each kernel argument does, see
[the kernel documentation](https://www.kernel.org/doc/html/v6.17/admin-guide/kernel-parameters.html).
-# Standard
+## [Standard](#standard)
+{: #standard}
Stable kernel arguments that are set by default on a fresh secureblue
installation, and are always applied by the script `ujust set-kargs-hardening`.
@@ -87,30 +91,28 @@ installation, and are always applied by the script `ujust set-kargs-hardening`.
- `vsyscall=none`: Disable vsyscall as it is both obsolete and enables an ROP
attack vector.
-# Additional
+## [Additional](#additional)
+{: #additional}
Sets of additional kargs that can be selectively set alongside the standard
kargs detailed above. The `set-kargs-hardening` command prompts the user on
whether to add apply of the 3 sets of kargs detailed below:
-## Disable 32-bit processes and syscalls
-
+### Disable 32-bit processes and syscalls
{: #32bit}
{% include alert.html type='note' content='32-bit support is needed by some legacy software, such as Steam.' %}
- `ia32_emulation=0`: Disables 32-bit processes and syscalls.
-## Force disable simultaneous multithreading
-
+### Force disable simultaneous multithreading
{: #smt}
- `nosmt=force`: Disables this hardware feature on user request, regardless of
whether it is affected by known vulnerabilities. Note that this
[halves the number of CPU cores](/faq#smt).
-## Unstable kargs
-
+### Unstable kargs
{: #unstable}
{% include alert.html type='caution' content='These may cause issues on some hardware.' %}
From 82c3aca13bb0a77ff5976cec6f8473ceb39b3d5a Mon Sep 17 00:00:00 2001
From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com>
Date: Sun, 15 Feb 2026 17:49:11 -0800
Subject: [PATCH 06/51] typo
---
content/articles/ARTICLES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/articles/ARTICLES.md b/content/articles/ARTICLES.md
index 342b8ad..9d17583 100644
--- a/content/articles/ARTICLES.md
+++ b/content/articles/ARTICLES.md
@@ -13,4 +13,4 @@ Other articles on assorted topics related to secureblue:
- [User Namespaces](/articles/userns) - Brief overview of unprivileged User Namespaces, the security risk they enabled and how secureblue handles that risk.
- [Kernel Arguments](/articles/kargs) - List and brief explanation of the hardening kargs that the `ujust set-kargs-hardening` command can set.
- [Flatpak](/articles/flatpak) - Flatpak: the good, the bad, the ugly.
-- [Build Architecture](/articles/build-architecutre) - Build architecture for secureblue
+- [Build Architecture](/articles/build-architecture) - Build architecture for secureblue
From 3b419c03964af1894b65c647db35590069520c8b Mon Sep 17 00:00:00 2001
From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com>
Date: Sun, 15 Feb 2026 17:55:05 -0800
Subject: [PATCH 07/51] formatting fixes
---
_headers | 2 +-
content/articles/BUILD_ARCHITECTURE.md | 46 +++++++++++++++++++++-----
2 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/_headers b/_headers
index a0589cb..1f8e13d 100644
--- a/_headers
+++ b/_headers
@@ -10,4 +10,4 @@
/articles/build-architecture
! Content-Security-Policy
- Content-Security-Policy: default-src 'none'; style-src 'self'; style-src-attr 'none'; font-src 'self'; img-src 'self' https://release-assets.githubusercontent.com; manifest-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'; sandbox; upgrade-insecure-requests;
+ Content-Security-Policy: default-src 'none'; style-src 'self'; style-src-attr 'none'; font-src 'self'; img-src 'self' https://github.com https://release-assets.githubusercontent.com; manifest-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'; sandbox; upgrade-insecure-requests;
diff --git a/content/articles/BUILD_ARCHITECTURE.md b/content/articles/BUILD_ARCHITECTURE.md
index eb68001..f350321 100644
--- a/content/articles/BUILD_ARCHITECTURE.md
+++ b/content/articles/BUILD_ARCHITECTURE.md
@@ -10,25 +10,53 @@ permalink: /articles/build-architecture
{: #table-of-contents}
- [Introduction](#introduction)
-- [Security mechanisms](#security-mechanisms)
-- [Build Process](#build-process)
+- [Definitions](#definitions)
+- [Mitigation logic](#mitigation-logic)
+ - [Provenance](#provenance)
+ - [Signatures](#signatures)
+ - [Egress auditing](#egress-auditing)
+ - [Branch protection](#branch-protection)
+- [Build rocess](#build-process)
## [Introduction](#introduction)
{: #introduction}
Supply chain security is a priority for secureblue. During the the build process, we use complementary security mechanisms to protect against a variety of supply chain attack vectors. The documentation below covers each of these mechanisms, the protections they provide, and where secureblue uses these mechanisms.
-## [Security mechanisms](#security-mechanisms)
-{: #security-mechanisms}
+## [Definitions](#definitions)
+{: #definitions}
| Security mechanism | Implementation tooling | Threat vectors | Mitigation logic | Scope |
|------------|---------------------------------------|-------------------------|--------------|---------------------------------|
-| Provenance | [SLSA](https://slsa.dev) | Maintainer signing key theft, Rogue maintainers | To generate provenance, the build platform (in our case, GitHub Actions) generates and signs an attestation file containing metadata about the build environment. Crucially, it cryptographically attests to the authenticity of runner and the source commit on which the artifact is being built. This attestation is then published in the repository or registry alongside the artifact. On the client side, when the artifact is pulled, the signature of the attestation is validated against the build platform's public key and the contents of the attestation are validated to confirm that the artifact was built: on an authorized runner from a commit in a specific branch in the source repository protected by branch policies, pull request review, and maintainer login 2FA. This means that even in the event that a maintainer's artifact signing keys and artifact repository credentials were both stolen, any malicious builds pushed by the credential thief would be rejected by clients due to provenance validation. | All secureblue [OCI](https://opencontainers.org/) images, Trivalent RPM packages, Blue-Build build tools |
-| Signatures | [cosign](https://github.com/sigstore/cosign), [GPG](https://gnupg.org/) | Artifact tampering, Artifact forgery, Registry credential theft | A private key owned by the artifact maintainer is used in combination with a [hash](https://en.wikipedia.org/wiki/Cryptographic_hash_function) of the artifact to compute a [signature](https://en.wikipedia.org/wiki/Digital_signature). The signature is then provided alongside the artifact so that clients can verify the artifact signature before installing or using the artifact. For example, for our ISOs, each signature is shipped in a corresponding `-CHECKSUM` file. Once the client has all of the required information, it can use the maintainer's public key to verify the signature, revealing a hash that it then compares against a locally-generated hash of the artifact. This means that in the event that an artifact registry was compromised or artifacts otherwise tampered with by malicious third parties, any corresponding signature file would either not be present or fail validation. | All secureblue [OCI](https://opencontainers.org/) images, all secureblue ISOs and torrents, all secureblue RPM packages, all Fedora RPM packages, all Flatpaks from Flathub ([centrally signed](https://flathub.org/repo/flathub.gpg)), Blue-Build build tools |
-| Egress auditing|[StepSecurity Harden-Runner](https://docs.stepsecurity.io/harden-runner)|Maintainer secrets exfiltration, Source code tampering, Dependency tampering, Registry credential theft |StepSecurity Harden-Runner provides network traffic controls and source code integrity monitoring, among other mechanisms. It restricts outbound traffic to a configurable list of authorized outbound domains, and enforces this at multiple levels (DNS, HTTPS, network layer, transport layer). It has several other functions as well, like monitoring the source code as the build progresses to ensure tampering doesn't occur, monitoring for anomalous privileged processes, etc.|All secureblue OCI image builds, Trivalent RPM builds|
-| Branch protection | [GitHub Rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets) | Maintainer source code repository credential theft, Rogue maintainers | Branch protection via rulesets prevents any changes being made to secureblue source code without those changes first meeting specific criteria. Among those criteria is a minimum number of code reviews from maintainers, excluding of course the author of the pull request should they be a maintainer. This means that in the event that a maintainer's source code repository credentials were stolen, the thief would be unable to push changes to the repository. This includes the repo owner credentials, since bypassing rulesets is only possible after 2FA has been granted. |All secureblue source code repositories|
+| Provenance | [SLSA](https://slsa.dev) | Maintainer signing key theft, Rogue maintainers | All secureblue [OCI](https://opencontainers.org/) images, Trivalent RPM packages, Blue-Build build tools |
+| Signatures | [cosign](https://github.com/sigstore/cosign), [GPG](https://gnupg.org/) | Artifact tampering, Artifact forgery, Registry credential theft | All secureblue [OCI](https://opencontainers.org/) images, all secureblue ISOs and torrents, all secureblue RPM packages, all Fedora RPM packages, all Flatpaks from Flathub ([centrally signed](https://flathub.org/repo/flathub.gpg)), Blue-Build build tools |
+| Egress auditing | [StepSecurity Harden-Runner](https://docs.stepsecurity.io/harden-runner) | Maintainer secrets exfiltration, Source code tampering, Dependency tampering, Registry credential theft | All secureblue OCI image builds, Trivalent RPM builds |
+| Branch protection | [GitHub Rulesets](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets) | Maintainer source code repository credential theft, Rogue maintainers | All secureblue source code repositories |
-## [Build Process](#build-process)
+## [Mitigation logic](#mitigation-logic)
+{: #mitigation-logic}
+
+## [Provenance](#provenance)
+{: #provenance}
+
+To generate provenance, the build platform (in our case, GitHub Actions) generates and signs an attestation file containing metadata about the build environment. Crucially, it cryptographically attests to the authenticity of runner and the source commit on which the artifact is being built. This attestation is then published in the repository or registry alongside the artifact. On the client side, when the artifact is pulled, the signature of the attestation is validated against the build platform's public key and the contents of the attestation are validated to confirm that the artifact was built: on an authorized runner from a commit in a specific branch in the source repository protected by branch policies, pull request review, and maintainer login 2FA. This means that even in the event that a maintainer's artifact signing keys and artifact repository credentials were both stolen, any malicious builds pushed by the credential thief would be rejected by clients due to provenance validation.
+
+## [Signatures](#signatures)
+{: #signatures}
+
+A private key owned by the artifact maintainer is used in combination with a [hash](https://en.wikipedia.org/wiki/Cryptographic_hash_function) of the artifact to compute a [signature](https://en.wikipedia.org/wiki/Digital_signature). The signature is then provided alongside the artifact so that clients can verify the artifact signature before installing or using the artifact. For example, for our ISOs, each signature is shipped in a corresponding `-CHECKSUM` file. Once the client has all of the required information, it can use the maintainer's public key to verify the signature, revealing a hash that it then compares against a locally-generated hash of the artifact. This means that in the event that an artifact registry was compromised or artifacts otherwise tampered with by malicious third parties, any corresponding signature file would either not be present or fail validation.
+
+## [Egress auditing](#egress-auditing)
+{: #egress-auditing}
+
+StepSecurity Harden-Runner provides network traffic controls and source code integrity monitoring, among other mechanisms. It restricts outbound traffic to a configurable list of authorized outbound domains, and enforces this at multiple levels (DNS, HTTPS, network layer, transport layer). It has several other functions as well, like monitoring the source code as the build progresses to ensure tampering doesn't occur, monitoring for anomalous privileged processes, etc.
+
+## [Branch protection](#branch-protection)
+{: #branch-protection}
+
+Branch protection via rulesets prevents any changes being made to secureblue source code without those changes first meeting specific criteria. Among those criteria is a minimum number of code reviews from maintainers, excluding of course the author of the pull request should they be a maintainer. This means that in the event that a maintainer's source code repository credentials were stolen, the thief would be unable to push changes to the repository. This includes the repo owner credentials, since bypassing rulesets is only possible after 2FA has been granted.
+
+## [Build process](#build-process)
{: #build-process}
From cb6a3b74a3cfa660775b058611811fc743e27d3a Mon Sep 17 00:00:00 2001
From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com>
Date: Sun, 15 Feb 2026 17:55:28 -0800
Subject: [PATCH 08/51] fix columns
---
content/articles/BUILD_ARCHITECTURE.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/content/articles/BUILD_ARCHITECTURE.md b/content/articles/BUILD_ARCHITECTURE.md
index f350321..1c0e72c 100644
--- a/content/articles/BUILD_ARCHITECTURE.md
+++ b/content/articles/BUILD_ARCHITECTURE.md
@@ -26,7 +26,7 @@ Supply chain security is a priority for secureblue. During the the build process
## [Definitions](#definitions)
{: #definitions}
-| Security mechanism | Implementation tooling | Threat vectors | Mitigation logic | Scope |
+| Security mechanism | Implementation tooling | Threat vectors | Scope |
|------------|---------------------------------------|-------------------------|--------------|---------------------------------|
| Provenance | [SLSA](https://slsa.dev) | Maintainer signing key theft, Rogue maintainers | All secureblue [OCI](https://opencontainers.org/) images, Trivalent RPM packages, Blue-Build build tools |
| Signatures | [cosign](https://github.com/sigstore/cosign), [GPG](https://gnupg.org/) | Artifact tampering, Artifact forgery, Registry credential theft | All secureblue [OCI](https://opencontainers.org/) images, all secureblue ISOs and torrents, all secureblue RPM packages, all Fedora RPM packages, all Flatpaks from Flathub ([centrally signed](https://flathub.org/repo/flathub.gpg)), Blue-Build build tools |
From e2b5cc42618bc1969188380cdf9e872a776d15dd Mon Sep 17 00:00:00 2001
From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com>
Date: Sun, 15 Feb 2026 17:56:21 -0800
Subject: [PATCH 09/51] fix
---
_headers | 2 +-
content/articles/BUILD_ARCHITECTURE.md | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/_headers b/_headers
index 1f8e13d..475feae 100644
--- a/_headers
+++ b/_headers
@@ -10,4 +10,4 @@
/articles/build-architecture
! Content-Security-Policy
- Content-Security-Policy: default-src 'none'; style-src 'self'; style-src-attr 'none'; font-src 'self'; img-src 'self' https://github.com https://release-assets.githubusercontent.com; manifest-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'; sandbox; upgrade-insecure-requests;
+ Content-Security-Policy: default-src 'none'; style-src 'self'; style-src-attr 'none'; font-src 'self'; img-src 'self' https://github.com https://release-assets.githubusercontent.com; manifest-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'; sandbox allow-popups; upgrade-insecure-requests;
diff --git a/content/articles/BUILD_ARCHITECTURE.md b/content/articles/BUILD_ARCHITECTURE.md
index 1c0e72c..45ac0a3 100644
--- a/content/articles/BUILD_ARCHITECTURE.md
+++ b/content/articles/BUILD_ARCHITECTURE.md
@@ -36,22 +36,22 @@ Supply chain security is a priority for secureblue. During the the build process
## [Mitigation logic](#mitigation-logic)
{: #mitigation-logic}
-## [Provenance](#provenance)
+### [Provenance](#provenance)
{: #provenance}
To generate provenance, the build platform (in our case, GitHub Actions) generates and signs an attestation file containing metadata about the build environment. Crucially, it cryptographically attests to the authenticity of runner and the source commit on which the artifact is being built. This attestation is then published in the repository or registry alongside the artifact. On the client side, when the artifact is pulled, the signature of the attestation is validated against the build platform's public key and the contents of the attestation are validated to confirm that the artifact was built: on an authorized runner from a commit in a specific branch in the source repository protected by branch policies, pull request review, and maintainer login 2FA. This means that even in the event that a maintainer's artifact signing keys and artifact repository credentials were both stolen, any malicious builds pushed by the credential thief would be rejected by clients due to provenance validation.
-## [Signatures](#signatures)
+### [Signatures](#signatures)
{: #signatures}
A private key owned by the artifact maintainer is used in combination with a [hash](https://en.wikipedia.org/wiki/Cryptographic_hash_function) of the artifact to compute a [signature](https://en.wikipedia.org/wiki/Digital_signature). The signature is then provided alongside the artifact so that clients can verify the artifact signature before installing or using the artifact. For example, for our ISOs, each signature is shipped in a corresponding `-CHECKSUM` file. Once the client has all of the required information, it can use the maintainer's public key to verify the signature, revealing a hash that it then compares against a locally-generated hash of the artifact. This means that in the event that an artifact registry was compromised or artifacts otherwise tampered with by malicious third parties, any corresponding signature file would either not be present or fail validation.
-## [Egress auditing](#egress-auditing)
+### [Egress auditing](#egress-auditing)
{: #egress-auditing}
StepSecurity Harden-Runner provides network traffic controls and source code integrity monitoring, among other mechanisms. It restricts outbound traffic to a configurable list of authorized outbound domains, and enforces this at multiple levels (DNS, HTTPS, network layer, transport layer). It has several other functions as well, like monitoring the source code as the build progresses to ensure tampering doesn't occur, monitoring for anomalous privileged processes, etc.
-## [Branch protection](#branch-protection)
+### [Branch protection](#branch-protection)
{: #branch-protection}
Branch protection via rulesets prevents any changes being made to secureblue source code without those changes first meeting specific criteria. Among those criteria is a minimum number of code reviews from maintainers, excluding of course the author of the pull request should they be a maintainer. This means that in the event that a maintainer's source code repository credentials were stolen, the thief would be unable to push changes to the repository. This includes the repo owner credentials, since bypassing rulesets is only possible after 2FA has been granted.
From a678c3f67668eb8cba7a301ed204314929752a50 Mon Sep 17 00:00:00 2001
From: RoyalOughtness <129108030+RoyalOughtness@users.noreply.github.com>
Date: Sun, 15 Feb 2026 17:59:07 -0800
Subject: [PATCH 10/51] fixes
---
_headers | 2 +-
assets/architecture.png | Bin 0 -> 1483209 bytes
content/articles/BUILD_ARCHITECTURE.md | 4 ++--
3 files changed, 3 insertions(+), 3 deletions(-)
create mode 100644 assets/architecture.png
diff --git a/_headers b/_headers
index 475feae..88824e3 100644
--- a/_headers
+++ b/_headers
@@ -10,4 +10,4 @@
/articles/build-architecture
! Content-Security-Policy
- Content-Security-Policy: default-src 'none'; style-src 'self'; style-src-attr 'none'; font-src 'self'; img-src 'self' https://github.com https://release-assets.githubusercontent.com; manifest-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'; sandbox allow-popups; upgrade-insecure-requests;
+ Content-Security-Policy: default-src 'none'; style-src 'self'; style-src-attr 'none'; font-src 'self'; img-src 'self'; manifest-src 'self'; form-action 'none'; frame-ancestors 'none'; base-uri 'none'; sandbox allow-popups; upgrade-insecure-requests;
diff --git a/assets/architecture.png b/assets/architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2c88a80c548970763a73471b23e83e9862e3b9b
GIT binary patch
literal 1483209
zcmeFacT|&E*FJ17sGuNSiVaYt3n*1b0g)!sgisWuHzU0zqN5;HMS6*XbOGrlfv7a;
z0z&8!5JHck1qeyLlV@IMe8#8fn)e;ow|@NLGREZG=bYWHYwvwd9$wK@*+<7gw`tR+
zeX5r(Ufr~bGi}o*rnOx=z&oFhukwSx#4WF>T4`u(ItgCy+O%ae!=^3Z)z*vRn>KCU
z|Bu&u!N2*ypH1$f!qUQGLYI`zU)+?PYJLE`wb|vW$}gL8TMtcc+Qhp__2PM5Pt%#f
zH@i29?%kU2PJM1N!LqY)+xcazM}OGSb9Xjv-m-1ie%`T4 zG`2;A40x>evqKd7QbbV78KXt`-MdxgpDS6KPFnR +WePY?2nC&DEN6 Q7TH~H5CaWLWb2oeb zSzCcvANt__EqX>|^J*~tee#)i- Vc9)6*I~rN*9L% z<}}9D&gC!Vrh7@jhG;QHsTK*a%#o`Y6gZjEQ%oJ=0 DgM`??{!_SZS-4`f0%A~AdH>Nz^8mWMo2X>Pjnf;iD5z1SrwV!HWXm!{3muMD zi+(@SDs1A)cV61z#(C-St1uO1c7Roey7TjLTpYRKOd#`)?fKpO9B@{*KK)43cpV2g zxOhJI^srR5pti+@yqV>+{ms#)3H7O3ef^Qvr87s|S8dnit00)Ga-uE#IR5krBgbx! zAC6i_Ne^6FJ4J25rkDGqC{zHoL^UF}Y9jvQ&fA;Ga}-~40dQbo)#m! `&@b8)avmR6LC9ID`++3~E;v|U;NQB?ojWhh8j_Rot zn82G@72Q7xA}WDhA=dm-;wXul4{NyiCAgHW;(XOX{P~*xzlf;d;Or+$)5e2L(l5mO z$|~hfVRyV;0(e(jzBQ6?NhERxXvK;s!&o2OXLz^V#O|8U9N->qA?az)Rd*c@$Z2@! z(KJet8I&apOwXvydus-{?IhR`4X!x*6Os7Ah!cjv0?MOy^Z!ZBUPWTSIFYc2&Sg^W zvMbB*m^g@(RI{!~(p-fxLpac9Huprox|F1fU^j&i_5g1ZkSaC;xJn$Ru@J(a6>un! zycc`NUlMU@d0bC&d}%R%Xq7wIuj0{JVbO%Mz$A^{d_zZBK*t^H*ctu@=?H%)&RNl0 z6q_0W()M=_*Pj5J^7WzmN7hKC1W2ewnBcJP57zfT--*uwY$TUoRQ)Gqcjd9AnVHX$ zy;!yGyQsl2?Qv>{O$YIJbL}<*Zn57SF!}_4S;AqKutcm1Gbb8dbB_UFD@&YpUmffB zkN!EfQXviqBV6T8_+3CJ_{5H`IlL#>MGdT+aq8NeVt?W%7+{N o495Q)&RbE$pxS!MVo9{UJfcnfGmud-*u5#$yV_*tn9&7wnhJSDaj=gIT ze(xCnIu29d4Dq%e=)|C76K2h3H>l7|^Ua9Yh}I8iC2tP8h_`VLUdKhjINc{;E4|C# zKX!aIFjmM7PWg3kFB0(JfAP!QRsds|t*2Y|{E0Q90v1DWWOwsgp?zyMjw5B?i_Ge* zlH))ZDvkW3c0VB4&vEG6FJC_jD!XRxJ$;sVwY{Jl(5axCvTzdb2^Ml=`Heg5gD0pK z`|G6yBb&h9H5e46oh{tO|M1?ChvB4u%hGH9z5U{zvjJ)M2niovb~L$sK7jP{+s%h* zFI4ZjM)-Q${nHn=9C~v8^hM&ZtLKQ1Y~tPin&A0g$6mdj!&HXIl)fCjrE{h-Z+aY~ ziqWvp2}KknAyWq(e^x8FR(Dg0S)z2|+7Qg~sOhcvk`0u^4c~D*irMDf>^ky*aeC(^ zy)5bXfYg0eWay2-z(5i8ku|ci`t(P%bs{9(SAUfB%^y{jkKeMdKAmq9dd*wI)>lK_ zl{L&CGDzI^Cj#0hBEq4z`)_uFuN>r53 |`LBdEI_5Y0wHHfMk@xa{g5rr3mnC7t zgzanIdQX$j=tt!LI@E7J9M8F@nG?>aFT6$%;4J^D$o=rq)6IYvc(=XXw)(xjlwfjm zo0IWJtBY8g5*$)lN9nm$i1`oar743x;>qp`ubHFkP~MvVR!8{5nTUi961Wbzh9ocj z_%U9D71<3Ky`P?tVO6DFR0RX;At_w=-TS}3fPNF8De*)73xBXK8{o0J0)SUUHo)U6 zdtpCpfX6q$umK+5fYSzeY=Fl%4DqdXw*ej-;PH(%`G!|Ez+(eEzF~+B@c4!yzI6>Z zERSz^<$nx3o(2^*6WuC(1e5fH$^-_sk5hna7)2~eo9}iAaSXpd%VCEBr*l*}_a1); zT L*0Du|JHXRw;H~v8Y9e95h0jZvpL`lw zC;=IA|FfF6k{8160e^e@{x~1}{cR^EFk#w1I&r<0X0Ag5+rfgFk$_%17#L+K&Vd1Q zn53=av`8{`3Dp0wRg|De%Dao+b_pvKPd7X5vY?XXdZd|i@S*0zo7fN <+>DVf)Ab8px4xiFn`w2Y=5R*pyf`Vz69PZ|MU$I zk{9)v{P=Sr&S>9X1WP1Z3psT85D5O6VqJS75Ps|Dq?C;WEvz0v2I8M=6QTP=8DDY% z@L{m4Ae`oBvS5M#z5_1psECh8RcveJB4h$;N2L2(@6Ck)P!E2wpCLWB# zE;u9j7Nwlr!Ln!*jvXK%2g48`0<7F83#KV#${}|Ew0wNu;)_4EwE?wHL>pP+EfBcF zefkV6i+h;bxv;+h{35^?ob0v(rqW@Jx`YL%1H5g|zcnDfozOR{`T8WFcK^(n^v{iT z+!1`&a%wMFmOW{D+pcW`dk+V(up|SfIbT_F?G9*>V9-&)JHy231(4Lppn?v(g#dS| zBBEefPTjZI<+L3PBV_ac9YERup$!oFPPjg^#0Cic4xcta=r<|_Z>wkngf>8E1B8BI zGyVM01_*6{(1ttqa|N>Dj(y{N;R4BqJN6q_`u}Tu=;w^QI?9ch&~G4rBPR44Hlp8% z3H{LA{0fyDF`?f%zZ)R50YV#rX&iHE!yWsLSZu_Eey5w)?vCY@3OgI41xd*mg{aRt z?{=lhfI}uJPj?q9tV}8k%ykt_mRBT|@*@kVmlhJK=;q(w+keLFA}A&tLCnqfW{^N> ziRPxc4D-}gN!WIC%e`~LV0S`&^^Cw*efP5um$CcE7i5|pR;|z93?El-&=Y~Z5fjq; zd!CblqXEtDYgW3wdYma$uL{jDYY3f?rZu;lhmSbkzTEgIa5wc{EkmgF%g6gu(3>V3 z9_qw7SeCna=bAMI@tXElrWVkEl4Z6hRkM;ikjsPNbj1!B&%uu`6X)(Ss8Mq`Mhtvt z<3+VLEbzymgOo$#&1E7Mb*t(ULYbrVd=pHG8^CU=Lfd;r{O8~_&H@f+*dlane#6(l z+S03K0sDF8ZvH!!*qz3eB{Oe!U(-G*Xglj(z?^iDPO*10hn2Te3aFV^S`bRRhdHS| zdT7XCw$4DSX|$!^R%l|mvDc++6B}gWH= Z6xcz_y(M zL+G!D{hf)FlL #QiaS zk13aKNM5jPl2jt}flW;;Dq9(Sx;&}rVAVplX3nh-e10MZU^eL C{Pm&Khz>cw6=93Rkw~!sb#Gw`ns>d}aA2JxK48+Jw2J^ApstV~~O_b5cOwKj3 zB^l_tqCInkk4f3EZY81J&p(!B->BwsvfL)A#Oxe*2VbXEZ`G8Y9%RzVs;?Upu2T~t zg}PJP?O|q6Z1;)f%}SzDp${NIvLmTVOZklf5mdqolCYg}I(uVez(DM!g;sA M7m#U^>9el8jt-E}ol|xi)sHzvP2Cvgy6ja6y_lU1b~Vr+J<}Q4mGbb{rbD zOR@JlIFI+-lFexw!1hf)L-Oy086e<4jP1vDIXZgiGg}P({Lh%%@WO=bZOZywdfWO{ zWt C3w> zK^1a(Lu`?5xky?{FQHkhN`E2Ffy!X&_!&@;#aVwZW^^fbzjc=bsN Nsc80Dt3p}1G#d8Ms5Wf9LR)QXn~I> zlH;QF I-H)GJ4)b+WTCpD6pDA^rXqkxLoaS|5)G~q`j!+=vu*w5nt>p*Nb!LuZRxX zA01@(cLyQ?RQ66;(2XyVB?}p!u)K7^(ofyaAt9@0yPR+mW2iEf<<0gO>jUQ1QALl7 z{o9PjYi}*2Q5laCGnRomjM>+ag0szntT|nIgB`Y!yM^mt)-BFY_aeC4_fu-vT*woc z?w4K(%$*+yEa6gE;pv1f467AHM;zp9 =Cfn!A`#m^ z==%6Jn#$bCf-d%V^UT$*Jh_^!u22x5CdrLK!L&l{MN8e-q+<0Ff-TyGAo&ARgDt5# z&Y>C~d&8b#$~?F|4ACv2>ehEg3oxt_`Kg_6^2;}S^7JJ0AVyQ;suQqO_S>!BB!CKI z8&Qu;)o_^iIX;F4(%h7%3$+(3_F`Q)>l`{#dHdsQ9j%)DS+5Ij6peWiGfo{A9lVg` zA?;5j-B;guVf-B7w(}1`7T9;ti{n_WG1>mn1EL?Ws0@(_?c~sJewwj3uxKis$D@5| zak`3E&UzduYU3qy1vACxO)-DJQI6C`waYR!wrOYX;m|H`h?`eXHGYJxC0ZH8p%q(l z1GTT-Ltrk|03kHj#UO`JIN }ACght;T><;xJqMb8sM1#uS^ZWBYgjr#NGkdcU zAx3EaGCK4lo+V*uYd2h8XN%!dlPW`#ietY28GF%1iq#A|YcqE~Q(P zx){DP`*+@QDYYCF+HO)&LWf*5&|mD{)Q^OD%Otu>ICJTRlsq`2m2{Q3=luh(C(g8S z4wOqx!<2exB%N%uqzmj;735Ujq#vv#qs_2`)lXRzJ~v?56QJiHznpIlQ(;_4%)V7= zH{b8iVSg)k+Hhq|Dy1c=D927l(0X8Ac!7HKRFrO>i>3Sf>8x7}myZKQ`N*~Y6#j04 z2-YhQ*zpHewMf_y=psORlz?E2(DkaM0&{Bw^zO|di{TTK1?a@)ZZRx0$z{m#WnsYy z!JX;h!WKN|6UR%mv-!AT)^ePpPDgrM!3qK@u&?Z(>DAmf={BxI6m+UJCw oU6cvBYh zZ6tNIRrwN>re9PWHmO^-Pdd-_q(qcc9K}pmFG(LfZL$I!I )e2&xpq9 zbR3rS>T=PS#!Mj5g>mx4@ Sb)P4S3V+v5_&-V-2!Qzni==SN}=MqUV3!PNap$E!nY_Cb7KN2mEByjeC%9=4; z4vjT_?b^+?Zzpp(GOyVWAldTv^N**AHKH?`dm<(S>!2qclW4td+5@>{IMI9qSyv`= z;Y 3z-z13YYl(FBopdIz*WNkKx0>AfE3jL$5dY{&@FR>*F9Cz?y7TUqBZiBO zHQ`2ZAvq ~*<#!g#ami8T$TGO+@Q*TOUA^wQ-NJcwlk8^#Tqa^jn`AUeL~oI=Yk z!CFAE_8TRpeZ*)^6;F Q6mb}Srk)sXn8ays%-MuK@a6dv|^?(Gu#;8 zG^bXbG_ym+FkdTgYKplZ&eDNyE<*dPsCkJCj-!I=Kk4r0^G#%h<@T83*U@w;1DW$p zDn?~lm~k)RrTJG@Qy+*Y(a?O-B ksLEu21Vi`u8yD0@+UgcH@yd3%C_!*V=t$}Uj<6np9NGWS^Lt;Aei!2z3F zu>x8VBqVP0(+EFkdfj8{;w)Q7_;`S00WafLlD4>EjEX_}1^0sa#}=Vu!#gF~VmnP| z=NcS1jC=Z~I3fx1pn}4$7Lhj9v1R!orkDKAXoiRer`{|`@01xrNGz}{2P=yjL6@Xe z?LK(*#>FSO0W(=;I!?-Ymj_4YN=}92X4JrC(|Z*5z@BmIQUeD#g1LWag8tYKIYJL? z7^kO+_*`}Jvu>5K5t&BfEa3}Ihbiji26(V0jT=j*5p%rCV)|QWq5Wt$cLvkA&GrOc z9|ND=38 O*4?Z0w*P(@^e0hPXt}Kg9=C@88b*dQG9$MKWBQ$@l5&4PrN4yNk9}tna zS2) F)}+|W_GhNjaho9JWULIGh<6;r{{&wS5^kA%4RpM X7h_W?4Q9xG=x{6Bh=KS-9MhjrN1eG3^Z$Ft$6H*={1I zAQdp9zY}f>k3){7!)T4?wJ9^GW8*nb8bsSvV?ExTv^jE>!Td>fm0@S;T=-Y+s?5VZ zY>27?q9g8SXt%^im}Yd&dUI$kRK6)WL_|jl=SK!9*TfWsTF#z NUXIPO %2sC;CIt%It`5V;&21In0}rj#9QGz@}NC#TsD^CCKp z(PcVbJUPQpHVaJ;Wpz0te4wxx%i0+0Hv)*52 EI zAHzR4$7lhHmfm_%GnzSYU~-TFE#^flSPqZZL4I_mo C+0p}dNDV+K;ga*3^HM8_e1Kp lwn;qzVMqlBdnpoG`WHdyE1)xILM~6BN0kP#uzf=!xVb h?| z5qi^VEM3^kTbd8DNb6S_nffkk7tv0SEjuV)IBGY_DY#&e)YS1w8Om+&*35z>xB)VE zO7A}bs!TViJcpW~Edm((;3!OxXUl(~9f26`T89|odJj@SFkxnzl%%&AFTc>t!N!!5 zZ=7qLRY|^nBX6NRo Q3umD|2QOSxDnh$ewrPG zh-g==4CI}YqT@@ Mi ze)ni{$ezR##K<~4t$@2%*1Ci#OMu<-*>TWIa3E$5h_S_7F(0#go1t?@n=1h`R9-34 z2-J?hk~jBGf =(3|iCORw?lhON8=o#Sx2eP^XymKikyik*B}6XVOM)%; zO@| EvPzCABG-I|O*2)>nX8}Xv@S4mWRbanATT+aj^0G$ zTf}lFyT_He*dD!j=u*F )?OhP*;mRKe9uNhAKMP#ssTqX$I^7wiGv~SennJf{i0y>@J$h36*{YKu*B0RQyPx z!vobXRm`h(R^W#w;fO_rdE1o*7__G{wc2w8lKZO2`V!`#Me|!@R3priPezBtMoFR@ z1o!x*F|98p(v|HHlwQlKc4KL5W!sr&l!y0M@D)8LVzsX3uHh3bKrijk?99t-?Z`KQ z3t`oKi6_543 7xqd6neSkw5#ik*_%P|h1m+LhiUe^#$p{}bdOz7TuFKnCwM zcnSfQlUZse?~m %?hMg=!7ySbv2u?#w|no+1sLb^Ou z+S?HkY}s4pr$HVe2B(mXlJ@9iMtMq|p=y@@D-&M8pt-y_pE6nKg$)^3Ak5PJAv10= z!ki}@?k-;dYP46Yx;+~k(kyi%8mH6=a?s74FYQ2!sA9Fs A9tI<(dBjdk?2S;mAd%Ol&tS7JR;8eX1drNUI4w<@262-=p~j3l rLi`OwU7G9JZ0art;eB>5N zImu{;M5+6 +d?M zpM3$JAht*})&L|WXaNJQ=xp~ObUl7|bTUG-HSOgj3=!&;Z8{*II5%J8c%}eVl|*Sg z7B&9b9}=6lo3S<)oC+p+h|fztf9D^L2Lr;gn(V+57VNWYzEAcl$+I>}=g$S3jmBs- zEzO8s+_&fQF9=`$q+B&Z!0FK?$JuekN8a( thO&!6at@0E=9tPkq9mJuPQ$oYkryl4lV z1hO9%}r->+X(CH*!>tFKosCC%FFgL^{DcGY3+F=`9b31_A>wUgvfaUg=LN3j}Id zHVHMNvD7nHN8*^=<`dm6=5M$?^$=kQ6TKv&Y#lKc3rf >ZBBAD~2N07dz7@9xFhg7|Lr!BQqC-ed2`h&NAp2Zr&;ulF|LwlqK~ zy?h5h8Sqy^{odp{29yOT%9HZBob2xclem2JspTGfu;aZ#J212Pfn(sj`}OmHtImJm zB-A8)IHaj+zmBW>V*o`JbSS0QacMjbr)7`>(Y8oul~)w;hfJ6p^!UrE2~a8#hMf8U z{(jiO9)drpZv!~7gK t~mE}mIrb$Ts+2|#?;qB+a!n*?*@i=b%Si~LB-aS4E z?<)c}5tsvt4v)SQ|H(?=Gq}PGK!i3(Q^|I~(B$f#5qs!sl>wzt3u;12BL1w_n@ZP_ zXVMKi>n`4kvk2=M;5)PBO<%zt-083faMGTmHKb1fB)J)* $2jbd?miKc?^r;G`$db+#1) z7%ItHV8UNkE{g%2sAdgXhf$0(IDKY%P 0*YIi@+0dU ;q 3& z1$nSqZ^QWcwduHF{QO+AV{v=K_*pAWIJDX@etvEJZWuos#?P-g ;F~br_is6`H|N!*th_(v5CR%r6#ncH326G|J>3IT*tx4 zn;?Rv9TWKZO6y+&@lVApfOuOymrB-%FDck-O4;fRzF3GINQijfCIW7-v6o8~NwSVI zo)^GxU0F+0{=3n9`c !3dwB^h+4=PHVNZD}Z_k@~H(mC?Qp3pF z((l;QLm;5|%J3Ne8j4*O1h=Cylzu5zzqA-d!eT+-uD&GKBCgPu&dy?Sz|xUlXbI+c zwdMv7b|3<3T_r|BmU+`n6=l>(9T(2uD?9?CnBujizwY-NR=xvBaA#)gIyNG{pOKRg z=)&G&ENb;Z9Ee=Yb-0_ZV>vVT0uJzbja )^g1|3BlgQmd%)T zgsX8o|KxwIHq(RscveRu>D88Rq+-p>zpidEVCs^E1-{=>?H7IC1&Wk-%?#gz&6Enb z%FRW|FS!6tWM5zS`wuCAS5pcK{^VkH0PJ8>XZ2Ob>A_~xbz;w7Oyc`T4*_8wO)Y%F zq}7hrEctIq3(DLoc2(yS$%qKpSkdiVOW`Qcxm5odcU;E$S<6MBU?fDi@xPxQcg$u$ z9gSodqgT^0F3W%onNI1TCqH{D?sT)T*#icG_8$2E1h*3_S0Ke8Q{*d2ob-VdkM8nc z2R@w#;&WjKW*zAB{R)%P<1jABf2ioZH~%9+!KEj*MI;Sqv$SO7I-nT0^G`9{)#i@? zS3fFr{k7V%hLdrLi5&%YGmJgC=8s0<%pM%NhNu4}VErE6v1uWTG(79L5P}r!5K@ke zjNnhcRX+T}kT~%E?*Qv}@E#EVI*5o^{-OL<$nyD9cBB|A-h`PW)(EflZTx-S+Hj zJMssebNjTh|60$j6&(7rKtXNlxQPER)^OzK#i^A7nAKL=;rDgbL<9kk*zg-4#=qAt zY!XW*YK9B{pWqBcr0WFe#9{5(?|;W4!eQ2b$2|N_ 0h$<*FwoR+6))# zUjg8Il_&H^j;#PimMQWr8L1a-C(+t7_)f8)bJ^@&47gs-&sz2Zz}Z{tfqzXn+!=L% zE^-X)sxSrUw>o7;jw|S1Z^vcZsvSIBpOEG_{X`FUD1WE*NPn*fY@C9}gMrlQDoDzp zTgMHCqaaH!6Z5#k>nnP$|HD3Pd^VX-%qprd& 9be+2W#_|! zfUe2*;UUF^%Ad8|)dFBn{b1qX&%W@p6<7nh^b;#!0he9L2@4J~DRoy?f4*BHZaat_ zK!@vs;#0t|di!(n57gWSdA_ilb&x*^Z=V8o%PCY9El7!{_L=%TKdTI&FH=1PI93mT z{MwZHx>|**fKJ(+QR@hxe$R4FzJN+Bu!8nT=s~9WGCCxiB@q!Q8w=i{L;znHrwiH7 zBI%b-YzmbIT( Hr;EVnbuYj&d`-%I(6(L0M08c-e?PhJ*{2JHNjk^{k?TnC z$L;bQAlNxc+DmJWb|izKMaRbxJyWY2IcMT6uHZeQT9Dfg85>snll$K)K@=)b$Kazi z;Du?6&d=xrINymJV2OP5bIx_lRssA3GHAW(3VvlZ{6FjmA$n@fsmp7Q2029nw)a)n z2rSxBpRSbdhWCh^ux_P+0 786`Pc7&ej{P9feFA4@?+t6k0=a8SJm1YbN?jj?9T|IGBvHQ zrvWb_#_~SHKQ bE!J0t*ev*Z_? zai)yYOVy>spZ?gheXWqrl0R_03I)L8ST`LD1_26wBZSl^VZxgIiXb>;_=ts<0sq ntVAOqzFz_84jV+dGpxS0_Ad#<2|C=AovNhK(YRb zjX41Jw5w9j4CMjAx8^tcjD8>&pm00jC}#Z+RQS) 3Fdnv8f$V|*d>M+^;iO$ ud&dsc6gX*!7w_Xp zJ1=?Vs?@{FjfYE_G@rcmUl2+ZdPT@}?S!ikONhM6KCY&Ofs{+>u_s;+@Lmk>q@a>x z_&fZ4*V5>;gGqq><56>P>t|Bx?85lU8&eV(Dt|n6WeH~wahQ?bAL7tt7^g16u7 yw=X4hT+6?AJ!g1q^fN{759K)t zY}*!9QS_o=9Tg244g-Qy2-@Nw4aSvfr}G5&hxT$Py+{EAYTe4dP{%RZsz;`|gd!@H zS24WOcEh}NX&f2_su~E }g3@c$h*TO^8I__rN7B#)~*E;Jrh%HSC-VH8{zIYbPeNPY}mN$aXBW?jCJj)od zGH`Q!-6E2!>7b&;+|~y$H_Ui`MBEPNu^gE^f!W44`DE||@K>p~ssd=DLze47g%De< z&OGbHS#_(oyeSCUB0jTQ6mIoqRpHA=ETcG(N6>xdyF&ZCB^J=n&D5p>-BPczs~O)4 zMo4d|@3*$mUB~X)bFl6b;Wu~TE)D)Im%YK_1 8&t#ax!- z?aj7uqtYF0c@2S&^&PtT^inWoy`hAq^y=Ky;bA7kl(>+~YezP5*imRU z4>OP_ohIw?YwT(v(a{$8$J6Ou!03-$YFf4be=XKO(AS#?xQMq!#k 7(s(BNOy;YV`R5RD~NMY%)j{VUgv-K8& zO{1Bj?$)Dh!NWdH-FI@L $e}jMI+f9C;wJ6A z*vN}0o2OL$Xt#{^5@hn^ACDPujQ%`Lb kpHi?o^4z zXXxJC0c9D|gPG>v50+`RXTh{;!#1T Qr_=)XnWr>s zx|IyaCt?ePS?{DPuuPaPSti#QeMjrY*2&pvwbVb@l&B&wQCMVL;sYy{&?+lUAkirU zqEzMsU6RU0q?>g(U<`VPnb};3=xmNaa>t{r=KE77-#XKsY0QMF=a#)MB5^tDtC&|c zJx~=$Ng_OTTVSSk&}ufDQgisl9c#SBa2{ `brN(RD6;UR4LN7u zez%upa$&^L4HOwE)s0U)kc&K%P&rgWso^TY24xDdo_%EHSc)y6V>J3^x|U}l=2@L> zi*{=w{TNy)Cq_FNale9p!B(!-uN3+2U6mI#_o49|OvrxD0hcKFOA?(bU7HFO1KuOM zg%_VH+9t9c36i(>BaVts%4~}x1Ljt6pc?)bpojz3&eV}-!r!LD?K~S;d46qm B z)In7mb0v}LDZ@ JD=c3_ki z=*~L6B{dy=N2y}EW{Hb6yDxLHjTv&HZEC5vfD%-kyV+y 2^7z1)- f;IotCFm6vVd|ag!sA&>j}=Wm937q&st4xG zwB@UYIcK_RPtNK^rFOIFu`$nteY>rDh|5a5ojop^Cd39E^=Bm)bvAngRKN6Ai*+2q zeVPq^QYjYpCpWUz&H=S_z_HY$_67rCz5U`O<7B*PwO0izG*17B@JfqJZy?baOjlBz zpqJ@Uwa@Ovv|}FxBTYlBdWM=;3XL+URMTU)n_AwQadtWiTeKNi<)LPa&&${cCT6 c;fc*fA+|f+cChg
xuP;y#RuTQwCnqrGXzAvgMYT}!=Z#p39 zH;a6ipp>eGv?p=BTI06xf`HwqU?`y3?tK(ZkSc _Y8ayiZ0NDa((ACpax%cO zKm_R;aoj@ut$L@&SpR`kOMmXz)P6}=JnSQf)r5^y>Pu92f|XuR@!Z4%CGFH!-3peT zg%MUG&Lb@1*Ht5Hvp;J4G#$x~-WP}V7;`QucJVGB*3fh*(dsI6;xHI)uy|1RoUncu zd<7a%Z9nxvr@UIDIeCUIv%|zbKGUI#dxgK$-8yd+bM 6F?s&X_lQXv9eL=IV+vQ?G)68>{*Ry znjyVMHHlBl^MnE9>@Qf!?1_yoN3`nn3#D9w7jWF^DfVCPbbq64ls})d|I|(IVw7bu zXQB-s2KmaDZf15MZ}d&RR+WQZ@f@+E8?R~W?l|U0&ASe=(=RU%2x~Sur&g3J>I5%O z)^0|pGbN^W>Lk83yR*V-r&Ijis>{h)1qC&M`$Qninaik+^7f?aIPQZBkJ}ozr-(J3 zdMDk+><_8GO%oIj)_5NW%{nglFcSwZxSGjH*FU-J-s31R08<89VmkUb{2?Dt?iTFp z;+cHdtNG!m-)+-7&kM6Iy)un_z?>* N9+1FVFrD2 >GbJ|>+4tP|f&)ggjj7H<8m(idG$xg5Fj$DNU2K6hM=GDuXF&dr4nHfdh z*rT8vulf@~v{3SB0$V~08?CL`wH8ad%0>3aV;M4|dDFX%yPPm3${LEPLn{)8^bkR| zXM-Hy9@QT4; z*z^yf4S_m_`M<;l)_xKh;-@gga9mo}; zv#g6PU0UyrzvKdd%49t~J8BFTY(vhB1vfhk8giHp5NYeFQ)BdJ)Gc1- $$=twEXTAS9SQeqGlVi1pfre%Eqe@h-PTiQ^@rU0o2UWn zh|@e(TSo@?O(uGOR#^wXKS_Pk1pYL0Y0z}1HpA9>AA+IB$Xtb>g$TORj}mN+y646J zZe0WE6PZ_=>)(a)8)DS--+WN0D2O*xh_v*7?fa;PXYq+vPXT6G)ne2KntvQ (q{JN_SgZypcz9{rEsRxLMLNF`e;WewTaZZ}GnWXmp+ z5R%;(le!T?CD|!L_I)=-Wk|N{`;2U3pR9v1Gr!ln<<`CONx$yn_xn7)U;puD=KXq| z*E!GgJm D*iML$NS#H_z8 vC4K(i54O?OWn3X10$0%Fz(Jbr47xZjpa+?A^VWcH2Ys5lH*K79BTw zB#gjedv # n*1bA?oy9mTg)AZ~y?AM9b~3& N~USHt4^d`pao() z6Ot{p`uKcVEH2{#m=S-OqrH*4#O6lsgUKgBHYiw%gaqM>W^b_pfe zLj>X%l5$!X|G4kgubh&)06aS1wGY7XC?lGv-HzQh#z{GhDbJ9RkHQ1WM*IAwy|B7= zX1dO^_I#tS+XJ_R-F_{<&WKz3+=x~>dx~>jxH7tzEp+{F6mof6;z(M5h=!!u!r{rG zq0qy&sr_n&)6WAC2Zg(w&bQAJ$nSGOJL{Jw*k&U9=rAvk{S#bDM)}C(d@z-mSZH $H-1DxNYuqN=Vq)HwhabLm{9LIT6m|@wYJ28q8Yvq~LBO;`A5xana9wI~ z2%CXjhxH56cPSWq75hY+UudC26Uv3yRK{vPAz@#+-`h@+d*re=S=j>9yz%9%p2>jI zU}b&Et$-$jO28=^rV^IC#YztCh;K+acY8R~DeBzf=$K(4L~u}2b3uMI?0t+tNtkYp z?g2@+^JQ0dEmNcAGWz`FficigQKra-U(r#0D9kgth)&IVczakrplfhc9F3(+UY))G zn;YAYKp0 j4C1CYAe!?L6(+5i?e#=g`i_Q`Ent zal}5`W6nkXrqYo#fx5*rx(*BKCYlG+DN;6zX7PXGG04yo<(tZKErBg@f_Oy_SIIb~ zkQQA;!khuQH(9>!X$?iW!Su){80WaREv(@Nhu*`(!8|^Mkmsmu1if}iSOfn2uw&c| zEFj+BuuwuVDL-dh9OuNC{pz=tdqWk1V*xGD)nm&vZk12oTmXLDV?I@h>)qLxb|6RY zw?nvtONwNtWJ~#ycd9mySjSLa!Hj5F(!;82_?bo?>|Vk*kS%k&j~`VG)%}R7Rb;*6 z$(-ljHLjy#I*5QTRc6|rXLXKEFTN{X^n0f`0G5tJqgqYxAhaMqlsm{kz!2gy+0yct zgfsg5I)mVZ>8v_mAD)upu_ES(n|~a1YrCg0U 7XOpy<@QjeCa0&TnkAkI;JY91hf3 zpKA5eeK!O}p72+TKXFQQ*~00`fEA(NcY8O-wv+NFy8F+m_C8ic?52@iin>*BaT+jq zl`c3=(S%yZQt~9mb#y!vZ}mBDh`Ug<2QeR$-&YIMZnr-fY(?53 )Os!eAsOvX}YR}v)Q$#IjDT9io11&WZ#OVl@^<2rvr
>?TGQ5-g2xST~cbUd?P_wnsnWDv 1el* 6xLiHB|@wg`EUzfRU$nCtEd2>P}*1#)WorH z16A4M 3`7qTDaXsXTy%$XPTSdX(*qoO`uiCLu-haby_QPiMzF%z~m@oiwYg<5=MMYaQ(>0 zNf2Iy5{jLtjR=x+{y`Nb4T-ht8siK}Gvf?+MMRqDt;r9sWy}1PM4#2LKk_iuo_#*h zxL>- mTTrH7vxbP%`UjF@qB7BCyefU6*2Ad9iwmBLqRr(5(tzAF7 z^i)|Sy3Ri%#(*f?q1?$rO!b7GqN`BrIbco^PxXGHNO9#T;0OXP^uH3Q^g@A3ZSr)N z8CcdwE_ku)@%i)7)6qJ4Rwg=3P9NUS*CPCN`}v}DF5lI7e+8@>vAqsKM{jWROcJbC zqHkt?E|1!rOuoIH*UNxBvh>_iFwH`%E}Hu6?!@Msl=}p%zn&ulhNCnE3CnGFsmh-V zt%?S*t0hlDoJTG-@LaKmg^wI7k!(?53FHYNNeD$HJVg_YSMTXpl{~p*H0d<+Ub-SN zDWxHC;H1QP&p35uZ7IeO%SSn8qDMZN6p2y3@FR_t=}*@q_!3NOlSMov3H$ca>)%j9 z+t2C)2ZZUJNRkCI7Brvxi5j2tZa|3Q%@Tg1`Pj02Rlgc|trC@HdL{$N9MHb9e{=6n zU)df%Ul6zFiPrA|ZDT SWspNSIa<_H%BjN z6RZR_ 4$TNcBht(`ph*2&hA^GETMZE<$1MdXYcv;Y@-e?xI z?@h_;I5fuqYC~B{6mJA|PD^^v?ZY@VK+z)9w^0hgh R1;h$jv?tu%A#ddB=8D7TD-!LagERO9ppV_s+F|X z1My;KS<_FPth9sRNDiI+D{ 9N{?y%m80S>qQKi1 zwTcp4APekl|8!Oy IXd@pYC0>SkWqs(JapuV4` zbQS{c2NsZ_G8tU 3G}-aLwx0rk?`-oeH=e{ZJa7Den1C+ d1TtVWuRtQnPB+Bj{*9Tf5o3i?QPcB>nL%Pd|EdQ0f5ecYvb6tmG zGZe^SYLz~^E|%b0hBtS>3P>oN^ZhqV`JRD%`X3o?AaL{gtY5nM 8n6OW zCyogI1On%PFfi#%o&GQIC>fTAK!5*K*lPl)0Z-q${EzLCZ*qfQTKhN^CV^H6nES4J zOzy9?fynfynAdWMT-yx(w+65H!~gEh;A;fw`*#5RpGA-`ldS1q_5v)M?;2V9vFBPN zOF#BpYh>xiByNo?EhiDno~)6j f;57fMuNL^ ;KM z$PXQ)*DO1SZi4h}Vb@vOKbJZB6~+G?O1YX`sQ86rPwUpFfTXlD-9IXRQ()&N4{rd6 zM#Sx5Z$azs)n{)HLD}2hrdfs6PvUQ0{N;xcsK#8|lbR%NnD<(?f&zzWsKYEjpWz|1 zy+dL7Cq1ijPyO+<3e*cmZ?dWUM6-qm(4oJ_rx<_Yc8D+I`iczMpaOtX?>}YO6l`WQ zq2AX!p1?ftO!rgf-JR!ndW$)-H~0=!`8#f+L**i^`gKsgKu4k`R$nUE1*#Wxm*2Yl z#H}S?$M<=}-&S@$QzaI#)<4sR>OVbU@fB(>+yDaEg!rvv^_7rKpd_t%i`C*MO4487 z_t}E3Kvjv+t@%;kRDQq}G2i_5qjb`LyM^}aiqYzVLeop;TXU<|kaduT7{1Z|6%EmX z%6%^DC%#z*sNA+9;4C+VlZC*ZWTVo_U+1#?pMLN}h90bK>n4w<8^4Nw6I25HK=l;< z_0e+n@{cDMeuH#sU*_Ibi*Wh6%d`Lx&WyZ8{N_8LI`$7H@a-4*g1tMb_3X*gs~-4r zX}{Y9*4Eyg^_ctL-z@VIsvRz^yY{W_{?D(Vg?4JM^GH7PKmXhRIJXDT29;#?9=C74 z1KJ?+56Lf|z&B6++e2DkO?nMNKJLQ*YIbW7vIZev&0`Hh{>4E5KIi#WMr#nV1|eUy zWQ~RVE1mlPErhJYKHB|dFTht5{f0< K7tUZ?z=c zKPPZ>)1GyrQD}VM6ZBxWg{5l{QLC XIGr>eqV@i;1nne;YdS zMTjp~*cG4j^E?gaA^bJ|E2)UxJ1-~%$!wARYBBFBH_ h3)mMW0qi=KX0wW)YOed}WBmY7yu*r8lSeD&e zUVhVETCCufQK6FCy5!Y278i4eKC&~D?wc_1tAzhG@fAiZBe(rn-00B8;%@^swB5wt z5#5h}cu)j}(X}U+dD%37{Mj#qJSzj1Wj*V@Zz4%{`U?uJmAtoRS3Nr!cA#dhTmQ&C z^a~>yy0#8~5*o@XZe4r@^(1KOxwgVB|rtS98B|etGMbV{zwMHnM%y#-V=5lovLo zORai#LmQ!woO+}2E6Eo|?x*0m%bpKz>(T2^Gb7k|kXCj}mR)uVkOf`1UD}c4;2%Ie zO1B|*Lgkg2AB)UW1t38ab1|QvSbi0-{N4${UaSAevh}!f6yQ{rOiDmtDU+P!ZVJ)g zOl$ngevlEc%PuXn;G#nn+${2AdJU2$!OAjx5u879>CS(Offra#AWm&R2Bj*F$r<*O zHdKkeIlghrV=(^Ilk!wQktO%q29)IFKI5PG$TzU}QMKH|0jLf