Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions cmd/image-factory/cmd/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,9 @@ type SecureBootOptions struct {
// AWSKMS configures SecureBoot using AWS KMS.
AWSKMS AWSKMSProviderOptions `koanf:"awsKMS"`

// STACKITKMS decrypts the file-based SecureBoot keys with STACKIT KMS.
STACKITKMS STACKITKMSProviderOptions `koanf:"stackitKMS"`

// Enabled enables SecureBoot asset generation.
Enabled bool `koanf:"enabled"`
}
Expand Down Expand Up @@ -561,6 +564,28 @@ type AWSKMSProviderOptions struct {
Region string `koanf:"region"`
}

// STACKITKMSProviderOptions names the STACKIT KMS symmetric key the file-based SecureBoot keys are encrypted with.
//
// When set, the private keys in secureBoot.file contain the base64 ciphertext returned by the KMS
// encrypt operation. They are decrypted at startup and kept in memory. Credentials are read from the
// STACKIT SDK environment, for example STACKIT_SERVICE_ACCOUNT_KEY_PATH.
type STACKITKMSProviderOptions struct {
// ProjectID is the STACKIT project UUID the key ring belongs to.
ProjectID string `koanf:"projectID"`

// Region is the STACKIT region of the key ring, for example eu01.
Region string `koanf:"region"`

// KeyRingID is the UUID of the key ring.
KeyRingID string `koanf:"keyRingID"`

// KeyID is the UUID of the aes_256_gcm key the key files are encrypted with.
KeyID string `koanf:"keyID"`

// KeyVersion is the version of the KMS key, defaults to 1.
KeyVersion int64 `koanf:"keyVersion"`
}

// ArtifactsOptions defines the names and references of images used by the image factory.
type ArtifactsOptions struct {
// Replace the image registry defined in the extension/overlay image with the one defined here
Expand Down Expand Up @@ -1035,6 +1060,12 @@ var DefaultOptions = Options{
},
},

SecureBoot: SecureBootOptions{
STACKITKMS: STACKITKMSProviderOptions{
KeyVersion: 1,
},
},

