README
ΒΆ
KubeUser
Lightweight Kubernetes-native user management operator that simplifies user authentication and authorization through declarative custom resources.
Overview
KubeUser automates Kubernetes user management through declarative custom resources. It handles certificate generation, RBAC binding, and kubeconfig creation automatically.
Why KubeUser?
Kubernetes-native user management - no certificate handling , no Keycloak required.
Architecture Overview
KubeUser follows the standard Kubernetes operator pattern:
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β User CRD βββββΆβ User Controller βββββΆβ RBAC Resources β
β (Custom Res.) β β (Reconciler) β β (Roles/Bindings)β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β
βΌ
βββββββββββββββββββ
β Certificate & β
β Kubeconfig Gen β
βββββββββββββββββββ
Quick installation
# Install cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Wait for cert-manager to be ready
kubectl wait --for=condition=ready pod -l app=cert-manager -n cert-manager --timeout=60s
helm repo add kubeuser https://openkube-hub.github.io/KubeUser
export KUBERNETES_API_SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
# Install with automatic namespace creation (recommended)
helm install kubeuser kubeuser/kubeuser --create-namespace -n kubeuser \
--set env.KUBERNETES_API_SERVER="$KUBERNETES_API_SERVER"
# verify installation
kubectl get pods -n kubeuser
Important: The controller requires a namespace for storing user certificates. Use --create-namespace or install into an existing namespace. The controller will NOT automatically create namespaces for GitOps compatibility.
Security Considerations
Deleting a User does NOT invalidate issued ceriticates.
When deleting a User:
- RBAC bindings removed immediately (no permissions)
- secrets deleted
- Certificated remain valid until expiry (~1 year)
π§ implemented Features
- Declarative User CRD with status tracking and finalizers
- Automatic client certificate generation via Kubernetes CSR API
- Certificate rotation 30 days before expiry
- Kubeconfig generation stored as Kubernetes secrets
- Namespace-scoped Role bindings (Role + RoleBinding)
- Namespace-scoped ClusterRole bindings (ClusterRole + RoleBinding)
- Dynamic RBAC reconciliation with automatic cleanup
- Admission webhook validation with TLS/HTTPS
- Role/ClusterRole existence validation
- High availability with leader election
- Prometheus metrics endpoint (HTTPS :8443) with RBAC protection
- Health probes (liveness and readiness)
- Helm chart and Kustomize deployment options
π§ Planned Features
- User Groups (UserGroup CRD)
- User templates and bulk operations
- Predefined role templates library
- Certificate revocation mechanism
- OIDC, LDAP/AD, and SSO integration
- Enhanced metrics with Grafana dashboards and Prometheus alerts
- CLI tool and Web UI
π¦ Installation Instructions
Prerequisites
- Kubernetes cluster (v1.28+)
- kubectl configured to access your cluster with cluster-admin permissions
- cert-manager (required for webhook certificates)
- Docker (for building images locally)
- kind or minikube (for local testing)
Install cert-manager
KubeUser requires cert-manager for webhook certificate management:
# Install cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Wait for cert-manager to be ready
kubectl wait --for=condition=ready pod -l app=cert-manager -n cert-manager --timeout=60s
Deployment Options
Option 1: Using Helm (Recommended)
KubeUser publishes Helm charts via GitHub Pages. To install using Helm:
helm repo add kubeuser https://openkube-hub.github.io/KubeUser
helm repo update
```bash
# Install with automatic namespace creation (recommended)
helm upgrade --install kubeuser kubeuser/kubeuser \
--create-namespace \
--namespace kubeuser \
--version <version>
# Or install into existing namespace
helm upgrade --install kubeuser kubeuser/kubeuser \
--namespace existing-namespace \
--version <version>
# List available versions
helm search repo kubeuser --versions
# Upgrade to a new version later
# helm upgrade kubeuser kubeuser/kubeuser -n kubeuser --version <new-version>
# Uninstall
# helm uninstall kubeuser -n kubeuser
Notes:
- All resource names are prefixed by the Helm release name (e.g.,
kubeuser). - The chart defaults the image.tag to the chart version; override with
--set image.tag=<tag>if needed.
Option 2: Using Kustomize
# Clone the repository
git clone https://github.com/openkube-hub/KubeUser.git
cd KubeUser
# Create namespace first (required)
kubectl create namespace kubeuser
# Deploy using kustomize
kubectl apply -k config/default
# Wait for controller to be ready
kubectl wait --for=condition=ready pod -l control-plane=controller-manager -n kubeuser --timeout=120s
Option 3: Local Development with kind
For local testing and development:
# Build the Docker image
make docker-build
# Load image into kind cluster
kind load docker-image ghcr.io/openkube-hub/kubeuser-controller:latest --name <your-cluster-name>
# Deploy with local image
kubectl apply -k config/default
# Update deployment to use local image
kubectl patch deployment kubeuser-controller-manager -n kubeuser -p '{"spec":{"template":{"spec":{"containers":[{"name":"manager","imagePullPolicy":"Never"}]}}}}'
Verification
Verify the installation:
# Check controller status
kubectl get pods -n kubeuser
# Check webhook certificate
kubectl get certificates -n kubeuser
# Check CRDs
kubectl get crd users.auth.openkube.io
π Quick Start / Usage
Basic User Creation
Create a user with namespace-scoped access:
apiVersion: auth.openkube.io/v1alpha1
kind: User
metadata:
name: alice
spec:
roles:
- namespace: "development"
existingRole: "developer"
- namespace: "staging"
existingRole: "viewer"
User with Cluster-wide Access
apiVersion: auth.openkube.io/v1alpha1
kind: User
metadata:
name: bob-admin
spec:
clusterRoles:
- existingClusterRole: "cluster-admin"
Mixed Permissions Example
apiVersion: auth.openkube.io/v1alpha1
kind: User
metadata:
name: contractor-jane
spec:
roles:
- namespace: "project-x"
existingRole: "developer"
- namespace: "testing"
existingRole: "tester"
clusterRoles:
- existingClusterRole: "view" # Read-only cluster access
Field Reference
| Field | Type | Required | Description |
|---|---|---|---|
spec.roles |
[]RoleSpec |
No | List of namespace-scoped role bindings |
spec.roles[].namespace |
string |
Yes | Target namespace for the role binding |
spec.roles[].existingRole |
string |
Yes | Name of the existing Role in the namespace |
spec.clusterRoles |
[]ClusterRoleSpec |
No | List of cluster-wide role bindings |
spec.clusterRoles[].existingClusterRole |
string |
Yes | Name of the existing ClusterRole |
Managing Users
# Create sample namespace and role
kubectl create ns dev
kubectl create role developer --verb=get,list,watch --resource=pods -n dev
# Apply user configuration
kubectl apply -f test/test-user.yaml
# Check user status
kubectl get users
kubectl describe user jane
# Get the generated kubeconfig
kubectl get secret jane-kubeconfig -n kubeuser -o jsonpath='{.data.config}' | base64 -d > ~/tmp/kubeconfig
# Test user access
kubectl --kubeconfig ~/tmp/kubeconfig get pods -n dev
# Delete user (cleans up all associated resources)
kubectl delete user jane
Comprehensive Testing
For thorough testing of all features, use the provided test script:
# Run the comprehensive test suite
./test-kubeuser.sh
This script tests:
- Prerequisites validation
- Controller deployment health
- User creation and RBAC bindings
- Certificate generation and kubeconfig creation
- User access validation
- Certificate rotation
- Resource cleanup
Manual Testing Steps
-
Setup test environment:
kubectl apply -f test/test-setup.yaml -
Create a test user:
kubectl apply -f test/test-user-jane-1.yaml -
Verify user creation:
kubectl get users kubectl describe user jane -
Check generated resources:
# Check secrets kubectl get secrets -n kubeuser | grep jane # Check RBAC bindings kubectl get rolebindings -n dev | grep jane kubectl get clusterrolebindings | grep jane # Check CSR (if still present) kubectl get csr -l auth.openkube.io/user=jane -
Test user access:
# Extract kubeconfig kubectl get secret jane-kubeconfig -n kubeuser -o jsonpath='{.data.config}' | base64 -d > /tmp/jane.kubeconfig # Test authentication kubectl --kubeconfig /tmp/jane.kubeconfig auth can-i get pods -n dev # Test actual access kubectl --kubeconfig /tmp/jane.kubeconfig get pods -n dev
βοΈ Configuration
Breaking Change Notice
v0.3.0+: The controller no longer automatically creates namespaces. This change improves GitOps compatibility by ensuring all resources are explicitly declared.
Migration: If upgrading from an earlier version, ensure your target namespace exists before deployment:
- Helm: Use
--create-namespaceflag - Kustomize: Namespace is included in manifests
- Manual: Create namespace with
kubectl create namespace <name>
Environment Variables
The operator supports the following environment variables:
| Variable | Default | Description |
|---|---|---|
KUBERNETES_API_SERVER |
https://kubernetes.default.svc |
Kubernetes API server address |
π§ Troubleshooting
Common Issues
Controller Pod Not Starting
# Check pod status
kubectl get pods -n kubeuser
# Check pod logs
kubectl logs -n kubeuser deployment/kubeuser-controller-manager
# Check events
kubectl get events -n kubeuser --sort-by=.lastTimestamp
Common causes:
- Missing cert-manager installation
- Webhook certificate not ready
- Image pull issues (for local development)
Webhook Certificate Issues
# Check certificate status
kubectl get certificates -n kubeuser
kubectl describe certificate kubeuser-webhook-cert -n kubeuser
# Check cert-manager logs
kubectl logs -n cert-manager deployment/cert-manager
# Force certificate recreation
kubectl delete certificate kubeuser-webhook-cert -n kubeuser
kubectl apply -k config/default
User Creation Fails
# Check user status
kubectl describe user <username>
# Check controller logs
kubectl logs -n kubeuser deployment/kubeuser-controller-manager | grep -i error
# Check webhook validation
kubectl get validatingwebhookconfiguration kubeuser-validating-webhook-configuration -o yaml
Common causes:
- Referenced roles don't exist
- Target namespace doesn't exist (controller no longer auto-creates namespaces)
- RBAC permission issues
- Webhook validation failures
Namespace Issues: If you see errors about missing namespaces, ensure you:
- Used
--create-namespacewith Helm installation - Pre-created the namespace for Kustomize deployments
Certificate Generation Issues
# Check CSR status
kubectl get csr -l auth.openkube.io/user=<username>
# Check CSR details
kubectl describe csr <csr-name>
# Check controller RBAC permissions
kubectl auth can-i create certificatesigningrequests --as=system:serviceaccount:kubeuser:kubeuser-controller-manager
Getting Help
For additional support:
- Check the comprehensive documentation in
docs/ - Review logs for specific error messages
- Ensure all prerequisites are properly installed
- Verify RBAC permissions are correctly configured
π Documentation
- Certificate Management Guide - Comprehensive certificate management details
- Webhook Validation - Webhook validation and troubleshooting
- Test Script - Automated testing script
π Quick Reference
Essential Commands
# Deploy KubeUser
kubectl apply -k config/default
# Check deployment status
kubectl get pods -n kubeuser
kubectl get certificates -n kubeuser
# Create a user
kubectl apply -f test/test-user-jane-1.yaml
# Get user kubeconfig
kubectl get secret jane-kubeconfig -n kubeuser -o jsonpath='{.data.config}' | base64 -d > jane.kubeconfig
# Test user access
kubectl --kubeconfig jane.kubeconfig auth can-i get pods -n dev
# Clean up
kubectl delete user jane
kubectl delete -k config/default
Key Resources Created
- Namespace:
kubeuser - CRD:
users.auth.openkube.io - Controller:
kubeuser-controller-manager - Webhook:
kubeuser-validating-webhook-configuration - Certificates:
kubeuser-webhook-cert(managed by cert-manager)
User Resource Secrets
For each user, the controller creates:
<username>-key: Private key secret<username>-kubeconfig: Complete kubeconfig file- CSR:
<username>-csr(temporary, cleaned up after use)
π» Development Guide
Prerequisites
- Go: Version 1.24+ (as specified in go.mod)
- Docker: For building container images
- kubectl: Kubernetes command-line tool
- Kind: For local testing (optional but recommended)
- Kustomize: For manifest management
- Kubebuilder: v3.0+ (for code generation)
Local Development Setup
- Clone the repository:
git clone https://github.com/openkube-hub/KubeUser.git
cd KubeUser
- Install dependencies:
go mod tidy
- Generate code and manifests:
make generate
make manifests
- Run tests:
make test
Building and Running Locally
# Build the manager binary
make build
# Run against a Kubernetes cluster (requires kubeconfig)
make run
# Build and load Docker image (requires Docker)
make docker-build
Testing
Unit Tests
# Run all unit tests
make test
# Run tests with coverage
go test ./... -coverprofile=coverage.out
go tool cover -html=coverage.out
End-to-End Tests
# Run e2e tests (creates Kind cluster)
make test-e2e
# Manual e2e testing
make setup-test-e2e # Creates Kind cluster
# ... run manual tests ...
make cleanup-test-e2e # Cleanup
Linting and Code Quality
# Run linter
make lint
# Fix linting issues automatically
make lint-fix
# Verify linting configuration
make lint-config
# Format code
make fmt
# Vet code
make vet
Development Workflow
- Make changes to the code
- Generate code:
make generate manifests - Run tests:
make test - Test locally:
make run - Build image:
make docker-build - Run e2e tests:
make test-e2e
π€ Contributing
We welcome contributions to KubeUser! Please follow these guidelines:
Submitting Pull Requests
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Follow the development setup above
- Make your changes with tests
- Ensure all tests pass:
make test lint - Commit with conventional commit format:
feat: add user group management - Implement UserGroup CRD - Add controller logic for group management - Include comprehensive tests Fixes #123 - Push to your fork:
git push origin feature/amazing-feature - Create a Pull Request
Code Style
- Follow standard Go conventions
- Use
gofmtfor formatting - Pass
golangci-lintchecks - Write comprehensive tests for new features
- Update documentation for user-facing changes
Commit Message Format
We use Conventional Commits:
feat:New featuresfix:Bug fixesdocs:Documentation changestest:Test-related changesrefactor:Code refactoringci:CI/CD changeschore:Maintenance tasks
If you find KubeUser useful, please consider giving it a β on GitHub!