Introduction I recently set up a three-node Vault Enterprise HA cluster on OpenShift, using HCP Vault as the auto-unseal provider via the transit secrets engine.
On paper this is a straightforward combination of well-documented features.
In practice, it was a series of traps — some subtle, some spectacular — that took multiple sessions to fully work through.
This post covers the four main challenge areas I hit: getting right on OpenShift, wiring up the auto-unseal token flow securely, managing Raft quorum safely during rolling updates, and working around a reconciliation bug in Vault Secrets Operator.
I'll focus on what caught me off guard and what the correct solution looks like.
The deployment is GitOps-managed via ArgoCD using a three-source Helm pattern: the upstream Vault chart, a values file from the repo, and raw manifests for cluster-level resources (SCCs, Routes, ConfigMaps) that Helm can't cleanly own.
Challenge 1: IPC_LOCK on OpenShift The Problem Vault requires the Linux capability so it can call to prevent secrets from being swapped to disk.
This is non-negotiable — if the capability is missing, Vault exits at startup.
On OpenShift this runs into the default Security Context Constraint (SCC), which doesn't include in its allowed capabilities.
I discovered this the hard way when all three pods went into immediately after deploying.
What made it more confusing was that the error message differed depending on the image: Upstream image (): Vault starts, calls , gets , and exits with: Red Hat partner image (): The binary ships with set via .
When the kernel drops that from the bounding set at exec time (because the SCC doesn't allow it), the itself fails before Vault even starts: Both root causes are the same — no in the SCC — but the symptoms look completely different, which costs time when debugging.
The Solution: Custom SCC The fix is a custom SCC that adds as both an allowed and default capability: Custom SCCs don't automatically get a the way built-in ones do, so you also need to create one manually and bind it to the Vault service account: The SCC Priority Gotcha Here's the non-obvious part.
When multiple SCCs have the same priority, OpenShift's SCC resolver picks one based on a deterministic but non-obvious ordering algorithm.
In my cluster, a pre-existing had the same default priority of
10.
Without an explicit hint in the pod spec, the init container landed on and failed — despite the service account being bound to my new SCC.
The fix is to explicitly declare in the container's : This hint steers the SCC resolver to select over any same-priority SCC that doesn't advertise support.
The hint is required even when is set — without it, the resolver may never reach your SCC.
Image Choice I also switched from the Red Hat partner image to the upstream .
Without the prefix, RHCOS short-name rewriting rewrites unqualified image tags to at pull time.
That's fine in theory, but in practice the partner mirror had divergent cached bytes across nodes (different digests for the same tag) and was using a floating tag rather than a pinned version.
Once the SCC was in place, the upstream image with an explicit registry and pinned tag worked cleanly.
Challenge 2: Auto-Unseal Token Flow Why HCP Vault Dedicated?
Before getting into the mechanics, it's worth explaining the choice of HCP Vault as the transit unseal provider rather than a self-hosted instance.
The transit auto-unseal mechanism doesn't require HCP Vault — any Vault cluster (including Community Edition) can host a transit secrets engine and serve as the unseal provider.
The problem is the bootstrap paradox: if your transit unseal cluster is also self-hosted, you need a way to unseal it before it can unseal anything else.
You've just moved the problem one level up.
HCP Vault Dedicated sidesteps this entirely.
HashiCorp operates the cluster, handles HA failover, applies upgrades, and manages the underlying infrastructure.
Critically, it uses cloud KMS for its own unseali