Enterprise: EnterpriseOptions{
VEX: VEXOptions{
Data: OCIRepositoryOptions{
Expand Down
36 changes: 36 additions & 0 deletions cmd/image-factory/cmd/secureboot_stackit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

package cmd

import (
"context"
"fmt"

"go.uber.org/zap"

"github.com/siderolabs/image-factory/internal/secureboot"
)

// buildSecureBootServiceWithStackit prefers the STACKIT KMS backed SecureBoot service when it is
// configured and falls back to the upstream backends otherwise.
func buildSecureBootServiceWithStackit(ctx context.Context, logger *zap.Logger, opts Options) (*secureboot.Service, error) {
if !opts.SecureBoot.Enabled || opts.SecureBoot.STACKITKMS.KeyID == "" {
return buildSecureBootService(opts)
}

svc, err := secureboot.NewStackitKMSService(
ctx,
logger,
secureboot.StackitKMSOptions(opts.SecureBoot.STACKITKMS),
opts.SecureBoot.File.SigningKeyPath,
opts.SecureBoot.File.SigningCertPath,
opts.SecureBoot.File.PCRKeyPath,
)
if err != nil {
return nil, fmt.Errorf("failed to initialize SecureBoot service: %w", err)
}

return svc, nil
}
2 changes: 1 addition & 1 deletion cmd/image-factory/cmd/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func RunFactory(ctx context.Context, logger *zap.Logger, opts Options) error {
return err
}

secureBootService, err := buildSecureBootService(opts)
secureBootService, err := buildSecureBootServiceWithStackit(ctx, logger, opts)
if err != nil {
return err
}
Expand Down
22 changes: 22 additions & 0 deletions deploy/helm/image-factory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,28 @@ config:
certificateName: signing-cert
```

### Using STACKIT KMS

The local files approach with the private keys encrypted by a STACKIT KMS
`aes_256_gcm` key. The key files contain the base64 ciphertext returned by the
KMS encrypt operation and are decrypted at startup. Credentials come from the
STACKIT SDK environment, for example `STACKIT_SERVICE_ACCOUNT_KEY_PATH`.

```yaml
config:
secureBoot:
enabled: true
file:
signingCertPath: /path/to/cert.pem
signingKeyPath: /path/to/key.pem.enc
pcrKeyPath: /path/to/pcr-key.pem.enc
stackitKMS:
projectID: 00000000-0000-0000-0000-000000000000
region: eu01
keyRingID: 00000000-0000-0000-0000-000000000000
keyID: 00000000-0000-0000-0000-000000000000
```

## Monitoring

### Prometheus ServiceMonitor
Expand Down
22 changes: 22 additions & 0 deletions deploy/helm/image-factory/README.md.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,28 @@ config:
certificateName: signing-cert
```

### Using STACKIT KMS

The local files approach with the private keys encrypted by a STACKIT KMS
`aes_256_gcm` key. The key files contain the base64 ciphertext returned by the
KMS encrypt operation and are decrypted at startup. Credentials come from the
STACKIT SDK environment, for example `STACKIT_SERVICE_ACCOUNT_KEY_PATH`.

```yaml
config:
secureBoot:
enabled: true
file:
signingCertPath: /path/to/cert.pem
signingKeyPath: /path/to/key.pem.enc
pcrKeyPath: /path/to/pcr-key.pem.enc
stackitKMS:
projectID: 00000000-0000-0000-0000-000000000000
region: eu01
keyRingID: 00000000-0000-0000-0000-000000000000
keyID: 00000000-0000-0000-0000-000000000000
```

## Monitoring

### Prometheus ServiceMonitor
Expand Down
7 changes: 7 additions & 0 deletions deploy/helm/image-factory/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@ config:
# certificateName: ""
# keyName: ""
# url: ""
## STACKIT KMS key the file-based private keys are encrypted with (decrypted at startup)
# stackitKMS:
# projectID: ""
# region: ""
# keyRingID: ""
# keyID: ""
# keyVersion: 1
## Enable SecureBoot asset generation
# enabled: false
## Local file-based keys for signing
Expand Down
84 changes: 84 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,57 @@ Region is the AWS region containing the KMS keys.

---

### `secureBoot.stackitKMS`

STACKITKMS decrypts the file-based SecureBoot keys with STACKIT KMS.

---

### `secureBoot.stackitKMS.projectID`

- **Type:** `string`
- **Env:** `SECUREBOOT_STACKITKMS_PROJECTID`

ProjectID is the STACKIT project UUID the key ring belongs to.

---

### `secureBoot.stackitKMS.region`

- **Type:** `string`
- **Env:** `SECUREBOOT_STACKITKMS_REGION`

Region is the STACKIT region of the key ring, for example eu01.

---

### `secureBoot.stackitKMS.keyRingID`

- **Type:** `string`
- **Env:** `SECUREBOOT_STACKITKMS_KEYRINGID`

KeyRingID is the UUID of the key ring.

---

### `secureBoot.stackitKMS.keyID`

- **Type:** `string`
- **Env:** `SECUREBOOT_STACKITKMS_KEYID`

KeyID is the UUID of the aes_256_gcm key the key files are encrypted with.

---

### `secureBoot.stackitKMS.keyVersion`

- **Type:** `int64`
- **Env:** `SECUREBOOT_STACKITKMS_KEYVERSION`

KeyVersion is the version of the KMS key, defaults to 1.

---

### `secureBoot.enabled`

- **Type:** `bool`
Expand All @@ -605,6 +656,15 @@ Artifacts defines names and references for various images used by the factory.

---

### `artifacts.overrideSourceImageRegistry`

- **Type:** `string`
- **Env:** `ARTIFACTS_OVERRIDESOURCEIMAGEREGISTRY`

Replace the image registry defined in the extension/overlay image with the one defined here

---

### `artifacts.core`

Core contains configuration for core images used by the image factory.
Expand Down Expand Up @@ -878,6 +938,15 @@ RefreshInterval specifies how often the image factory should refresh its connect

---

### `artifacts.skipVersionfilter`

- **Type:** `bool`
- **Env:** `ARTIFACTS_SKIPVERSIONFILTER`

Whether to skip beta/alpha versions and such when obtaining valid Talos versions

---

### `authentication`

Authentication settings.
Expand Down Expand Up @@ -1532,12 +1601,14 @@ artifacts:
namespace: siderolabs
registry: ghcr.io
repository: ""
overrideSourceImageRegistry: ""
refreshInterval: 5m0s
schematic:
insecure: false
namespace: siderolabs/image-factory
registry: ghcr.io
repository: schematics
skipVersionfilter: false
talosVersionRecheckInterval: 15m0s
audit:
file:
Expand Down Expand Up @@ -1676,6 +1747,12 @@ secureBoot:
pcrKeyPath: ""
signingCertPath: ""
signingKeyPath: ""
stackitKMS:
keyID: ""
keyRingID: ""
keyVersion: 1
projectID: ""
region: ""
```

### Environment Variables
Expand All @@ -1699,11 +1776,13 @@ IF_ARTIFACTS_INSTALLER_INTERNAL_INSECURE=false
IF_ARTIFACTS_INSTALLER_INTERNAL_NAMESPACE=siderolabs
IF_ARTIFACTS_INSTALLER_INTERNAL_REGISTRY=ghcr.io
IF_ARTIFACTS_INSTALLER_INTERNAL_REPOSITORY=
IF_ARTIFACTS_OVERRIDESOURCEIMAGEREGISTRY=

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you use some underscores pls to myke it more readable :)

IF_ARTIFACTS_REFRESHINTERVAL=5m0s
IF_ARTIFACTS_SCHEMATIC_INSECURE=false
IF_ARTIFACTS_SCHEMATIC_NAMESPACE=siderolabs/image-factory
IF_ARTIFACTS_SCHEMATIC_REGISTRY=ghcr.io
IF_ARTIFACTS_SCHEMATIC_REPOSITORY=schematics
IF_ARTIFACTS_SKIPVERSIONFILTER=false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same ⏫

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't find a nice way to do that. But I'll look into it!

IF_ARTIFACTS_TALOSVERSIONRECHECKINTERVAL=15m0s
IF_AUDIT_FILE_MAXAGE=30
IF_AUDIT_FILE_MAXBACKUPS=16
Expand Down Expand Up @@ -1806,4 +1885,9 @@ IF_SECUREBOOT_ENABLED=false
IF_SECUREBOOT_FILE_PCRKEYPATH=
IF_SECUREBOOT_FILE_SIGNINGCERTPATH=
IF_SECUREBOOT_FILE_SIGNINGKEYPATH=
IF_SECUREBOOT_STACKITKMS_KEYID=
IF_SECUREBOOT_STACKITKMS_KEYRINGID=
IF_SECUREBOOT_STACKITKMS_KEYVERSION=1
IF_SECUREBOOT_STACKITKMS_PROJECTID=
IF_SECUREBOOT_STACKITKMS_REGION=
```
6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/anchore/go-logger v0.2.0
github.com/anchore/grype v0.120.1
github.com/anchore/syft v1.54.1
github.com/awnumar/memguard v0.23.0
github.com/blang/semver/v4 v4.0.0
github.com/coreos/go-oidc/v3 v3.21.0
github.com/felixge/httpsnoop v1.1.0
Expand Down Expand Up @@ -54,6 +55,8 @@ require (
github.com/slok/go-http-metrics v0.13.0
github.com/spdx/tools-golang v0.6.0-rc4
github.com/spf13/pflag v1.0.10
github.com/stackitcloud/stackit-sdk-go/core v0.27.0
github.com/stackitcloud/stackit-sdk-go/services/kms v1.13.1
github.com/stretchr/testify v1.12.1
github.com/u-root/u-root v0.16.0
github.com/ulikunitz/xz v0.5.17
Expand All @@ -66,6 +69,7 @@ require (
golang.org/x/sys v0.49.0
golang.org/x/text v0.43.0
golang.org/x/time v0.16.0
google.golang.org/grpc v1.83.2
google.golang.org/protobuf v1.36.12
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
Expand Down Expand Up @@ -131,6 +135,7 @@ require (
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/awnumar/memcall v0.4.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.44.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 // indirect
github.com/aws/aws-sdk-go-v2/config v1.32.40 // indirect
Expand Down Expand Up @@ -491,7 +496,6 @@ require (
google.golang.org/genproto v0.0.0-20260715232425-e75dac1f907d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260825221802-da73d73af1c5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260825221802-da73d73af1c5 // indirect
google.golang.org/grpc v1.83.2 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.3 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/awnumar/memcall v0.4.0 h1:B7hgZYdfH6Ot1Goaz8jGne/7i8xD4taZie/PNSFZ29g=
github.com/awnumar/memcall v0.4.0/go.mod h1:8xOx1YbfyuCg3Fy6TO8DK0kZUua3V42/goA5Ru47E8w=
github.com/awnumar/memguard v0.23.0 h1:sJ3a1/SWlcuKIQ7MV+R9p0Pvo9CWsMbGZvcZQtmc68A=
github.com/awnumar/memguard v0.23.0/go.mod h1:olVofBrsPdITtJ2HgxQKrEYEMyIBAIciVG4wNnZhW9M=
github.com/aws/aws-sdk-go-v2 v1.44.0 h1:4IbaHhtzy+4h37z4JQyO9a2QsiCml3CNYHtq5hIHigo=
github.com/aws/aws-sdk-go-v2 v1.44.0/go.mod h1:bttEH6JqnUL8LepvDVfdrds/fZ5bCIxzpe3abyUrhDU=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.20 h1:GPRlPwz40I2B2VrBEASOA3Bi77NyeqejNLkifosX0rs=
Expand Down Expand Up @@ -1359,6 +1363,10 @@ github.com/spiffe/go-spiffe/v2 v2.7.0 h1:uXe1MflJoHw58wAUvxVlcM7WpKtijWG7I1UidcG
github.com/spiffe/go-spiffe/v2 v2.7.0/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U=
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw=
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M=
github.com/stackitcloud/stackit-sdk-go/core v0.27.0 h1:7lc6qStcFDFf8zHP4ORPa9joybw+Sa2LtB6BVjKQ+ek=
github.com/stackitcloud/stackit-sdk-go/core v0.27.0/go.mod h1:WU1hhxnjXw2EV7CYa1nlEvNpMiRY6CvmIOaHuL3pOaA=
github.com/stackitcloud/stackit-sdk-go/services/kms v1.13.1 h1:iEPerniBpji6dGiB31p1WAUxgBf9VBIL9gKocfbBqW8=
github.com/stackitcloud/stackit-sdk-go/services/kms v1.13.1/go.mod h1:aG3xzmeVCsxnLwb+TA4U5i79a4sPiDicWoWG7lyg4Zs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
Expand Down
Loading
Loading