Skip to content

Conversation

@SequeI
Copy link
Member

@SequeI SequeI commented Nov 12, 2025

Summary by Sourcery

Add a validating webhook to the operator for Securesign CRs to enforce RHTAS namespace policies, integrate cert-manager for TLS, update kustomize and Makefile for overlay support, and extend both unit and e2e tests as well as CI workflows to cover the new webhook functionality

New Features:

  • Add a validating webhook for Securesign CR to enforce namespace run-level policies and block installs in the default or reserved OpenShift namespaces
  • Register the SecureSignValidator with the controller manager and expose the webhook on port 9443 with certificate injection

Enhancements:

  • Extend Makefile with an OPENSHIFT flag to select the appropriate kustomize overlay for build, deploy, and undeploy targets
  • Augment kustomize overlays to include webhook service, cert-manager Issuer/Certificate resources, and webhook configuration
  • Patch manager deployment YAML to mount the webhook TLS secret and open the webhook port

CI:

  • Update GitHub Actions kind-cluster workflow to install cert-manager
  • Adjust Tekton pipeline pull-request selector to include 'retest-all-comment' events

Tests:

  • Add unit tests for SecureSignValidator covering allowed and disallowed namespace scenarios
  • Enhance e2e test suite to install webhook infrastructure, wait for manager pod readiness, and verify CA bundle injection into the ValidatingWebhookConfiguration

@sourcery-ai
Copy link

sourcery-ai bot commented Nov 12, 2025

Reviewer's Guide

This PR implements a validating admission webhook for Securesign CRs to enforce namespace run-level policies, integrating it into the operator controller, adding the necessary webhook configuration, service, cert-manager resources and kustomize overlays, enhancing the e2e tests to deploy and validate the webhook (including CA bundle injection), updating the Makefile and CI to support overlay selection and cert-manager installation, and adding unit tests for the new validator logic.

Sequence diagram for Securesign CR validation via webhook

sequenceDiagram
    participant User as actor User
    participant K8sAPI as Kubernetes API Server
    participant Webhook as Validating Webhook
    participant Operator as Operator Controller

    User->>K8sAPI: Create/Update Securesign CR
    K8sAPI->>Webhook: AdmissionReview (Securesign CR)
    Webhook->>Operator: Validate namespace policy
    Operator-->>Webhook: Validation result
    Webhook-->>K8sAPI: AdmissionResponse (allow/deny)
    K8sAPI-->>User: Resource created/updated or error
Loading

ER diagram for webhook and certificate resources

