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
15 changes: 15 additions & 0 deletions helm-charts/secrets-operator/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{- if .Values.configureBasicKubernetesAuth }}
{{- $namespace := .Release.Namespace }}
==========================================
Installation complete.
==========================================

To view the reviewer token, CA certificate, and Kubernetes host, run:

kubectl logs -n {{ $namespace }} -l app.kubernetes.io/component=token-setup --tail=100

==========================================
{{- else }}
Installation complete.
{{- end }}

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{ if .Values.configureBasicKubernetesAuth }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: infisical-token-reviewer-role-binding
namespace: {{ .Release.Namespace }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: infisical-token-reviewer
namespace: {{ .Release.Namespace }}
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{{- if .Values.configureBasicKubernetesAuth }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "secrets-operator.fullname" . }}-token-setup
namespace: {{ .Release.Namespace }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "1"
"helm.sh/hook-delete-policy": before-hook-creation # we keep the job after successful creation so we can view logs afterwards
Copy link

Choose a reason for hiding this comment

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

style: The comment states "we keep the job after successful creation so we can view logs afterwards" but this perpetuates the security issue of having sensitive tokens in logs.

Consider using hook-delete-policy: hook-succeeded to clean up the job and its logs after successful completion, reducing the window of token exposure.

labels:
{{- include "secrets-operator.labels" . | nindent 4 }}
app.kubernetes.io/component: token-setup
spec:
activeDeadlineSeconds: 30 # Timeout after 30 seconds to prevent Helm from hanging
Copy link

Choose a reason for hiding this comment

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

style: 30 seconds may be too short for slower clusters or during high load. If the token secret takes longer to provision, the job will fail and Helm may hang or report failure even though the resources were created successfully.

Consider increasing to 60-120 seconds to account for cluster variability.

backoffLimit: 0 # Don't retry the Job if it fails
template:
metadata:
labels:
{{- include "secrets-operator.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: token-setup
spec:
serviceAccountName: {{ include "secrets-operator.serviceAccountName" . }}
restartPolicy: Never
containers:
- name: token-setup
image: bitnami/kubectl:latest
Copy link

Choose a reason for hiding this comment

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

logic: Using latest tag without digest pinning creates supply chain security risks. A compromised or malicious image pushed to this tag could execute arbitrary code during Helm installation.

Attack vector: If the bitnami/kubectl repository is compromised, attackers could push malicious code that executes with the permissions of the service account during post-install hooks.

Consider pinning to a specific version and digest:

Suggested change
image: bitnami/kubectl:latest
image: bitnami/kubectl:1.31.3@sha256:<digest-here>

command:
- /bin/sh
- -c
- |
set -e
echo "Patching service account infisical-token-reviewer..."
kubectl patch serviceaccount infisical-token-reviewer \
-p '{"secrets": [{"name": "infisical-token-reviewer-token"}]}' \
-n {{ .Release.Namespace }} || echo "Note: Service account may already be patched"

echo "Waiting for token secret to be available..."
MAX_RETRIES=15
RETRY_COUNT=0

while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
if kubectl get secret infisical-token-reviewer-token -n {{ .Release.Namespace }} &>/dev/null; then
TOKEN=$(kubectl get secret infisical-token-reviewer-token -n {{ .Release.Namespace }} -o=jsonpath='{.data.token}' 2>/dev/null | base64 -d 2>/dev/null || echo "")
if [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ]; then
# Get CA certificate from the secret
CA_CERT=$(kubectl get secret infisical-token-reviewer-token -n {{ .Release.Namespace }} -o=jsonpath='{.data.ca\.crt}' 2>/dev/null | base64 -d 2>/dev/null || echo "")

echo ""
echo "=========================================="
echo "Installation complete."
echo ""
echo "Reviewer token:"
echo ""
echo "$TOKEN"
echo ""
echo ""
if [ -n "$CA_CERT" ]; then
echo "CA certificate:"
echo ""
echo "$CA_CERT"
Comment on lines +55 to +61
Copy link

Choose a reason for hiding this comment

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

logic: CRITICAL SECURITY ISSUE: Printing sensitive service account tokens directly to stdout exposes them in Kubernetes logs, which persist indefinitely and can be accessed by anyone with log viewing permissions.

Attack vector: A malicious actor with kubectl logs access can extract this token and use it to authenticate as the infisical-token-reviewer service account with system:auth-delegator cluster-level permissions. This token could be used to validate other service account tokens across the entire cluster.

Risks:

  • Tokens remain in logs even after rotation
  • Logs may be forwarded to external logging systems (Splunk, ELK, etc.)
  • Audit logs expose credentials
  • No expiration control once logged

Safer alternatives:

  1. Store token in a Kubernetes Secret and instruct users to retrieve it via kubectl get secret
  2. Use a one-time retrieval mechanism
  3. Don't echo the token at all - provide instructions for users to extract it themselves when needed
  4. Use short-lived tokens with automatic rotation

else
echo "CA certificate: (not available in secret)"
echo ""
fi
echo ""
echo "Kubernetes host:"
echo ""
echo "Unable to determine Kubernetes host. You can find your Kubernetes host by running 'kubectl cluster-info'."
echo "Ensure that the Kubernetes host is accessible by Infisical. If this is a private cluster, you may need to configure the Infisical Gateway to allow access to the Kubernetes host from Infisical."
echo ""
echo ""
echo "=========================================="
exit 0
fi
fi
RETRY_COUNT=$((RETRY_COUNT + 1))
echo " Attempt $RETRY_COUNT/$MAX_RETRIES: Token not ready yet, waiting..."
sleep 1
done

echo ""
echo "Warning: Token not available after $MAX_RETRIES attempts."
echo "Please check the secret manually with:"
echo " kubectl get secret infisical-token-reviewer-token -n {{ .Release.Namespace }} -o=jsonpath='{.data.token}' | base64 --decode && echo"
exit 1
{{- end }}

Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{{- if .Values.configureBasicKubernetesAuth }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "secrets-operator.fullname" . }}-token-setup-role
namespace: {{ .Release.Namespace }}
labels:
{{- include "secrets-operator.labels" . | nindent 4 }}
app.kubernetes.io/component: token-setup
rules:
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- patch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "secrets-operator.fullname" . }}-token-setup-rolebinding
namespace: {{ .Release.Namespace }}
labels:
{{- include "secrets-operator.labels" . | nindent 4 }}
app.kubernetes.io/component: token-setup
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "secrets-operator.fullname" . }}-token-setup-role
subjects:
- kind: ServiceAccount
name: {{ include "secrets-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{ if .Values.configureBasicKubernetesAuth }}
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: infisical-token-reviewer-token
namespace: {{ .Release.Namespace }}
annotations:
kubernetes.io/service-account.name: infisical-token-reviewer
{{- end }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{ if .Values.configureBasicKubernetesAuth }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: infisical-token-reviewer
namespace: {{ .Release.Namespace }}
{{- end }}
1 change: 1 addition & 0 deletions helm-charts/secrets-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ kubernetesClusterDomain: cluster.local
scopedNamespace: ""
scopedRBAC: false
installCRDs: true
configureBasicKubernetesAuth: false
Copy link

Choose a reason for hiding this comment

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

style: The new configureBasicKubernetesAuth parameter lacks documentation in the README. Users won't discover this feature without examining source code. Add documentation explaining what it does, when to enable it, security implications, and how to use the generated token.

Context Used: Context from dashboard - When naming sections in documentation, use clear and descriptive titles that reflect the functionali... (source)

imagePullSecrets: []