diff --git a/README-PUBLIC.md b/README.md similarity index 96% rename from README-PUBLIC.md rename to README.md index 127f8db..0e45c6c 100644 --- a/README-PUBLIC.md +++ b/README.md @@ -1,711 +1,711 @@ -# ManagedSecret Operator - -A Kubernetes operator for declarative secret management with automated rotation, drift detection, and zero-downtime password changes. - -## Overview - -The ManagedSecret operator provides: - -- 🔐 **Generates secrets** with configurable password policies -- 🏦 **Stores in Vault/OpenBao** as the authoritative source -- 🔄 **Syncs to Kubernetes Secrets** for application consumption -- 🔍 **Detects and fixes drift** automatically (Vault → K8s) -- 🔁 **Rotates secrets** on a configurable schedule -- ⏱️ **Preserves previous versions** during rotation for zero-downtime password changes - -### Key Principle: Vault/OpenBao is ALWAYS the source of truth - -- Changes in Vault → Synced to K8s automatically -- Changes in K8s → Overwritten by Vault values -- Drift detection runs every 1 minute - ---- - -## 🚀 Quick Start - -> **Prerequisites:** Contact your administrator to receive: -> - Registry username and password for `registry.c5ai.ch` -> - Confirmation that OpenBao/Vault is configured for your cluster - -```bash -# 1. Set your credentials (provided by administrator) -export REGISTRY_USER="" -export REGISTRY_PASS="" - -# 2. Install Reloader (for automatic pod restarts during rotation) -kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml - -# 3. Login to Helm registry -helm registry login registry.c5ai.ch -u $REGISTRY_USER -p $REGISTRY_PASS - -# 4. Create imagePullSecret -kubectl create namespace managedsecret-operator-system -kubectl create secret docker-registry registry-pull-secret \ - --docker-server=registry.c5ai.ch \ - --docker-username=$REGISTRY_USER \ - --docker-password=$REGISTRY_PASS \ - --namespace managedsecret-operator-system - -# 5. Install operator via Helm -helm install managedsecret-operator oci://registry.c5ai.ch/charts/managedsecret-operator \ - --version 1.0.7 \ - --namespace managedsecret-operator-system \ - --set imagePullSecrets[0].name=registry-pull-secret - -# 6. Verify installation -kubectl get pods -n managedsecret-operator-system -``` - -That's it! Now check the [examples](./examples/) folder for comprehensive usage scenarios. - ---- - -## 📦 What You Get - -### Helm Chart from registry.c5ai.ch - -The operator is distributed as a Helm chart: - -- ✅ **No building required** - Just `helm install` -- ✅ **Versioned releases** - Use specific versions or upgrade easily -- ✅ **Pre-configured** - Sensible defaults, customize via `values.yaml` -- ✅ **Private & secure** - Hosted on your infrastructure - -### What's Deployed - -``` -managedsecret-operator-system/ -├── CustomResourceDefinition (ManagedSecret) -├── ServiceAccount (controller-manager) -├── Role & RoleBinding (RBAC) -├── ClusterRole & ClusterRoleBinding -├── Deployment (controller-manager) -└── ConfigMap (operator configuration) -``` - ---- - -## Prerequisites - -### On Your Side (User) -- ✅ Kubernetes cluster (1.24+) -- ✅ kubectl configured and working -- ✅ Helm 3.x installed -- ✅ Cluster admin permissions - -### Provided by Administrator -- ✅ **Registry credentials** for `registry.c5ai.ch` -- ✅ **OpenBao/Vault configuration** for your cluster - - Vault address (e.g., `http://openbao.openbao.svc.cluster.local:8200`) - - Kubernetes auth configured - - Vault role name (typically `managedsecret-operator`) - -### Optional (Recommended) -- ✅ **Reloader by Stakater** (for automatic pod restarts on rotation) - ---- - -## Installation Steps - -### Step 1: Install Reloader (Recommended) - -Reloader automatically restarts pods when secrets change: - -```bash -# Direct install (simplest) -kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml - -# Via Helm -helm repo add stakater https://stakater.github.io/stakater-charts -helm install reloader stakater/reloader \ - --namespace reloader \ - --create-namespace -``` - -### Step 2: Authenticate to Registry - -```bash -# Set credentials from administrator -export REGISTRY_USER="" -export REGISTRY_PASS="" - -# Login to Helm registry -helm registry login registry.c5ai.ch -u $REGISTRY_USER -p $REGISTRY_PASS - -# Create namespace -kubectl create namespace managedsecret-operator-system - -# Create imagePullSecret -kubectl create secret docker-registry registry-pull-secret \ - --docker-server=registry.c5ai.ch \ - --docker-username=$REGISTRY_USER \ - --docker-password=$REGISTRY_PASS \ - --namespace managedsecret-operator-system -``` - -### Step 3: Install the Operator - -```bash -# Install with default configuration -helm install managedsecret-operator \ - oci://registry.c5ai.ch/charts/managedsecret-operator \ - --version 1.0.7 \ - --namespace managedsecret-operator-system \ - --set imagePullSecrets[0].name=registry-pull-secret - -# Or with custom values -cat > values.yaml <-previous with old values - 4. Updates K8s Secret with new values - 5. If Reloader is enabled: - - Reloader detects change → Restarts pods - 6. After previousVersionTTL: - - Operator deletes -previous secret -``` - -### When to Use `keepPreviousVersion` - -Use `keepPreviousVersion: true` when your service needs the **old password to authenticate** before changing to the new password: - -- ✅ PostgreSQL, MySQL, MariaDB (`ALTER USER` requires authentication) -- ✅ MinIO (`mc admin` needs old credentials) -- ✅ LDAP, Active Directory -- ❌ Container registries (htpasswd regenerated fresh) -- ❌ Redis (CONFIG SET doesn't need old password) -- ❌ Web services with startup scripts - -### Forcing Rotation - -```bash -# Trigger immediate rotation -kubectl annotate managedsecret -n \ - reconcile="$(date +%s)" --overwrite -``` - ---- - -## 🔍 Drift Detection - -The operator automatically detects and fixes drift every 60 seconds: - -**Scenario 1: Secret deleted in Kubernetes** -```bash -kubectl delete secret my-secret -n my-app -# Operator recreates it from Vault within 60 seconds -``` - -**Scenario 2: Secret modified in Vault** -```bash -# Update value in Vault -vault kv put secret/my-app/keys password=newvalue -# Operator syncs to K8s within 60 seconds -``` - -**Scenario 3: Secret manually edited in K8s** -```bash -kubectl edit secret my-secret -n my-app -# Changes are overwritten by Vault values within 60 seconds -``` - ---- - -## 🔧 Troubleshooting - -### Operator Not Starting - -```bash -# Check pod status -kubectl get pods -n managedsecret-operator-system - -# View logs -kubectl logs -n managedsecret-operator-system \ - -l control-plane=controller-manager --tail=100 - -# Common issues: -# - ImagePullBackOff: Check imagePullSecret is created correctly -# - CrashLoopBackOff: Check Vault connectivity -``` - -### Secret Not Created - -```bash -# Check ManagedSecret status -kubectl get managedsecret -n -o yaml - -# Look for conditions/events -kubectl describe managedsecret -n - -# Check operator logs -kubectl logs -n managedsecret-operator-system \ - -l control-plane=controller-manager | grep -``` - -### Vault Authentication Failing - -```bash -# Verify ServiceAccount exists -kubectl get sa controller-manager -n managedsecret-operator-system - -# Check Vault role configuration -vault read auth/kubernetes/role/managedsecret-operator - -# Test authentication manually -kubectl exec -it -n managedsecret-operator-system \ - deployment/managedsecret-operator-controller-manager -- sh -# Inside pod: Check /var/run/secrets/kubernetes.io/serviceaccount/token exists -``` - -### Rotation Not Working - -```bash -# Check ManagedSecret schedule -kubectl get managedsecret -n -o yaml | grep schedule - -# Force rotation to test -kubectl annotate managedsecret -n \ - reconcile="$(date +%s)" --overwrite - -# Check if Reloader is installed (if using rotation) -kubectl get pods -n reloader -``` - -### Reloader Not Restarting Pods - -```bash -# Verify Reloader is running -kubectl get pods -n reloader - -# Check pod has correct annotation -kubectl get deployment -n -o yaml | grep reloader - -# View Reloader logs -kubectl logs -n reloader -l app=reloader - -# Required annotation on pod template: -# annotations: -# reloader.stakater.com/auto: "true" -``` - ---- - -## 🎯 Best Practices - -### 1. Always Use Reloader for Rotating Secrets - -Without Reloader, pods won't pick up new credentials: -```yaml -template: - metadata: - annotations: - reloader.stakater.com/auto: "true" -``` - -### 2. Set Appropriate Rotation Schedules - -- **High Security** (passwords, admin credentials): 30-90 days -- **Medium Security** (application credentials): 90-180 days -- **Low Security** (read-only API keys): 180+ days or disabled - -### 3. Use `keepPreviousVersion` Correctly - -Only use it when the service needs the old password to authenticate: -```yaml -destination: - keepPreviousVersion: true # Only if old password is needed - previousVersionTTL: 1h # Adjust based on your workflow -``` - -### 4. Test Rotation Before Production - -```bash -# Create test ManagedSecret with short rotation -spec: - rotation: - enabled: true - schedule: 5m # Test rotation every 5 minutes - -# Watch the rotation -kubectl get secrets -n -w - -# Verify application handles rotation -kubectl logs -n -``` - -### 5. Monitor Rotation Jobs - -For services using `keepPreviousVersion`, monitor your CronJobs: -```bash -# Check job status -kubectl get jobs -n - -# View job logs -kubectl logs -n -l job-name= - -# Set up alerts for failed jobs -``` - -### 6. Backup Vault Regularly - -Vault is your source of truth: -```bash -# Example: Backup with Velero -velero backup create vault-backup \ - --include-namespaces openbao \ - --snapshot-volumes -``` - -### 7. Version Control Your ManagedSecrets - -Store ManagedSecret manifests in Git: -```yaml -# managedsecrets/ -# ├── production/ -# │ ├── postgres-credentials.yaml -# │ └── api-keys.yaml -# └── staging/ -# ├── postgres-credentials.yaml -# └── api-keys.yaml -``` - -### 8. Use GitOps for Deployment - -Deploy with ArgoCD or Flux: -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: managedsecrets -spec: - source: - path: managedsecrets/production - destination: - namespace: default -``` - ---- - -## 🔒 Security Considerations - -### Production Checklist - -- [ ] OpenBao/Vault is properly secured (TLS, audit logging, backups) -- [ ] RBAC configured with least-privilege -- [ ] Network policies in place -- [ ] Monitoring and alerting configured -- [ ] Disaster recovery plan documented -- [ ] Registry credentials stored securely (not in Git) - -### Credentials Management - -The operator needs: -1. Access to Vault (via Kubernetes ServiceAccount auth) -2. Access to pull its image (via imagePullSecret) - -Both use Kubernetes-native methods. **Never hardcode credentials in manifests!** - ---- - -## 📞 Support - -### Getting Help - -1. **Check documentation**: - - This README - - [examples/EXAMPLES-SUMMARY.md](./examples/EXAMPLES-SUMMARY.md) - - Individual example files - -2. **Check operator logs**: - ```bash - kubectl logs -n managedsecret-operator-system \ - -l control-plane=controller-manager --tail=100 - ``` - -3. **Contact your administrator** if: - - You need registry credentials - - Vault is not configured for your cluster - - Operator authentication issues - -### For Administrators - -#### Information to Provide Users - -**Registry Credentials:** -``` -Registry: registry.c5ai.ch -Username: -Password: -Chart: oci://registry.c5ai.ch/charts/managedsecret-operator -Version: 1.0.7 -``` - -**Vault Configuration:** -``` -Address: http://openbao.openbao.svc.cluster.local:8200 -Auth Method: kubernetes -Role: managedsecret-operator -KV Mount: secret -KV Version: v2 -``` - -#### Prerequisites for New Cluster - -```bash -# 1. Enable Kubernetes auth -bao auth enable kubernetes -bao write auth/kubernetes/config \ - kubernetes_host="https://kubernetes.default.svc:443" - -# 2. Create policy -bao policy write managedsecret-operator - <<'EOF' -path "secret/data/*" { - capabilities = ["create", "read", "update", "delete", "list"] -} -path "secret/metadata/*" { - capabilities = ["list", "read", "delete"] -} -EOF - -# 3. Create role -bao write auth/kubernetes/role/managedsecret-operator \ - bound_service_account_names=controller-manager \ - bound_service_account_namespaces=managedsecret-operator-system \ - policies=managedsecret-operator \ - ttl=1h -``` - ---- - -## 🔄 Upgrading - -### Upgrade Operator Version - -```bash -# Check current version -helm list -n managedsecret-operator-system - -# Upgrade to new version -helm upgrade managedsecret-operator \ - oci://registry.c5ai.ch/charts/managedsecret-operator \ - --version 1.0.8 \ - --namespace managedsecret-operator-system \ - --reuse-values -``` - -### Migration Notes - -When upgrading from earlier versions: -- CRD updates are handled automatically -- Existing ManagedSecrets continue to work -- No manual migration required -- Check changelog for breaking changes - ---- - -## 📝 Changelog - -### Version 1.0.7 -- ✨ Added `keepPreviousVersion` for zero-downtime rotation -- ✨ Added `previousVersionTTL` for automatic cleanup -- 📦 Helm chart deployment support -- 📚 Comprehensive examples and documentation -- 🐛 Bug fixes and improvements - ---- - -## License - -Proprietary Use License - -Permission is granted to use this software for any purpose, including commercial use, without charge. - -Modification, adaptation, or creation of derivative works is prohibited. -Redistribution of modified versions is prohibited. - ---- - -**Version:** 1.0.7 -**Registry:** registry.c5ai.ch/charts/managedsecret-operator -**Minimum Kubernetes:** 1.24+ +# ManagedSecret Operator + +A Kubernetes operator for declarative secret management with automated rotation, drift detection, and zero-downtime password changes. + +## Overview + +The ManagedSecret operator provides: + +- 🔐 **Generates secrets** with configurable password policies +- 🏦 **Stores in Vault/OpenBao** as the authoritative source +- 🔄 **Syncs to Kubernetes Secrets** for application consumption +- 🔍 **Detects and fixes drift** automatically (Vault → K8s) +- 🔁 **Rotates secrets** on a configurable schedule +- ⏱️ **Preserves previous versions** during rotation for zero-downtime password changes + +### Key Principle: Vault/OpenBao is ALWAYS the source of truth + +- Changes in Vault → Synced to K8s automatically +- Changes in K8s → Overwritten by Vault values +- Drift detection runs every 1 minute + +--- + +## 🚀 Quick Start + +> **Prerequisites:** Contact your administrator to receive: +> - Registry username and password for `registry.c5ai.ch` +> - Confirmation that OpenBao/Vault is configured for your cluster + +```bash +# 1. Set your credentials (provided by administrator) +export REGISTRY_USER="" +export REGISTRY_PASS="" + +# 2. Install Reloader (for automatic pod restarts during rotation) +kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml + +# 3. Login to Helm registry +helm registry login registry.c5ai.ch -u $REGISTRY_USER -p $REGISTRY_PASS + +# 4. Create imagePullSecret +kubectl create namespace managedsecret-operator-system +kubectl create secret docker-registry registry-pull-secret \ + --docker-server=registry.c5ai.ch \ + --docker-username=$REGISTRY_USER \ + --docker-password=$REGISTRY_PASS \ + --namespace managedsecret-operator-system + +# 5. Install operator via Helm +helm install managedsecret-operator oci://registry.c5ai.ch/charts/managedsecret-operator \ + --version 1.0.7 \ + --namespace managedsecret-operator-system \ + --set imagePullSecrets[0].name=registry-pull-secret + +# 6. Verify installation +kubectl get pods -n managedsecret-operator-system +``` + +That's it! Now check the [examples](./examples/) folder for comprehensive usage scenarios. + +--- + +## 📦 What You Get + +### Helm Chart from registry.c5ai.ch + +The operator is distributed as a Helm chart: + +- ✅ **No building required** - Just `helm install` +- ✅ **Versioned releases** - Use specific versions or upgrade easily +- ✅ **Pre-configured** - Sensible defaults, customize via `values.yaml` +- ✅ **Private & secure** - Hosted on your infrastructure + +### What's Deployed + +``` +managedsecret-operator-system/ +├── CustomResourceDefinition (ManagedSecret) +├── ServiceAccount (controller-manager) +├── Role & RoleBinding (RBAC) +├── ClusterRole & ClusterRoleBinding +├── Deployment (controller-manager) +└── ConfigMap (operator configuration) +``` + +--- + +## Prerequisites + +### On Your Side (User) +- ✅ Kubernetes cluster (1.24+) +- ✅ kubectl configured and working +- ✅ Helm 3.x installed +- ✅ Cluster admin permissions + +### Provided by Administrator +- ✅ **Registry credentials** for `registry.c5ai.ch` +- ✅ **OpenBao/Vault configuration** for your cluster + - Vault address (e.g., `http://openbao.openbao.svc.cluster.local:8200`) + - Kubernetes auth configured + - Vault role name (typically `managedsecret-operator`) + +### Optional (Recommended) +- ✅ **Reloader by Stakater** (for automatic pod restarts on rotation) + +--- + +## Installation Steps + +### Step 1: Install Reloader (Recommended) + +Reloader automatically restarts pods when secrets change: + +```bash +# Direct install (simplest) +kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml + +# Via Helm +helm repo add stakater https://stakater.github.io/stakater-charts +helm install reloader stakater/reloader \ + --namespace reloader \ + --create-namespace +``` + +### Step 2: Authenticate to Registry + +```bash +# Set credentials from administrator +export REGISTRY_USER="" +export REGISTRY_PASS="" + +# Login to Helm registry +helm registry login registry.c5ai.ch -u $REGISTRY_USER -p $REGISTRY_PASS + +# Create namespace +kubectl create namespace managedsecret-operator-system + +# Create imagePullSecret +kubectl create secret docker-registry registry-pull-secret \ + --docker-server=registry.c5ai.ch \ + --docker-username=$REGISTRY_USER \ + --docker-password=$REGISTRY_PASS \ + --namespace managedsecret-operator-system +``` + +### Step 3: Install the Operator + +```bash +# Install with default configuration +helm install managedsecret-operator \ + oci://registry.c5ai.ch/charts/managedsecret-operator \ + --version 1.0.7 \ + --namespace managedsecret-operator-system \ + --set imagePullSecrets[0].name=registry-pull-secret + +# Or with custom values +cat > values.yaml <-previous with old values + 4. Updates K8s Secret with new values + 5. If Reloader is enabled: + - Reloader detects change → Restarts pods + 6. After previousVersionTTL: + - Operator deletes -previous secret +``` + +### When to Use `keepPreviousVersion` + +Use `keepPreviousVersion: true` when your service needs the **old password to authenticate** before changing to the new password: + +- ✅ PostgreSQL, MySQL, MariaDB (`ALTER USER` requires authentication) +- ✅ MinIO (`mc admin` needs old credentials) +- ✅ LDAP, Active Directory +- ❌ Container registries (htpasswd regenerated fresh) +- ❌ Redis (CONFIG SET doesn't need old password) +- ❌ Web services with startup scripts + +### Forcing Rotation + +```bash +# Trigger immediate rotation +kubectl annotate managedsecret -n \ + reconcile="$(date +%s)" --overwrite +``` + +--- + +## 🔍 Drift Detection + +The operator automatically detects and fixes drift every 60 seconds: + +**Scenario 1: Secret deleted in Kubernetes** +```bash +kubectl delete secret my-secret -n my-app +# Operator recreates it from Vault within 60 seconds +``` + +**Scenario 2: Secret modified in Vault** +```bash +# Update value in Vault +vault kv put secret/my-app/keys password=newvalue +# Operator syncs to K8s within 60 seconds +``` + +**Scenario 3: Secret manually edited in K8s** +```bash +kubectl edit secret my-secret -n my-app +# Changes are overwritten by Vault values within 60 seconds +``` + +--- + +## 🔧 Troubleshooting + +### Operator Not Starting + +```bash +# Check pod status +kubectl get pods -n managedsecret-operator-system + +# View logs +kubectl logs -n managedsecret-operator-system \ + -l control-plane=controller-manager --tail=100 + +# Common issues: +# - ImagePullBackOff: Check imagePullSecret is created correctly +# - CrashLoopBackOff: Check Vault connectivity +``` + +### Secret Not Created + +```bash +# Check ManagedSecret status +kubectl get managedsecret -n -o yaml + +# Look for conditions/events +kubectl describe managedsecret -n + +# Check operator logs +kubectl logs -n managedsecret-operator-system \ + -l control-plane=controller-manager | grep +``` + +### Vault Authentication Failing + +```bash +# Verify ServiceAccount exists +kubectl get sa controller-manager -n managedsecret-operator-system + +# Check Vault role configuration +vault read auth/kubernetes/role/managedsecret-operator + +# Test authentication manually +kubectl exec -it -n managedsecret-operator-system \ + deployment/managedsecret-operator-controller-manager -- sh +# Inside pod: Check /var/run/secrets/kubernetes.io/serviceaccount/token exists +``` + +### Rotation Not Working + +```bash +# Check ManagedSecret schedule +kubectl get managedsecret -n -o yaml | grep schedule + +# Force rotation to test +kubectl annotate managedsecret -n \ + reconcile="$(date +%s)" --overwrite + +# Check if Reloader is installed (if using rotation) +kubectl get pods -n reloader +``` + +### Reloader Not Restarting Pods + +```bash +# Verify Reloader is running +kubectl get pods -n reloader + +# Check pod has correct annotation +kubectl get deployment -n -o yaml | grep reloader + +# View Reloader logs +kubectl logs -n reloader -l app=reloader + +# Required annotation on pod template: +# annotations: +# reloader.stakater.com/auto: "true" +``` + +--- + +## 🎯 Best Practices + +### 1. Always Use Reloader for Rotating Secrets + +Without Reloader, pods won't pick up new credentials: +```yaml +template: + metadata: + annotations: + reloader.stakater.com/auto: "true" +``` + +### 2. Set Appropriate Rotation Schedules + +- **High Security** (passwords, admin credentials): 30-90 days +- **Medium Security** (application credentials): 90-180 days +- **Low Security** (read-only API keys): 180+ days or disabled + +### 3. Use `keepPreviousVersion` Correctly + +Only use it when the service needs the old password to authenticate: +```yaml +destination: + keepPreviousVersion: true # Only if old password is needed + previousVersionTTL: 1h # Adjust based on your workflow +``` + +### 4. Test Rotation Before Production + +```bash +# Create test ManagedSecret with short rotation +spec: + rotation: + enabled: true + schedule: 5m # Test rotation every 5 minutes + +# Watch the rotation +kubectl get secrets -n -w + +# Verify application handles rotation +kubectl logs -n +``` + +### 5. Monitor Rotation Jobs + +For services using `keepPreviousVersion`, monitor your CronJobs: +```bash +# Check job status +kubectl get jobs -n + +# View job logs +kubectl logs -n -l job-name= + +# Set up alerts for failed jobs +``` + +### 6. Backup Vault Regularly + +Vault is your source of truth: +```bash +# Example: Backup with Velero +velero backup create vault-backup \ + --include-namespaces openbao \ + --snapshot-volumes +``` + +### 7. Version Control Your ManagedSecrets + +Store ManagedSecret manifests in Git: +```yaml +# managedsecrets/ +# ├── production/ +# │ ├── postgres-credentials.yaml +# │ └── api-keys.yaml +# └── staging/ +# ├── postgres-credentials.yaml +# └── api-keys.yaml +``` + +### 8. Use GitOps for Deployment + +Deploy with ArgoCD or Flux: +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: managedsecrets +spec: + source: + path: managedsecrets/production + destination: + namespace: default +``` + +--- + +## 🔒 Security Considerations + +### Production Checklist + +- [ ] OpenBao/Vault is properly secured (TLS, audit logging, backups) +- [ ] RBAC configured with least-privilege +- [ ] Network policies in place +- [ ] Monitoring and alerting configured +- [ ] Disaster recovery plan documented +- [ ] Registry credentials stored securely (not in Git) + +### Credentials Management + +The operator needs: +1. Access to Vault (via Kubernetes ServiceAccount auth) +2. Access to pull its image (via imagePullSecret) + +Both use Kubernetes-native methods. **Never hardcode credentials in manifests!** + +--- + +## 📞 Support + +### Getting Help + +1. **Check documentation**: + - This README + - [examples/EXAMPLES-SUMMARY.md](./examples/EXAMPLES-SUMMARY.md) + - Individual example files + +2. **Check operator logs**: + ```bash + kubectl logs -n managedsecret-operator-system \ + -l control-plane=controller-manager --tail=100 + ``` + +3. **Contact your administrator** if: + - You need registry credentials + - Vault is not configured for your cluster + - Operator authentication issues + +### For Administrators + +#### Information to Provide Users + +**Registry Credentials:** +``` +Registry: registry.c5ai.ch +Username: +Password: +Chart: oci://registry.c5ai.ch/charts/managedsecret-operator +Version: 1.0.7 +``` + +**Vault Configuration:** +``` +Address: http://openbao.openbao.svc.cluster.local:8200 +Auth Method: kubernetes +Role: managedsecret-operator +KV Mount: secret +KV Version: v2 +``` + +#### Prerequisites for New Cluster + +```bash +# 1. Enable Kubernetes auth +bao auth enable kubernetes +bao write auth/kubernetes/config \ + kubernetes_host="https://kubernetes.default.svc:443" + +# 2. Create policy +bao policy write managedsecret-operator - <<'EOF' +path "secret/data/*" { + capabilities = ["create", "read", "update", "delete", "list"] +} +path "secret/metadata/*" { + capabilities = ["list", "read", "delete"] +} +EOF + +# 3. Create role +bao write auth/kubernetes/role/managedsecret-operator \ + bound_service_account_names=controller-manager \ + bound_service_account_namespaces=managedsecret-operator-system \ + policies=managedsecret-operator \ + ttl=1h +``` + +--- + +## 🔄 Upgrading + +### Upgrade Operator Version + +```bash +# Check current version +helm list -n managedsecret-operator-system + +# Upgrade to new version +helm upgrade managedsecret-operator \ + oci://registry.c5ai.ch/charts/managedsecret-operator \ + --version 1.0.8 \ + --namespace managedsecret-operator-system \ + --reuse-values +``` + +### Migration Notes + +When upgrading from earlier versions: +- CRD updates are handled automatically +- Existing ManagedSecrets continue to work +- No manual migration required +- Check changelog for breaking changes + +--- + +## 📝 Changelog + +### Version 1.0.7 +- ✨ Added `keepPreviousVersion` for zero-downtime rotation +- ✨ Added `previousVersionTTL` for automatic cleanup +- 📦 Helm chart deployment support +- 📚 Comprehensive examples and documentation +- 🐛 Bug fixes and improvements + +--- + +## License + +Proprietary Use License + +Permission is granted to use this software for any purpose, including commercial use, without charge. + +Modification, adaptation, or creation of derivative works is prohibited. +Redistribution of modified versions is prohibited. + +--- + +**Version:** 1.0.7 +**Registry:** registry.c5ai.ch/charts/managedsecret-operator +**Minimum Kubernetes:** 1.24+ **Compatible with:** OpenBao, HashiCorp Vault \ No newline at end of file