Skip to content

fix: Address security vulnerabilities and configuration issues from PR #3 review#10

Draft
Copilot wants to merge 14 commits intomainfrom
copilot/apply-comments-from-pull-request-3
Draft

fix: Address security vulnerabilities and configuration issues from PR #3 review#10
Copilot wants to merge 14 commits intomainfrom
copilot/apply-comments-from-pull-request-3

Conversation

Copy link

Copilot AI commented Feb 12, 2026

Addressing PR Review Comments - Complete ✅

Original Security Fixes (PR #3) ✅

  • Command Injection - Replaced eval with array-based command construction in 3 files
  • Secret Exposure - Fixed unsafe .env loading and DigitalOcean token handling
  • Configuration - Fixed NetworkPolicy namespace mismatches and pinned K8s version
  • Cleanup - Removed duplicate function, fixed documentation paths

Code Review Improvements (Round 1) ✅

  • Array-based argument handling throughout cli/lib/stacks.sh
  • Eliminated code duplication in helm_utils.sh
  • Fixed DigitalOcean external-dns parameters (secretName + proper key name)
  • Enhanced .env security with custom parser preventing command execution
  • Removed misleading shellcheck disable comments

Code Review Improvements (Round 2) ✅

  • Improved quote stripping logic to only handle matching pairs
  • Added explanatory comments for whitespace trimming pattern
  • Enhanced quote handling with case statement for clarity

Namespace Consistency Fix (Round 3) ✅

  • Changed all infrastructure namespaces from infra to standard names
  • Removed incorrect NetworkPolicy overrides that set name=infra
  • Added automatic namespace labeling for ingress-nginx after deployment
  • Updated deploy scripts to reference correct namespaces
  • Fixed namespace labeling condition and error handling

Security & Robustness Improvements (Round 4) ✅

  • Fixed label check to use jsonpath instead of grep to avoid false positives
  • Added CRLF line ending handling in .env parser
  • Changed password fields from --set to --set-string

Error Handling & Return Codes (Round 5) ✅

  • Added return codes (0/1) to install_selection function for proper error propagation
  • Fixed kubectl label error handling in wordpress/deploy.sh to check command success
  • Updated create_node_pool usage message to match actual function signature

Critical Error Handling & Documentation (Round 6) ✅

  • Treat namespace label failure as hard error in shared ingress path (return 1 immediately)
  • Clarified create_node_pool usage to reflect actual positional parsing with default note
  • Made ExternalDNS error message self-contained with complete kubectl commands

Security Best Practices & Optional Parameters (Round 7) ✅

  • Replaced insecure secret creation methods (--from-literal, /tmp) with mktemp+trap and stdin piping
  • Treat ingress-nginx namespace label failure as hard error in install_selection
  • Implemented proper optional-arg parsing for create_node_pool (3 args vs 4+ args detection)

All changes validated with shellcheck and security best practices enforced throughout.

Original prompt

This section details on the original issue you should resolve

<issue_title>@copilot open a new pull request to apply changes based on the comments in this thread</issue_title>
<issue_description>@copilot open a new pull request to apply changes based on the comments in this thread

Originally posted by @romandidomizio in #3 (comment)
</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 4 commits February 12, 2026 05:32
…fe secret handling

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
…cy namespace mismatches

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
…labeling)

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Copilot AI changed the title [WIP] Apply changes from comments in review thread fix: Address security vulnerabilities and configuration issues from PR #3 review Feb 12, 2026
Copilot AI requested a review from romandidomizio February 12, 2026 05:38
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request addresses critical security vulnerabilities and configuration issues identified in PR #3, focusing on command injection prevention, secret handling improvements, and namespace configuration fixes. The changes enhance the security posture of the deployment scripts by eliminating unsafe patterns and improving operational robustness.

Changes:

  • Security hardening: Replaced eval-based command construction with array-based approach in 3 files to prevent command injection vulnerabilities
  • Secret management: Transitioned DigitalOcean token from CLI argument passing to Kubernetes Secret requirement, and improved .env file loading safety
  • Configuration fixes: Added automatic namespace labeling for NetworkPolicy compatibility, pinned Kubernetes version to prevent drift, removed duplicate functions, and corrected documentation references

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
wordpress/helm/templates/secrets.yaml Improved comment clarity for WordPress password field
wordpress/deploy.sh Added automatic namespace labeling for NetworkPolicy ingress access compatibility
n8n/deploy.sh Updated documentation references from old script paths to CLI tool, removed duplicate get_external_ip() function, corrected namespace reference in error messages
cli/lib/stacks.sh Replaced eval with array-based Helm command construction, changed DigitalOcean token to require Kubernetes Secret reference
cli/lib/helm_utils.sh Eliminated eval by using direct Helm calls with proper argument quoting
cli/lib/do_k8s.sh Improved .env loading safety using set -a/set +a pattern, pinned K8S_VERSION to 1.33.1-do.0, converted doctl command to array-based construction

