This guide will walk you through quickly deploying Kubermatic SecureGuard in a local or development environment. This deployment bundles OpenBao (in dev mode), the Dex OIDC provider, External Secrets Operator (ESO), and the SecureGuard dashboard UI.
This guide is intended for development and local testing. Do not use dev mode secrets for production workloads. For production deployments, refer to the Installation guide.
A local SecureGuard you can log into, showing how a secret flows from the vault to your apps:
OpenBao (vault) ──ESO syncs──▶ Kubernetes Secret ──▶ your app
▲ │
└──── you watch it all from the SecureGuard dashboard ────┘
If any of the terms below (ESO, OpenBao, SecretStore, OIDC, Dex) are new, keep the Glossary handy — each is defined in one line.
Before you begin, ensure you have the following installed:
Install the Helm Chart
Deploy the chart directly from the Kubermatic Quay.io registry into your cluster under the secureguard release name. The chart will automatically install all required Custom Resource Definitions (CRDs) for the External Secrets Operator.
helm install secureguard oci://quay.io/kubermatic/helm-charts/secureguard \
--namespace secureguard-system \
--create-namespace \
--set openbao.server.dev.enabled=true \
--version 0.2.0 # replace with latest from the releases page
Verify the Deployment
Ensure all pods have started and are reporting Running status:
kubectl get pods -n secureguard-system
You should see pods for the backend proxy, the UI, OpenBao, Dex, and the ESO controllers.
Once the deployment is up, you need to access the SecureGuard dashboard.
Port-Forward the Dashboard Service Note: In production, you would configure an Ingress. For local testing, port-forwarding is sufficient.
kubectl port-forward svc/secureguard-ui 8080:80 -n secureguard-system
Access the UI
Open your browser and navigate to http://localhost:8080.
Logging In via Dex
Authentication is mandatory, so you are redirected to the Dex OIDC login page. The local dev deployment provisions a static admin user — email admin@secureguard.local, password admin — bound to cluster-admin. Change these immediately for any non-local deployment.
Access is enforced per user: the proxy impersonates the logged-in user on every Kubernetes API request, so what you can see and do is governed by the RBAC bound to your user/groups. A user with no bindings can log in but sees 403 errors until granted access — see User Authorization.
As you explore the dashboard, keep the following security principles in mind:
ExternalSecret, the actual secret values retrieved from OpenBao are masked (••••••••). The proxy redacts all secret values before they reach the browser — there is no mechanism to reveal them in the UI.Let’s watch a secret flow end-to-end. To keep this beginner-friendly we’ll use
ESO’s built-in fake provider, which returns values baked into the manifest
— so you don’t need OpenBao auth, a cloud account, or any credentials to see
syncing work. (In real life the provider would be OpenBao or a cloud vault.)
Remember: the dashboard is read-mostly, so we create the resources with
kubectl and then watch them in the UI — exactly how you’d work day-to-day.
Save this manifest as first-secret.yaml:
# A self-contained demo: a fake "vault" plus an ExternalSecret that reads it.
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: demo-fake-store # the "how to connect" config (here: fake data)
spec:
provider:
fake:
data:
- key: /demo/db
value: "hunter2" # the pretend secret value
version: v1
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: demo-db-credentials
namespace: default
spec:
refreshInterval: 1h
secretStoreRef:
name: demo-fake-store
kind: ClusterSecretStore
target:
name: demo-db-credentials # the Kubernetes Secret ESO will create
data:
- secretKey: password # key inside the created Secret
remoteRef:
key: /demo/db # which entry to read from the store
version: v1
Apply it:
kubectl apply -f first-secret.yaml
Watch it in the dashboard:
demo-db-credentials appears and turns
Synced (green) within a few seconds.demo-db-credentials, tagged as ESO-managed. Its password key is shown
as •••••••• — the value never reaches your browser, even in this demo.Clean up when you’re done:
kubectl delete -f first-secret.yaml
What just happened? You defined where to read from (the ClusterSecretStore) and what to fetch (the ExternalSecret). ESO did the rest: it created and now keeps a normal Kubernetes Secret in sync. Swap the fake provider for an OpenBao SecretStore and the exact same flow works with real, encrypted secrets — see ESO Basics.
Now that you have a local instance running: