Skip to content

Commit ff25fbc

Browse files
committed
change to allowedRegisties only with default of ghct.io
1 parent 6d252ed commit ff25fbc

7 files changed

Lines changed: 145 additions & 116 deletions

File tree

cmd/main.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ func main() {
8181
var imageServerURL string
8282
var architecture string
8383
var allowedRegistries string
84-
var blockedRegistries string
8584

8685
flag.StringVar(&architecture, "architecture", "amd64", "Target system architecture (e.g., amd64, arm64)")
8786
flag.IntVar(&ipxeServicePort, "ipxe-service-port", 5000, "IPXE Service port to listen on.")
@@ -101,8 +100,7 @@ func main() {
101100
flag.BoolVar(&secureMetrics, "metrics-secure", true, "If set the metrics endpoint is served securely")
102101
flag.BoolVar(&enableHTTP2, "enable-http2", false,
103102
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
104-
flag.StringVar(&allowedRegistries, "allowed-registries", "", "Comma-separated list of allowed OCI registries. If set, only these registries are permitted.")
105-
flag.StringVar(&blockedRegistries, "blocked-registries", "", "Comma-separated list of blocked OCI registries. If set, these registries are denied.")
103+
flag.StringVar(&allowedRegistries, "allowed-registries", "", "Comma-separated list of allowed OCI registries. Defaults to ghcr.io if not set.")
106104

107105
controllers := switches.New(
108106
// core controllers
@@ -233,8 +231,12 @@ func main() {
233231
}
234232

235233
// Initialize registry validator for OCI image validation
236-
registryValidator := registry.NewValidator(allowedRegistries, blockedRegistries)
237-
setupLog.Info("Initialized registry validator", "allowedRegistries", allowedRegistries, "blockedRegistries", blockedRegistries)
234+
registryValidator := registry.NewValidator(allowedRegistries)
235+
if allowedRegistries == "" {
236+
setupLog.Info("Initialized registry validator with default", "defaultAllowedRegistry", "ghcr.io")
237+
} else {
238+
setupLog.Info("Initialized registry validator", "allowedRegistries", allowedRegistries)
239+
}
238240

239241
if controllers.Enabled(ipxeBootConfigController) {
240242
if err = (&controller.IPXEBootConfigReconciler{

docs/README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ Boot Operator includes the following key components:
3131
- Handles `/image` requests
3232
- Extracts layers from OCI (Open Container Initiative) images, with support for multiple registries (e.g., GHCR, Docker Hub, Keppel, and any OCI-compliant registry)
3333
- Downloads specific layers based on the requested URI and image specifications
34-
- Registry access is controlled via CLI flags:
34+
- Registry access is controlled via CLI flag:
3535
- `--allowed-registries`: comma-separated list of permitted registries (allowlist mode)
36-
- `--blocked-registries`: comma-separated list of denied registries (blocklist mode)
37-
- If neither flag is set, all registries are denied (fail-closed)
36+
- If not set, defaults to allowing only `ghcr.io` (zero-config default)
37+
- When set, the specified registries completely replace the default (ghcr.io must be explicitly included if needed)
3838
- Example:
3939
- `wget http://SERVER_ADDRESS:30007/image?imageName=ghcr.io/ironcore-dev/os-images/gardenlinux&version=1443.10&layerName=application/vnd.ironcore.image.squashfs.v1alpha1.squashfs`
4040

@@ -48,17 +48,18 @@ These servers leverage Kubernetes controllers and API objects to manage the boot
4848

4949
Boot Operator enforces OCI registry restrictions at two levels:
5050

51-
1. **Controller level (early validation):** The PXE and HTTP boot controllers validate image references against the registry allow/block list during reconciliation. This means misconfigured or disallowed registries are rejected immediately when a `ServerBootConfiguration` is created, providing fast feedback before any machine attempts to boot.
51+
1. **Controller level (early validation):** The PXE and HTTP boot controllers validate image references against the registry allow list during reconciliation. This means misconfigured or disallowed registries are rejected immediately when a `ServerBootConfiguration` is created, providing fast feedback before any machine attempts to boot.
5252

5353
2. **Image Proxy Server level (runtime enforcement):** The image proxy server also validates registry domains before proxying layer downloads, acting as a second line of defense.
5454

55-
Registry restrictions are configured via CLI flags on the manager binary:
55+
Registry restrictions are configured via CLI flag on the manager binary:
5656

5757
| Flag | Description |
5858
|------|-------------|
59-
| `--allowed-registries` | Comma-separated list of permitted registries (allowlist mode). Only these registries are accepted. |
60-
| `--blocked-registries` | Comma-separated list of denied registries (blocklist mode). All registries except these are accepted. |
59+
| `--allowed-registries` | Comma-separated list of permitted registries (allowlist mode). When not set, defaults to `ghcr.io`. |
6160

62-
- If `--allowed-registries` is set, it takes precedence over `--blocked-registries`.
63-
- If neither flag is set, all registries are **denied** (fail-closed).
61+
**Behavior:**
62+
- **Default (no flag set):** Only `ghcr.io` is allowed, enabling zero-config operation with a secure default.
63+
- **Custom allow list:** When `--allowed-registries` is specified, it completely replaces the default. If you want to allow `ghcr.io` along with other registries, you must explicitly include it in the list (e.g., `--allowed-registries=ghcr.io,myregistry.example.com`).
64+
- **Case-insensitive matching:** All registry domain comparisons are case-insensitive.
6465
- Docker Hub variants (`docker.io`, `index.docker.io`, `registry-1.docker.io`) are normalized for consistent matching.

internal/controller/suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func SetupTest() *corev1.Namespace {
148148
})
149149
Expect(err).ToNot(HaveOccurred())
150150

151-
registryValidator := registry.NewValidator(allowedRegistries, "")
151+
registryValidator := registry.NewValidator(allowedRegistries)
152152

153153
Expect((&ServerBootConfigurationPXEReconciler{
154154
Client: k8sManager.GetClient(),

internal/registry/validation.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,22 @@ const (
1515
DefaultRegistry = "registry-1.docker.io"
1616
// DockerHubDomain is the canonical short domain for Docker Hub
1717
DockerHubDomain = "docker.io"
18+
// DefaultAllowedRegistry is the default registry when no allow list is configured
19+
DefaultAllowedRegistry = "ghcr.io"
1820
)
1921

20-
// Validator provides registry validation with configurable allow/block lists.
22+
// Validator provides registry validation with configurable allow list.
23+
// When no allow list is configured, it defaults to only allowing ghcr.io.
2124
type Validator struct {
2225
AllowedRegistries string
23-
BlockedRegistries string
2426
}
2527

26-
// NewValidator creates a new Validator with the given allowed and blocked registry lists.
27-
// Each list is a comma-separated string of registry domains.
28-
func NewValidator(allowedRegistries, blockedRegistries string) *Validator {
28+
// NewValidator creates a new Validator with the given allowed registry list.
29+
// The list is a comma-separated string of registry domains.
30+
// If the list is empty, it defaults to allowing only ghcr.io.
31+
func NewValidator(allowedRegistries string) *Validator {
2932
return &Validator{
3033
AllowedRegistries: allowedRegistries,
31-
BlockedRegistries: blockedRegistries,
3234
}
3335
}
3436

@@ -80,29 +82,26 @@ func isInList(registry string, list string) bool {
8082
return false
8183
}
8284

83-
// IsRegistryAllowed checks if a registry is allowed based on the allow/block lists.
85+
// IsRegistryAllowed checks if a registry is allowed based on the allow list.
86+
// If no allow list is configured, it defaults to allowing only ghcr.io.
8487
func (v *Validator) IsRegistryAllowed(registry string) bool {
8588
if v.AllowedRegistries != "" {
8689
return isInList(registry, v.AllowedRegistries)
8790
}
8891

89-
if v.BlockedRegistries != "" {
90-
return !isInList(registry, v.BlockedRegistries)
91-
}
92-
93-
return false
92+
// Default to allowing only ghcr.io when no allow list is configured
93+
return isInList(registry, DefaultAllowedRegistry)
9494
}
9595

9696
// ValidateImageRegistry validates that an image reference uses an allowed registry.
97+
// If no allow list is configured, only ghcr.io is permitted by default.
9798
func (v *Validator) ValidateImageRegistry(imageRef string) error {
9899
registry := ExtractRegistryDomain(imageRef)
99100
if !v.IsRegistryAllowed(registry) {
100101
if v.AllowedRegistries != "" {
101102
return fmt.Errorf("registry not allowed: %s (allowed registries: %s)", registry, v.AllowedRegistries)
102-
} else if v.BlockedRegistries != "" {
103-
return fmt.Errorf("registry blocked: %s (blocked registries: %s)", registry, v.BlockedRegistries)
104103
}
105-
return fmt.Errorf("registry not allowed: %s (no --allowed-registries or --blocked-registries configured, denying all)", registry)
104+
return fmt.Errorf("registry not allowed: %s (default allowed registry: %s)", registry, DefaultAllowedRegistry)
106105
}
107106
return nil
108107
}

0 commit comments

Comments
 (0)