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
2 changes: 2 additions & 0 deletions .github/workflows/superlinter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ jobs:
VALIDATE_ALL_CODEBASE: true
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Exclude bash scripts with Helm templating (they contain {{ }} syntax)
FILTER_REGEX_EXCLUDE: .*\.sh\.tpl$
# These are the validation we disable atm
VALIDATE_ANSIBLE: false
VALIDATE_BASH: false
Expand Down
61 changes: 40 additions & 21 deletions charts/qtodo/files/spiffe-vault-client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ def __init__(self):
self.credentials_file = os.getenv(
"CREDENTIALS_FILE", "/etc/credentials.properties"
)
# ZTVP trusted CA bundle (preferred)
self.ztvp_ca_bundle = os.getenv(
"ZTVP_CA_BUNDLE",
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
)
# Service CA (fallback for backward compatibility)
self.service_ca_file = os.getenv(
"SERVICE_CA_FILE",
"/run/secrets/kubernetes.io/serviceaccount/service-ca.crt",
Expand All @@ -54,6 +60,7 @@ def __init__(self):
logger.info(" VAULT_ROLE: %s", self.vault_role)
logger.info(" DB_USERNAME: %s", self.db_username)
logger.info(" CREDENTIALS_FILE: %s", self.credentials_file)
logger.info(" ZTVP_CA_BUNDLE: %s", self.ztvp_ca_bundle)
logger.info(" SERVICE_CA_FILE: %s", self.service_ca_file)
logger.info(" JWT_TOKEN_FILE: %s", self.jwt_token_file)

Expand All @@ -63,10 +70,22 @@ def __init__(self):

# Setup SSL context for CA verification
self.ssl_context = ssl.create_default_context()
if os.path.exists(self.service_ca_file):

# Try ZTVP CA bundle first (contains both ingress and service CAs)
if os.path.exists(self.ztvp_ca_bundle):
self.ssl_context.load_verify_locations(self.ztvp_ca_bundle)
logger.info("Loaded ZTVP trusted CA bundle from: %s", self.ztvp_ca_bundle)
# Fallback to service CA only (for backward compatibility)
elif os.path.exists(self.service_ca_file):
self.ssl_context.load_verify_locations(self.service_ca_file)
logger.info("Loaded service CA from: %s", self.service_ca_file)
else:
logger.warning("Service CA file not found, using default SSL context")
logger.warning(
"No CA certificates found at %s or %s. "
"Using default SSL context. SSL verification may fail.",
self.ztvp_ca_bundle,
self.service_ca_file,
)

def _make_http_request(
self, url, method="GET", data=None, headers=None, timeout=30
Expand Down Expand Up @@ -111,11 +130,11 @@ def _make_http_request(
"text": error_data,
"json": lambda: (json.loads(error_data) if error_data else {}),
}
except URLError as e:
logger.error("URL Error: %s", e)
except URLError:
logger.error("URL Error occurred")
raise
except Exception as e:
logger.error("Request error: %s", e)
except Exception:
logger.error("Request error occurred")
raise

def get_spiffe_token(self):
Expand All @@ -125,8 +144,8 @@ def get_spiffe_token(self):
jwt_svid = source.read()
logger.info("Successfully retrieved SPIFFE JWT token")
return jwt_svid
except Exception as e:
logger.error("Failed to retrieve SPIFFE token: %s", e)
except Exception:
logger.error("Failed to retrieve SPIFFE token")
raise

def authenticate_with_vault(self):
Expand Down Expand Up @@ -167,8 +186,8 @@ def authenticate_with_vault(self):

return True

except Exception as e:
logger.error("Vault authentication error: %s", e)
except Exception:
logger.error("Vault authentication error occurred")
raise

def retrieve_vault_secret(self):
Expand Down Expand Up @@ -204,8 +223,8 @@ def retrieve_vault_secret(self):

return secret_data

except Exception as e:
logger.error("Secret retrieval error: %s", e)
except Exception:
logger.error("Secret retrieval error occurred")
raise

def extract_credentials(self, secret_data):
Expand All @@ -222,8 +241,8 @@ def extract_credentials(self, secret_data):
credentials["db-username"] = self.db_username
return credentials

except Exception as e:
logger.error("Credential extraction error: %s", e)
except Exception:
logger.error("Credential extraction error occurred")
raise

def write_properties_file(self, credentials):
Expand All @@ -243,8 +262,8 @@ def write_properties_file(self, credentials):

logger.info("Credentials written to %s", self.credentials_file)

except Exception as e:
logger.error("Error writing properties file: %s", e)
except Exception:
logger.error("Error writing properties file")
raise

def is_token_renewal_needed(self):
Expand Down Expand Up @@ -291,8 +310,8 @@ def renew_vault_token(self):
)
return False

except Exception as e:
logger.warning("Token renewal error: %s. Re-authenticating...", e)
except Exception:
logger.warning("Token renewal error occurred. Re-authenticating...")
return False

def run(self, init=False):
Expand Down Expand Up @@ -329,8 +348,8 @@ def run(self, init=False):
except KeyboardInterrupt:
logger.info("Received interrupt signal, shutting down...")
break
except Exception as e:
logger.error("Error in main loop: %s", e)
except Exception:
logger.error("Error in main loop")
logger.info("Retrying in 60 seconds...")
time.sleep(60)

Expand All @@ -352,7 +371,7 @@ def main():
manager = VaultCredentialManager()
manager.run(args.init)
except Exception as e:
logger.error("Failed to start credential manager: %s", e)
logger.error("Failed to start credential manager")
raise SystemExit(1) from e


Expand Down
15 changes: 15 additions & 0 deletions charts/qtodo/templates/app-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ metadata:
argocd.argoproj.io/sync-wave: '20'
labels:
app: qtodo
ztvp.io/uses-certificates: "true"
name: qtodo
namespace: qtodo
spec:
Expand Down Expand Up @@ -65,13 +66,18 @@ spec:
value: /run/secrets/db-credentials/credentials.properties
- name: JWT_TOKEN_FILE
value: /svids/jwt.token
- name: ZTVP_CA_BUNDLE
value: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
volumeMounts:
- name: svids
mountPath: /svids
- name: db-credentials
mountPath: /run/secrets/db-credentials
- name: spiffe-vault-client
mountPath: /opt/app-root/src
- name: ztvp-trusted-ca
mountPath: /etc/pki/ca-trust/extracted/pem
readOnly: true
{{- end }}
containers:
{{- if and .Values.app.spire.enabled .Values.app.spire.sidecars }}
Expand Down Expand Up @@ -113,6 +119,8 @@ spec:
value: /run/secrets/db-credentials/credentials.properties
- name: JWT_TOKEN_FILE
value: /svids/jwt.token
- name: ZTVP_CA_BUNDLE
value: /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
volumeMounts:
- name: svids
mountPath: /svids
Expand All @@ -122,6 +130,9 @@ spec:
- name: spiffe-vault-client
mountPath: /opt/app-root/src
readOnly: true
- name: ztvp-trusted-ca
mountPath: /etc/pki/ca-trust/extracted/pem
readOnly: true
{{- end }}
- name: qtodo
image: {{ .Values.app.images.main.name }}:{{ .Values.app.images.main.tag }}
Expand Down Expand Up @@ -195,4 +206,8 @@ spec:
- name: spiffe-vault-client
configMap:
name: spiffe-vault-client
- name: ztvp-trusted-ca
configMap:
name: ztvp-trusted-ca
defaultMode: 420
{{- end }}
19 changes: 19 additions & 0 deletions charts/ztvp-certificates/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v2
name: ztvp-certificates
description: Global CA certificate management for ZTVP pattern components
type: application
version: 1.0.0
appVersion: "1.0.0"
keywords:
- certificates
- tls
- ssl
- ca-bundle
- zero-trust
home: https://github.com/validatedpatterns/layered-zero-trust
sources:
- https://github.com/validatedpatterns/layered-zero-trust
maintainers:
- name: Zero Trust Validated Patterns Team
email: ztvp-arch-group@redhat.com

Loading