erDiagram
    "ValidatingWebhookConfiguration" {
        string name
        string path
        string failurePolicy
        string[] admissionReviewVersions
        string[] operations
        string[] resources
        string[] apiGroups
        string[] apiVersions
        string sideEffects
    }
    "Service" {
        string name
        string namespace
        string[] ports
        string selector
    }
    "Certificate" {
        string name
        string namespace
        string secretName
        string issuerRef
        string[] dnsNames
    }
    "Issuer" {
        string name
        string namespace
        string selfSigned
    }
    ValidatingWebhookConfiguration ||--|{ Service : "uses"
    Certificate ||--|{ Issuer : "issued by"
    ValidatingWebhookConfiguration ||--|{ Certificate : "secured by"
    Service ||--|{ Certificate : "serves cert"
    Certificate ||--|{ Service : "for service"
Loading

Class diagram for SecureSignValidator and validation logic

classDiagram
    class SecureSignValidator {
        +Client: client.Client
        +ValidateCreate(ctx, obj)
        +ValidateUpdate(ctx, oldObj, newObj)
        +ValidateDelete(ctx, obj)
        -validateNamespacePolicy(ctx, operandCR)
    }
    SecureSignValidator --|> admission.CustomValidator
    class reservedRunLevels {
        +"0": true
        +"1": true
        +"9": true
    }
Loading

File-Level Changes

Change Details Files
Add SecureSignValidator admission webhook and integrate into controller-manager
  • Implement namespace policy checks in SecureSignValidator
  • Register validating webhook in main.go with custom path '/validate'
  • Annotate Securesign CRD type with kubebuilder webhook marker
internal/webhook/securesign_validator.go
internal/webhook/webhooks.go
cmd/main.go
api/v1alpha1/securesign_types.go
Introduce webhook configuration, service, and cert-manager kustomize overlays
  • Add ValidatingWebhookConfiguration and Service YAML resources
  • Define cert-manager Issuer and Certificate in overlay
  • Provide overlay patches for CA injection and serving-cert annotations
config/webhook/webhook.yaml
config/webhook/service.yaml
config/overlays/kubernetes/cert_resources.yaml
config/overlays/kubernetes/kustomization.yaml
config/overlays/kubernetes/webhook_patch.yaml
config/overlays/openshift/kustomization.yaml
config/overlays/openshift/serving_cert_annotation_patch.yaml
config/overlays/openshift/inject_ca_bundle_annotation_patch.yaml
Extend e2e tests to deploy and validate webhook infrastructure
  • Update suite_test.go to install webhookInfra resources and wait for CA bundle injection
  • Enhance managerPod spec with webhook port, volume mounts, and readiness checks
  • Implement WaitForPodReadiness and WaitForWebhookCaInjection helpers
test/e2e/custom_install/suite_test.go
Adapt Makefile and CI for overlay selection and cert-manager installation
  • Introduce OPENSHIFT flag to choose kustomize overlay
  • Update manifests, deploy, and undeploy targets to use selected overlay
  • Add CI steps to install and wait for cert-manager in GitHub Action
Makefile
.github/actions/kind-cluster/action.yml
Add unit tests for SecureSignValidator logic with fake client
  • Create webhook_test.go covering Create/Update/Delete scenarios
  • Add testify dependency to go.mod
internal/webhook/test/webhook_test.go
go.mod

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@SequeI SequeI added the enhancement New feature or request label Nov 12, 2025
@SequeI SequeI requested review from JasonPowr and osmman November 12, 2025 22:35
@qodo-merge-pro
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing Audit Logs: The validating webhook denies installations in certain namespaces but does not emit any
structured audit logs for these critical authorization-like decisions.

Referred Code
func (v *SecureSignValidator) validateNamespacePolicy(ctx context.Context, operandCR *rhtasv1alpha1.Securesign) (admission.Warnings, error) {
	reqLog := logf.FromContext(ctx)
	targetNamespace := operandCR.GetNamespace()

	if targetNamespace == "default" {
		reqLog.Info("Validation failed: Deployment blocked in 'default' namespace.")
		return nil, fmt.Errorf("installation into the 'default' namespace is prohibited by RHTAS policy")
	}

	ns := &corev1.Namespace{}

	if err := v.Client.Get(ctx, types.NamespacedName{Name: targetNamespace}, ns); err != nil {
		if apierrors.IsNotFound(err) {
			return nil, nil
		}
		reqLog.Error(err, "Failed to retrieve target namespace object for validation.")
		return nil, fmt.Errorf("failed to retrieve target namespace %s: %w", targetNamespace, err)
	}

	runLevel, found := ns.Labels["openshift.io/run-level"]
	if found && reservedRunLevels[runLevel] {


 ... (clipped 7 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Generic Errors: The webhook returns generic errors without structured context and relies on label presence
without guarding type assertions in tests, which may reduce robustness under malformed
inputs.

Referred Code
func (v *SecureSignValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
	operandCR, ok := obj.(*rhtasv1alpha1.Securesign)
	if !ok {
		return nil, fmt.Errorf("expected SecureSign CR but got %T", obj)
	}
	return v.validateNamespacePolicy(ctx, operandCR)
}

func (v *SecureSignValidator) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
	operandCR, ok := newObj.(*rhtasv1alpha1.Securesign)
	if !ok {
		return nil, fmt.Errorf("expected SecureSign CR but got %T", newObj)
	}
	return v.validateNamespacePolicy(ctx, operandCR)
}

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The new polling helpers in suite_test always swallow client.Get errors (treating all errors as ‘not ready’); consider distinguishing NotFound from other errors and failing fast on real errors to avoid masking issues.
  • suite_test.go has grown very large and is doing a lot of raw YAML/unstructured object manipulation; consider extracting common YAML loading and patching logic into reusable test helpers or using typed API objects for clarity and maintainability.
  • The hardcoded relative paths for cert-manager and webhook YAML in tests can easily break when moving files—consider using Go’s embed FS or a configurable base path to make file resolution more robust.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new polling helpers in suite_test always swallow client.Get errors (treating all errors as ‘not ready’); consider distinguishing NotFound from other errors and failing fast on real errors to avoid masking issues.
- suite_test.go has grown very large and is doing a lot of raw YAML/unstructured object manipulation; consider extracting common YAML loading and patching logic into reusable test helpers or using typed API objects for clarity and maintainability.
- The hardcoded relative paths for cert-manager and webhook YAML in tests can easily break when moving files—consider using Go’s embed FS or a configurable base path to make file resolution more robust.

## Individual Comments

### Comment 1
<location> `config/overlays/openshift/serving_cert_annotation_patch.yaml:7` </location>
<code_context>
+  name: controller-manager-webhook-service
+  namespace: openshift-rhtas-operator
+  labels:
+    control-plane: controller-manager
+  annotations:
+    service.beta.openshift.io/serving-cert-secret-name: webhook-server-tls
</code_context>

<issue_to_address>
**issue (bug_risk):** Label value differs from base service; may cause selector issues.

The label should match the base service to ensure selectors and resource matching work correctly.
</issue_to_address>

### Comment 2
<location> `config/overlays/kubernetes/cert_resources.yaml:20-21` </location>
<code_context>
+    name: selfsigned-issuer
+    kind: Issuer
+  dnsNames:
+  - rhtas-controller-manager-webhook-service.openshift-rhtas-operator.svc
+  - rhtas-controller-manager-webhook-service.openshift-rhtas-operator.svc.cluster.local
</code_context>

<issue_to_address>
**issue (bug_risk):** DNS names for certificate may not match service name in base manifest.

The DNS names use 'rhtas-controller-manager-webhook-service', but the actual service is 'controller-manager-webhook-service'. This mismatch may lead to TLS failures. Please update the DNS names to match the service name.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@qodo-merge-pro
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix invalid cert-manager version in URL

Correct the cert-manager version in the download URL from v1.19.1 to a valid
version like v1.9.1 to prevent CI failures.

.github/actions/kind-cluster/action.yml [125-130]

 - name: Install Cert-Manager
   shell: bash
   run: |
-    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.1/cert-manager.yaml
+    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
     kubectl wait --for=condition=available deployment/cert-manager-webhook -n cert-manager --timeout=5m
     kubectl wait --for=condition=available deployment/cert-manager -n cert-manager --timeout=5m
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a typo in the cert-manager version in a download URL, which would cause the CI pipeline to fail.

High
  • More

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Review effort 3/5

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant