diff --git a/charts/onelens-agent/Chart.yaml b/charts/onelens-agent/Chart.yaml index 4a754db..97dfc0b 100644 --- a/charts/onelens-agent/Chart.yaml +++ b/charts/onelens-agent/Chart.yaml @@ -2,15 +2,15 @@ apiVersion: v2 name: onelens-agent description: Helm chart for the OneLens Agent type: application -version: 1.8.0 -appVersion: 1.8.0 +version: 1.9.0 +appVersion: 1.9.0 maintainers: - name: OneLens email: support@onelens.ai dependencies: - name: onelens-agent-base repository: oci://609916866699.dkr.ecr.ap-south-1.amazonaws.com/helm-charts - version: 1.8.0 + version: 1.9.0 alias: onelens-agent condition: onelens-agent.enabled - name: prometheus diff --git a/charts/onelens-agent/values.yaml b/charts/onelens-agent/values.yaml index e7a69e9..ac66eff 100644 --- a/charts/onelens-agent/values.yaml +++ b/charts/onelens-agent/values.yaml @@ -2,7 +2,7 @@ onelens-agent: enabled: true image: repository: public.ecr.aws/w7k6q5m9/onelens-agent - tag: v1.8.0 + tag: v1.9.0 pullPolicy: IfNotPresent nameOverride: "onelens-agent" fullnameOverride: "onelens-agent" diff --git a/charts/onelensdeployer/Chart.yaml b/charts/onelensdeployer/Chart.yaml index 31dbfa2..c9d009c 100644 --- a/charts/onelensdeployer/Chart.yaml +++ b/charts/onelensdeployer/Chart.yaml @@ -5,5 +5,5 @@ maintainers: email: support@onelens.cloud name: onelensdeployer type: application -version: 1.8.0 -appVersion: 1.8.0 +version: 1.9.0 +appVersion: 1.9.0 diff --git a/charts/onelensdeployer/templates/bootstrap-clusterrole.yaml b/charts/onelensdeployer/templates/bootstrap-clusterrole.yaml new file mode 100644 index 0000000..7170711 --- /dev/null +++ b/charts/onelensdeployer/templates/bootstrap-clusterrole.yaml @@ -0,0 +1,9 @@ +{{- if .Values.bootstrapRbac.clusterRole.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Values.bootstrapRbac.clusterRole.name }} +rules: +{{- toYaml .Values.bootstrapRbac.clusterRole.rules | nindent 2 }} +{{- end }} + diff --git a/charts/onelensdeployer/templates/bootstrap-clusterrolebinding.yaml b/charts/onelensdeployer/templates/bootstrap-clusterrolebinding.yaml new file mode 100644 index 0000000..ac0d2a9 --- /dev/null +++ b/charts/onelensdeployer/templates/bootstrap-clusterrolebinding.yaml @@ -0,0 +1,18 @@ +{{- if .Values.bootstrapRbac.clusterRoleBinding.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Values.bootstrapRbac.clusterRoleBinding.name }} +subjects: + # Only bind the installation job service account to bootstrap ClusterRole + {{- if .Values.job.serviceAccount.enabled }} + - kind: ServiceAccount + name: {{ .Values.job.serviceAccount.name }} + namespace: {{ .Release.Namespace }} + {{- end }} +roleRef: + kind: ClusterRole + name: {{ .Values.bootstrapRbac.clusterRole.name }} + apiGroup: rbac.authorization.k8s.io +{{- end }} + diff --git a/charts/onelensdeployer/templates/clusterole.yaml b/charts/onelensdeployer/templates/clusterole.yaml index a9e78e1..00297da 100644 --- a/charts/onelensdeployer/templates/clusterole.yaml +++ b/charts/onelensdeployer/templates/clusterole.yaml @@ -1,14 +1,8 @@ +{{- if .Values.rbac.clusterRole.enabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - name: {{ .Values.job.clusterRole.name }} + name: {{ .Values.rbac.clusterRole.name }} rules: -{{- toYaml .Values.job.clusterRole.rules | nindent 2 }} - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: {{ .Values.cronjob.clusterRole.name }} -rules: -{{- toYaml .Values.cronjob.clusterRole.rules | nindent 2 }} \ No newline at end of file +{{- toYaml .Values.rbac.clusterRole.rules | nindent 2 }} +{{- end }} \ No newline at end of file diff --git a/charts/onelensdeployer/templates/clusterrolebinding.yaml b/charts/onelensdeployer/templates/clusterrolebinding.yaml index a07b847..968d57e 100644 --- a/charts/onelensdeployer/templates/clusterrolebinding.yaml +++ b/charts/onelensdeployer/templates/clusterrolebinding.yaml @@ -1,26 +1,22 @@ +{{- if .Values.rbac.clusterRoleBinding.enabled }} apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: - name: {{ .Values.job.clusterRoleBinding.name }} + name: {{ .Values.rbac.clusterRoleBinding.name }} subjects: + # Bind both job and cronjob service accounts to the shared ClusterRole + {{- if .Values.job.serviceAccount.enabled }} - kind: ServiceAccount name: {{ .Values.job.serviceAccount.name }} namespace: {{ .Release.Namespace }} -roleRef: - kind: ClusterRole - name: {{ .Values.job.clusterRole.name }} - apiGroup: rbac.authorization.k8s.io - ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: {{ .Values.cronjob.clusterRoleBinding.name }} -subjects: + {{- end }} + {{- if .Values.cronjob.serviceAccount.enabled }} - kind: ServiceAccount name: {{ .Values.cronjob.serviceAccount.name }} namespace: {{ .Release.Namespace }} + {{- end }} roleRef: kind: ClusterRole - name: {{ .Values.cronjob.clusterRole.name }} - apiGroup: rbac.authorization.k8s.io \ No newline at end of file + name: {{ .Values.rbac.clusterRole.name }} + apiGroup: rbac.authorization.k8s.io +{{- end }} \ No newline at end of file diff --git a/charts/onelensdeployer/templates/role.yaml b/charts/onelensdeployer/templates/role.yaml new file mode 100644 index 0000000..da41e5a --- /dev/null +++ b/charts/onelensdeployer/templates/role.yaml @@ -0,0 +1,10 @@ +{{- if .Values.rbac.role.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Values.rbac.role.name }} + namespace: {{ .Release.Namespace }} +rules: +{{- toYaml .Values.rbac.role.rules | nindent 2 }} +{{- end }} + diff --git a/charts/onelensdeployer/templates/rolebinding.yaml b/charts/onelensdeployer/templates/rolebinding.yaml new file mode 100644 index 0000000..c5a11c3 --- /dev/null +++ b/charts/onelensdeployer/templates/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.roleBinding.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Values.rbac.roleBinding.name }} + namespace: {{ .Release.Namespace }} +subjects: + # Bind both job and cronjob service accounts to the shared Role + {{- if .Values.job.serviceAccount.enabled }} + - kind: ServiceAccount + name: {{ .Values.job.serviceAccount.name }} + namespace: {{ .Release.Namespace }} + {{- end }} + {{- if .Values.cronjob.serviceAccount.enabled }} + - kind: ServiceAccount + name: {{ .Values.cronjob.serviceAccount.name }} + namespace: {{ .Release.Namespace }} + {{- end }} +roleRef: + kind: Role + name: {{ .Values.rbac.role.name }} + apiGroup: rbac.authorization.k8s.io +{{- end }} + diff --git a/charts/onelensdeployer/values.yaml b/charts/onelensdeployer/values.yaml index 659094f..db18165 100644 --- a/charts/onelensdeployer/values.yaml +++ b/charts/onelensdeployer/values.yaml @@ -1,8 +1,171 @@ +# ================================================================================== +# BOOTSTRAP RBAC CONFIGURATION (Installation Job Only) +# ================================================================================== +# Used ONLY by the installation job to CREATE cluster-scoped resources +# This is deleted after installation completes (see install.sh cleanup) +bootstrapRbac: + clusterRole: + enabled: true + name: onelensdeployer-bootstrap-clusterrole + rules: + # Namespace creation permission + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["create"] + # StorageClass creation permission + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["create"] + # ClusterRole creation permission + - apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles"] + verbs: ["create"] + # ClusterRoleBinding creation permission + - apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterrolebindings"] + verbs: ["create"] + clusterRoleBinding: + enabled: true + name: onelensdeployer-bootstrap-clusterrolebinding + +# ================================================================================== +# ONGOING RBAC CONFIGURATION (Both Job & CronJob) +# ================================================================================== +# Used by both installation job and updater cronjob to MANAGE existing resources +# This follows the principle of least privilege with strict resourceNames restrictions +rbac: + # Namespace-scoped permissions - we own all resources in this namespace + role: + enabled: true + name: onelensdeployer-role + rules: + # Full control over all namespace-scoped resources - we own this namespace + - apiGroups: ["*"] + resources: ["*"] + verbs: ["*"] + roleBinding: + enabled: true + name: onelensdeployer-rolebinding + + # Cluster-scoped permissions - minimal with strict resourceNames restrictions + clusterRole: + enabled: true + name: onelensdeployer-clusterrole + rules: + # StorageClass permissions - we own this resource, restricted by resourceNames + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["*"] + resourceNames: + - onelens-sc + # Namespace permissions - we own onelens-agent namespace + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["*"] + resourceNames: + - onelens-agent + # Cluster-scoped READ-ONLY permissions required to manage ClusterRoles + # These permissions are needed because when you patch a ClusterRole, + # you must have all the permissions that ClusterRole grants (escalation protection) + # Also required for monitoring components like kube-state-metrics and Prometheus + - apiGroups: [""] + resources: + - configmaps + - deployments + - endpoints + - ingresses + - limitranges + - namespaces + - nodes + - nodes/metrics + - nodes/proxy + - persistentvolumeclaims + - persistentvolumes + - pods + - replicationcontrollers + - resourcequotas + - services + verbs: ["get", "list", "watch"] + - apiGroups: ["apps"] + resources: + - daemonsets + - deployments + - replicasets + - statefulsets + verbs: ["get", "list", "watch"] + - apiGroups: ["autoscaling"] + resources: + - horizontalpodautoscalers + verbs: ["get", "list", "watch"] + - apiGroups: ["batch"] + resources: + - cronjobs + - jobs + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: + - daemonsets + - deployments + - ingresses + - ingresses/status + - replicasets + verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: + - ingresses + - ingresses/status + verbs: ["get", "list", "watch"] + - apiGroups: ["discovery.k8s.io"] + resources: + - endpointslices + verbs: ["get", "list", "watch"] + - apiGroups: ["policy"] + resources: + - poddisruptionbudgets + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: + - storageclasses + verbs: ["get", "list", "watch"] + # Non-resource URL permissions for Prometheus metrics scraping + - nonResourceURLs: + - /metrics + verbs: ["get"] + # ClusterRole permissions - we own these resources, restricted by resourceNames + - apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles"] + verbs: ["*"] + resourceNames: + - onelens-agent-kube-state-metrics + - onelens-agent-prometheus-opencost-exporter + - onelens-agent-prometheus-server + - onelens-agent-workload-reader + - onelensdeployer-clusterrole + - onelensdeployer-bootstrap-clusterrole + # ClusterRoleBinding permissions - we own these resources, restricted by resourceNames + - apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterrolebindings"] + verbs: ["*"] + resourceNames: + - onelens-agent-kube-state-metrics + - onelens-agent-prometheus-opencost-exporter + - onelens-agent-prometheus-server + - onelens-agent-workload-reader-binding + - onelensdeployer-clusterrolebinding + - onelensdeployer-bootstrap-clusterrolebinding + clusterRoleBinding: + enabled: true + name: onelensdeployer-clusterrolebinding + +# ================================================================================== +# INSTALLATION JOB +# ================================================================================== +# One-time job that performs initial installation using shared RBAC permissions job: enabled: true name: onelensdeployerjob image: public.ecr.aws/w7k6q5m9/onelens-deployer - imageTag: v1.8.0 + imageTag: v1.9.0 imagePullPolicy: Always restartPolicy: Never backoffLimit: 2 @@ -28,20 +191,17 @@ job: serviceAccount: enabled: true name: onelensdeployerjob-sa - clusterRole: - name: onelensdeployerjob-clusterrole - rules: - - apiGroups: ["*"] - resources: ["*"] - verbs: ["*"] - clusterRoleBinding: - name: onelensdeployerjob-clusterrolebinding + +# ================================================================================== +# UPDATER CRONJOB +# ================================================================================== +# Periodic job that performs helm upgrade using shared RBAC permissions cronjob: enabled: true name: onelensupdater schedule: "0 2 * * *" image: public.ecr.aws/w7k6q5m9/onelens-deployer - imageTag: v1.8.0 + imageTag: v1.9.0 restartPolicy: Never env: deployment_type: cronjob @@ -69,44 +229,3 @@ cronjob: serviceAccount: enabled: true name: onelensupdater-sa - clusterRole: - name: onelensupdater-clusterrole - rules: - # Read access needed to inspect current deployments and resources - - apiGroups: ["", "apps", "autoscaling", "batch", "extensions", "policy", "rbac.authorization.k8s.io", "networking.k8s.io"] - resources: ["deployments", "replicasets", "pods", "services", "configmaps", "secrets", "persistentvolumeclaims", "statefulsets", "horizontalpodautoscalers", "ingresses", "networkpolicies", "roles", "rolebindings", "serviceaccounts", "daemonsets", "jobs", "cronjobs"] - verbs: ["get", "list", "watch", "patch", "update"] - # Write access to perform patching and upgrades - - apiGroups: ["", "apps", "autoscaling", "batch", "extensions", "policy", "rbac.authorization.k8s.io", "networking.k8s.io"] - resources: ["deployments", "replicasets", "pods", "services", "configmaps", "secrets", "persistentvolumeclaims", "statefulsets", "horizontalpodautoscalers", "ingresses", "networkpolicies", "roles", "rolebindings", "serviceaccounts", "daemonsets", "jobs", "cronjobs"] - verbs: ["create", "get", "list", "patch", "update", "watch"] - # Namespace discovery - - apiGroups: [""] - resources: ["namespaces"] - verbs: ["get", "list", "watch", "patch", "update"] - # Read access to RBAC resources - - apiGroups: ["rbac.authorization.k8s.io"] - resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"] - verbs: ["get", "list", "watch", "patch", "update"] - # Read access to limitranges - - apiGroups: [""] - resources: ["limitranges"] - verbs: ["list", "watch", "patch", "update"] - # Read access to nodes - - apiGroups: [""] - resources: ["nodes"] - verbs: ["get", "list", "watch", "patch", "update"] - # Read access to persistentvolumes - - apiGroups: [""] - resources: ["persistentvolumes"] - verbs: ["list", "watch", "patch", "update"] - # Read access to resourcequotas - - apiGroups: [""] - resources: ["resourcequotas"] - verbs: ["list", "watch", "patch", "update"] - # Read access to StorageClasses - - apiGroups: ["storage.k8s.io"] - resources: ["storageclasses"] - verbs: ["get", "list", "watch", "patch", "update"] - clusterRoleBinding: - name: onelensupdater-clusterrolebinding diff --git a/charts/onelensdeployer/version.md b/charts/onelensdeployer/version.md index 9a7ff2b..699f97a 100644 --- a/charts/onelensdeployer/version.md +++ b/charts/onelensdeployer/version.md @@ -10,3 +10,4 @@ #1.6.0 - set resources for ksm , gateway , reloader #1.7.0 - API's changes #1.8.0 - Adaptive KSM and Pushgateway Resource config +#1.9.0 - Implement Principle of least privilege \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 5ca6c9a..737bae5 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,7 +1,7 @@ #!/bin/bash # Global API endpoint -API_ENDPOINT="https://api-gp.onelens.cloud" +API_ENDPOINT="https://api-in.onelens.cloud" # Function to update cluster version logs update_cluster_logs() { diff --git a/globalvalues.yaml b/globalvalues.yaml index 759b77d..3132940 100644 --- a/globalvalues.yaml +++ b/globalvalues.yaml @@ -3,7 +3,7 @@ onelens-agent: image: repository: public.ecr.aws/w7k6q5m9/onelens-agent - tag: v1.8.0 + tag: v1.9.0 pullPolicy: IfNotPresent nameOverride: "onelens-agent" diff --git a/install.sh b/install.sh index 261ccdb..6b7021a 100755 --- a/install.sh +++ b/install.sh @@ -34,7 +34,7 @@ send_logs() { trap 'code=$?; if [ $code -ne 0 ]; then send_logs; fi; exit $code' EXIT # Phase 2: Environment Variable Setup -: "${RELEASE_VERSION:=1.8.0}" +: "${RELEASE_VERSION:=1.9.0}" : "${IMAGE_TAG:=v$RELEASE_VERSION}" : "${API_BASE_URL:=https://api-in.onelens.cloud}" : "${PVC_ENABLED:=true}" @@ -390,7 +390,7 @@ else fi CMD="helm upgrade --install onelens-agent -n onelens-agent --create-namespace onelens/onelens-agent \ - --version \"\${RELEASE_VERSION:=1.8.0}\" \ + --version \"\${RELEASE_VERSION:=1.9.0}\" \ -f $FILE \ --set onelens-agent.env.CLUSTER_NAME=\"$CLUSTER_NAME\" \ --set-string onelens-agent.env.ACCOUNT_ID=\"$ACCOUNT\" \ @@ -523,7 +523,15 @@ curl -X PUT "$API_BASE_URL/v1/kubernetes/registration" \ }" echo "To verify deployment: kubectl get pods -n onelens-agent" sleep 60 + +# Cleanup bootstrap RBAC resources (used only for initial installation) +echo "Cleaning up bootstrap RBAC resources..." +kubectl delete clusterrolebinding onelensdeployer-bootstrap-clusterrolebinding || true +kubectl delete clusterrole onelensdeployer-bootstrap-clusterrole || true + +# Cleanup installation job resources +echo "Cleaning up installation job resources..." kubectl delete job onelensdeployerjob -n onelens-agent || true -kubectl delete clusterrole onelensdeployerjob-clusterrole || true -kubectl delete clusterrolebinding onelensdeployerjob-clusterrolebinding || true kubectl delete sa onelensdeployerjob-sa -n onelens-agent || true + +echo "Bootstrap cleanup complete. Ongoing RBAC resources retained for cronjob updates."