@romandidomizio
Copy link
Member

@copilot apply changes based on the comments in this thread

Copilot AI and others added 2 commits February 13, 2026 08:32
…s, improve .env security

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
…ents

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Copy link
Author

Copilot AI commented Feb 13, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • charts.bitnami.com
    • Triggering command: /usr/local/bin/helm helm repo add bitnami REDACTED (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

@romandidomizio
Copy link
Member

@copilot fix the three issues above that you commented on. the namespace should be ingress-nginx. i'm not sure what infra is supposed to be referencing. identify where infra is referenced, explain why its there, and replace it.

…ect infra overrides

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Copy link
Author

Copilot AI commented Mar 16, 2026

@copilot fix the three issues above that you commented on. the namespace should be ingress-nginx. i'm not sure what infra is supposed to be referencing. identify where infra is referenced, explain why...

Fixed in commit 4dd6765.

What was "infra" and why it was there:
The infra namespace was an incorrect abstraction attempting to consolidate all infrastructure components (NGINX Ingress, cert-manager, external-dns, monitoring) into a single namespace. This created NetworkPolicy mismatches because:

  1. All Helm chart NetworkPolicies expect traffic from name=ingress-nginx label (per Kubernetes conventions)
  2. Deploying to infra but overriding NetworkPolicy to look for name=infra broke these conventions
  3. This caused the critical mismatch where ingress traffic would be blocked

Changes made:

  1. cli/lib/stacks.sh: Changed all infra component namespaces to match their component names (ingress-nginx, cert-manager, external-dns, monitoring)
  2. cli/lib/stacks.sh: Removed all NetworkPolicy overrides setting name=infra (lines 123, 144, 179, 202)
  3. cli/lib/stacks.sh: Added automatic labeling of ingress-nginx namespace with name=ingress-nginx after deployment
  4. wordpress/deploy.sh: Updated to check for ingress-nginx namespace instead of infra
  5. n8n/deploy.sh: Updated all references from infra to ingress-nginx namespace

Now all components use standard namespace naming and NetworkPolicy rules work correctly without overrides.

Copilot AI and others added 2 commits March 16, 2026 19:24
Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
…wording

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

@romandidomizio
Copy link
Member

@copilot apply changes based on the comments in this thread

…passwords

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Copy link
Author

Copilot AI commented Mar 17, 2026

@copilot apply changes based on the comments in this thread

Fixed in commit 0cd03cb.

Changes made:

  1. Label check fix: Changed from grep -q "name=ingress-nginx" to jsonpath-based check (kubectl get namespace ingress-nginx -o jsonpath='{.metadata.labels.name}') to avoid false positives with kubernetes.io/metadata.name=ingress-nginx label. Applied to both occurrences in wordpress/deploy.sh.

  2. CRLF handling: Added value="${value%$'\r'}" in .env parser to strip trailing carriage returns from Windows line endings, preventing broken tokens/domains.

  3. Password Helm parsing: Changed from --set to --set-string for all password fields (wordpress.wordpressPassword, mariadb.auth.rootPassword, mariadb.auth.password) to prevent Helm from misinterpreting commas, booleans, or numbers in password values.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

@romandidomizio
Copy link
Member

@copilot apply changes based on the comments in this thread

… kubectl label

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Copy link
Author

Copilot AI commented Mar 18, 2026

@copilot apply changes based on the comments in this thread

Fixed in commit 5a12917.

Changes made:

  1. cli/lib/stacks.sh: Added return 0 on success and return 1 on failure in install_selection function to properly propagate Helm command exit codes to callers.

  2. wordpress/deploy.sh: Wrapped kubectl label command in conditional check with error handling - now logs error and returns 1 on failure instead of always reporting success.

  3. cli/lib/do_k8s.sh: Updated create_node_pool usage message from <pool_name> to [cluster_name] <pool_name> to accurately reflect the optional first parameter.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

@romandidomizio
Copy link
Member

@copilot apply changes based on the comments in this thread

…r messages self-contained

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Agent-Logs-Url: https://github.com/WeOwnNetwork/ai/sessions/bd4cfc78-078d-491c-b3cc-6fcde72c9f75
Copy link
Author

Copilot AI commented Mar 24, 2026

@copilot apply changes based on the comments in this thread

Fixed in commit b61c232.

Changes made:

  1. wordpress/deploy.sh: Namespace label failure in shared ingress path now treated as hard error - inverted conditional to if ! and return 1 immediately on failure, preventing false success when NetworkPolicy prerequisites aren't satisfied.

  2. cli/lib/do_k8s.sh: Updated create_node_pool usage to clarify positional parsing - changed to <cluster_name> with explanatory note that it defaults to $CLUSTER_NAME or 'weown-cluster', reflecting actual implementation.

  3. cli/lib/stacks.sh: Made ExternalDNS error message self-contained with complete kubectl commands - removed "see the docs" reference and included step-by-step Secret creation examples using both --from-literal and --from-env-file methods.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Comment on lines +71 to +77
log_error "Create the Secret securely using:"
log_error " kubectl create secret generic <secret-name> --from-literal=digitalocean_api_token=<your-token> -n external-dns"
log_error "Or use an env file (recommended):"
log_error " echo 'digitalocean_api_token=<your-token>' > /tmp/do-token.env"
log_error " kubectl create secret generic <secret-name> --from-env-file=/tmp/do-token.env -n external-dns"
log_error " rm /tmp/do-token.env"
log_error ""
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The ExternalDNS guidance here suggests creating the Secret using --from-literal and writing the token to /tmp. Both patterns can leak secrets (shell history/process list; world-readable temp paths). Update the message to only recommend a secure approach (e.g., using mktemp with a trap cleanup and kubectl create secret ... --from-env-file, or piping from stdin) and avoid mentioning --from-literal or fixed /tmp paths.

Suggested change
log_error "Create the Secret securely using:"
log_error " kubectl create secret generic <secret-name> --from-literal=digitalocean_api_token=<your-token> -n external-dns"
log_error "Or use an env file (recommended):"
log_error " echo 'digitalocean_api_token=<your-token>' > /tmp/do-token.env"
log_error " kubectl create secret generic <secret-name> --from-env-file=/tmp/do-token.env -n external-dns"
log_error " rm /tmp/do-token.env"
log_error ""
log_error "Create the Secret securely using a temporary env file:"
log_error " AUTH_FILE=\"\$(mktemp)\""
log_error " trap 'rm -f \"\$AUTH_FILE\"' EXIT"
log_error " cat > \"\$AUTH_FILE\" << 'EOF'"
log_error "digitalocean_api_token=<your-token>"
log_error "EOF"
log_error " kubectl create secret generic <secret-name> --from-env-file=\"\$AUTH_FILE\" -n external-dns"
log_error ""
log_error "Alternatively, you can pipe the value from stdin without writing it to disk:"
log_error " printf 'digitalocean_api_token=' | tr -d '\\n'; read -s TOKEN; echo; \\"
log_error " kubectl create secret generic <secret-name> --from-env-file=<(printf 'digitalocean_api_token=%s\n' \"\$TOKEN\") -n external-dns"
log_error ""

Copilot uses AI. Check for mistakes.
if kubectl label namespace "$ns" name=ingress-nginx --overwrite; then
log_success "Labeled namespace '$ns' with name=ingress-nginx for NetworkPolicy access"
else
log_error "Failed to label namespace '$ns' - NetworkPolicy may not work correctly"
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

If labeling the ingress-nginx namespace fails, the function still returns success, even though NetworkPolicies for apps will likely block ingress without the name=ingress-nginx label. Treat this as a hard failure (return non-zero) so callers don’t proceed thinking the infra stack is healthy when it isn’t.

Suggested change
log_error "Failed to label namespace '$ns' - NetworkPolicy may not work correctly"
log_error "Failed to label namespace '$ns' - NetworkPolicy may not work correctly; treating as hard failure"
return 1

Copilot uses AI. Check for mistakes.
Comment on lines +128 to +137
# First arg is always cluster_name (with default), remaining args are positional
local cluster_name=${1:-${CLUSTER_NAME:-weown-cluster}}
local pool_name=$2
local size=$3
local count=$4
local tags=$5 # Optional setup as "role=value"

if [ -z "$pool_name" ] || [ -z "$size" ] || [ -z "$count" ]; then
log_error "Usage: create_node_pool <cluster_name> <pool_name> <size> <count> [label]"
log_error " (cluster_name defaults to \$CLUSTER_NAME or 'weown-cluster' if not provided)"
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

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

The usage note says cluster_name “defaults … if not provided”, but with the current positional parsing ($1=cluster_name, $2=pool_name, …) you can’t omit cluster_name while still providing the required pool args (the pool name would be treated as the cluster name). Either (a) make cluster_name truly optional by switching parsing based on arg count (e.g., 3 args => pool_name/size/count; 4+ => cluster_name/pool_name/size/count), or (b) update the usage text to make cluster_name required in practice.

Suggested change
# First arg is always cluster_name (with default), remaining args are positional
local cluster_name=${1:-${CLUSTER_NAME:-weown-cluster}}
local pool_name=$2
local size=$3
local count=$4
local tags=$5 # Optional setup as "role=value"
if [ -z "$pool_name" ] || [ -z "$size" ] || [ -z "$count" ]; then
log_error "Usage: create_node_pool <cluster_name> <pool_name> <size> <count> [label]"
log_error " (cluster_name defaults to \$CLUSTER_NAME or 'weown-cluster' if not provided)"
# cluster_name is optional:
# - 3 args => <pool_name> <size> <count> (cluster_name from \$CLUSTER_NAME or 'weown-cluster')
# - 4+ args => <cluster_name> <pool_name> <size> <count> [label]
local cluster_name
local pool_name
local size
local count
local tags # Optional setup as "role=value"
if [ "$#" -eq 3 ]; then
# Form: create_node_pool <pool_name> <size> <count>
cluster_name=${CLUSTER_NAME:-weown-cluster}
pool_name=$1
size=$2
count=$3
tags=
elif [ "$#" -ge 4 ]; then
# Form: create_node_pool <cluster_name> <pool_name> <size> <count> [label]
cluster_name=${1:-${CLUSTER_NAME:-weown-cluster}}
pool_name=$2
size=$3
count=$4
tags=$5
else
log_error "Usage:"
log_error " create_node_pool <pool_name> <size> <count>"
log_error " create_node_pool <cluster_name> <pool_name> <size> <count> [label]"
log_error " (cluster_name defaults to \$CLUSTER_NAME or 'weown-cluster' if not provided)"
return 1
fi
if [ -z "$pool_name" ] || [ -z "$size" ] || [ -z "$count" ]; then
log_error "Usage:"
log_error " create_node_pool <pool_name> <size> <count>"
log_error " create_node_pool <cluster_name> <pool_name> <size> <count> [label]"
log_error " (cluster_name defaults to \$CLUSTER_NAME or 'weown-cluster' if not provided)"

Copilot uses AI. Check for mistakes.
@romandidomizio
Copy link
Member

@copilot apply changes based on the comments in this thread

…error, make cluster_name truly optional

Co-authored-by: romandidomizio <123122767+romandidomizio@users.noreply.github.com>
Agent-Logs-Url: https://github.com/WeOwnNetwork/ai/sessions/2f54cc7d-fa5f-466f-92b9-2045c4da7432
Copy link
Author

Copilot AI commented Mar 24, 2026

@copilot apply changes based on the comments in this thread

Fixed in commit 3656bed.

Changes made:

  1. cli/lib/stacks.sh (lines 71-77): Replaced insecure secret creation methods with secure alternatives:

    • Removed --from-literal (leaks to shell history/process list)
    • Removed fixed /tmp paths (world-readable)
    • Added mktemp with trap cleanup pattern
    • Added stdin piping alternative using process substitution
  2. cli/lib/stacks.sh (line 241): Inverted conditional to treat ingress-nginx namespace label failure as hard error - now returns 1 immediately to prevent false success when NetworkPolicy prerequisites aren't met.

  3. cli/lib/do_k8s.sh (lines 128-137): Implemented proper optional-arg parsing with arg count detection:

    • 3 args: <pool_name> <size> <count> (cluster_name from env or default)
    • 4+ args: <cluster_name> <pool_name> <size> <count> [label]
    • Users can now truly omit cluster_name without argument misalignment

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

Labels

None yet

Projects

None yet

3 participants