User Management Guide
Comprehensive guide for managing Kubernetes users and RBAC permissions in the Open Service Portal.
Overview
This directory contains scripts and documentation for managing users and permissions in Kubernetes clusters. All scripts are located in scripts/users/.
Quick Start
# Grant cluster admin access
./scripts/users/create-user-with-cert.sh alice admin
# Create user with namespace access
./scripts/users/create-user-with-group.sh bob my-namespace
# List all custom RBAC resources
./scripts/users/rbac-list-custom.sh
# List all groups referenced in RoleBindings
./scripts/users/list-groups.sh
Understanding Kubernetes Users and Groups
Important: Kubernetes does NOT store users or groups as cluster resources.
Users
- No User resource exists in Kubernetes
- Users are authenticated via:
- Client certificates (X.509)
- OIDC tokens (Auth0, Keycloak, Google Workspace, etc.)
- Service Account tokens (for pods)
Groups
- No Group resource exists in Kubernetes
- Groups are virtual identities embedded in authentication:
- OIDC: Groups come from identity provider claims
- Certificates:
O=field in subject (Organization) - System groups:
system:authenticated,system:masters, etc.
- Groups only exist as references in RoleBindings/ClusterRoleBindings
Script Reference
User Creation Scripts
create-user-with-cert.sh
Creates a Kubernetes user with client certificate authentication.
./scripts/users/create-user-with-cert.sh <username> [role]
Arguments:
username: Username for the new userrole: Kubernetes role (default:admin)cluster-admin: Full cluster accessadmin: Full access within namespaceedit: Read/write accessview: Read-only access
What it does:
- Generates a private key and CSR (Certificate Signing Request)
- Creates CertificateSigningRequest resource in cluster
- Approves and retrieves the certificate
- Creates kubeconfig file for the user
- Creates RoleBinding for namespace access
Output:
- Kubeconfig file:
~/.kube/config-<username> - Certificate and key stored in cluster
Example:
# Create admin user with full cluster access
./scripts/users/create-user-with-cert.sh alice cluster-admin
# Create developer with namespace access
./scripts/users/create-user-with-cert.sh bob edit
create-user-with-group.sh
Creates a user with certificate-based group membership.
./scripts/users/create-user-with-group.sh <username> <namespace> [group-role]
Arguments:
username: Username for the new usernamespace: Target namespace for accessgroup-role: Role for the group (default:edit)
What it does:
- Creates a group based on namespace:
<namespace>-users - Generates certificate with group in O= field
- Creates RoleBinding that grants access to the group
- Generates kubeconfig for the user
Key Feature: Users belong to groups, and permissions are granted to groups (not individual users).
Example:
# Create user bob in dev namespace with edit access
./scripts/users/create-user-with-group.sh bob dev edit
# Create user alice in prod namespace with admin access
./scripts/users/create-user-with-group.sh alice prod admin
Group Management Scripts
rbac-create-group.sh
Creates a virtual group by creating RoleBindings that reference the group.
./scripts/users/rbac-create-group.sh <group-name> <namespace> [role]
Important: This doesn't create a Group resource (none exists in K8s). It creates the RBAC structure that references a group.
What it does:
- Creates namespace if it doesn't exist
- Creates RoleBinding with group as subject
- Adds labels and annotations for tracking
Example:
# Create developers group with edit access in dev namespace
./scripts/users/rbac-create-group.sh developers dev edit
# Create admins group with admin access in prod namespace
./scripts/users/rbac-create-group.sh admins prod admin
rbac-add-user-to-group.sh
Adds a user to an existing group by creating a certificate with the group in O= field.
./scripts/users/rbac-add-user-to-group.sh <username> <group-name>
What it does:
- Generates certificate with group in Organization field
- Creates kubeconfig for the user
- User inherits all permissions of the group
Example:
# Add alice to developers group
./scripts/users/rbac-add-user-to-group.sh alice developers
# Add bob to admins group
./scripts/users/rbac-add-user-to-group.sh bob admins
Listing and Discovery Scripts
list-groups.sh
Lists all groups referenced in RoleBindings and ClusterRoleBindings across the cluster.
./scripts/users/list-groups.sh
Output:
- All unique group names
- Namespaces where each group is referenced
- Count of bindings per group
Example output:
Group: developers
Namespace: dev (2 bindings)
Namespace: staging (1 binding)
Group: admins
Cluster-wide (1 ClusterRoleBinding)
Namespace: prod (1 binding)
rbac-list-custom.sh
Lists all custom RBAC resources created by our scripts (filtered by labels/annotations).
./scripts/users/rbac-list-custom.sh
Shows:
- RoleBindings with
rbac.openportal.dev/managed-byannotation - ClusterRoleBindings with OpenPortal labels
- Grouping by namespace and type
Useful for:
- Auditing permissions
- Finding resources to clean up
- Understanding current access setup
RBAC Templates
Located in scripts/users/, these templates are used by the scripts to create RBAC resources:
rbac-group.template.yaml- ClusterRoleBinding template for group accessrbac-group-namespace.template.yaml- RoleBinding template for namespace-scoped group access
Authentication Methods Comparison
| Method | Pros | Cons | Use Case |
|---|---|---|---|
| Client Certificates | Simple, no external deps | Manual rotation, no groups | Development, testing |
| OIDC | Centralized, automatic expiry, groups | Requires identity provider | Production, teams |
| Service Accounts | Built-in, namespace-scoped | Limited to pods | Application workloads |
Common Workflows
Onboarding a New Developer
# Option 1: Direct namespace access
./scripts/users/create-user-with-cert.sh alice edit
# Option 2: Group-based access (recommended)
./scripts/users/rbac-create-group.sh developers dev edit
./scripts/users/rbac-add-user-to-group.sh alice developers
Creating a Team with Shared Access
# 1. Create the group and bind permissions
./scripts/users/rbac-create-group.sh frontend-team frontend-ns admin
# 2. Add team members
./scripts/users/rbac-add-user-to-group.sh alice frontend-team
./scripts/users/rbac-add-user-to-group.sh bob frontend-team
./scripts/users/rbac-add-user-to-group.sh charlie frontend-team
Auditing Current Access
# See all groups
./scripts/users/list-groups.sh
# See all custom RBAC resources
./scripts/users/rbac-list-custom.sh
# Check specific user's access
kubectl auth can-i --list --as=alice
Removing Access
# Find the RoleBinding
kubectl get rolebinding -A | grep alice
# Delete the RoleBinding
kubectl delete rolebinding alice-binding -n dev
# Revoke certificate (prevents kubectl access)
kubectl delete certificatesigningrequest alice
Best Practices
1. Use Groups, Not Individual Users
- Create groups for teams/roles
- Add users to groups
- Easier to manage permissions at scale
2. Principle of Least Privilege
- Start with minimal permissions (
view) - Grant additional access as needed
- Avoid
cluster-adminexcept for platform admins
3. Namespace Isolation
- Use namespace-scoped RoleBindings when possible
- Only use ClusterRoleBindings for platform-wide access
- Create namespaces per team/project
4. Label and Annotate
- All scripts add
rbac.openportal.dev/managed-byannotations - Use labels for filtering:
rbac.openportal.dev/type=explicit-admin - Makes auditing and cleanup easier
5. Documentation
- Document why permissions were granted
- Use descriptive group names
- Keep track of who has cluster-admin
Troubleshooting
User Can't Access Cluster
# Check if certificate exists
kubectl get csr | grep username
# Check if RoleBinding exists
kubectl get rolebinding -A | grep username
# Test user's permissions
kubectl auth can-i --list --as=username
Group Not Working
# Verify group exists in RoleBindings
./scripts/users/list-groups.sh | grep group-name
# Check certificate has correct group
openssl x509 -in cert.pem -noout -subject
# Verify group in kubeconfig
kubectl config view --minify
Permission Denied Errors
# Check what user CAN do
kubectl auth can-i --list --as=username --namespace=dev
# Check specific permission
kubectl auth can-i get pods --as=username --namespace=dev
# View RoleBinding details
kubectl describe rolebinding binding-name -n namespace
Migration to OIDC
For production environments, consider migrating from client certificates to OIDC:
- Set up OIDC provider (Auth0, Keycloak, Google Workspace)
- Configure kubectl for OIDC authentication
- Create RoleBindings using OIDC user emails and groups
- Phase out client certificates
See the OIDC Authentication Guide for details.
Related Documentation
- OIDC Authentication Concept - Understanding OIDC auth
- RBAC Scripts Overview - Technical script details
Script Annotations and Labels
All scripts use consistent annotations and labels for tracking:
Annotations:
rbac.openportal.dev/managed-by- Which script created the resourcerbac.openportal.dev/created-at- Timestamprbac.openportal.dev/namespace- Target namespace (if applicable)
Labels:
rbac.openportal.dev/type- Type of access (e.g.,explicit-admin,namespace-scoped)rbac.openportal.dev/group- Group name (if group-based)
These make it easy to query and manage resources:
# Find all resources created by our scripts
kubectl get rolebindings -A -l rbac.openportal.dev/type
# Find resources created by specific script
kubectl get clusterrolebindings -o yaml | grep "managed-by: rbac-add-admin"
Manifest Templates
All RBAC templates used by the user management scripts are located in scripts/manifests/users/:
rbac-admin.template.yaml- ClusterRoleBinding for cluster-admin accessrbac-namespace-access.template.yaml- RoleBinding for namespace-scoped accessrbac-group.template.yaml- ClusterRoleBinding for group-based accessrbac-group-namespace.template.yaml- RoleBinding for group-based namespace access
These templates use environment variable substitution (envsubst) and are processed by the scripts before applying to the cluster.
Technical Reference
RBAC Scripts Overview
For detailed technical documentation of all RBAC scripts, see RBAC Scripts Overview.
This technical reference includes:
- Script architecture and design
- Template structure and usage
- Environment variable requirements
- Error handling and validation
- Integration with Kubernetes API