Recent development · Practical technical guide · 23 October 2026
HashiCorp Vault 2.2.0, released 15 October 2026, fixes a family of authorization bugs where case-variant names and a trailing slash could evade deny rules. This reads the changelog, explains why a deny on super-admin did not stop Super-Admin, and lists what to audit after upgrading.
A family of bypasses with one shape
HashiCorp Vault 2.2.0 was released on 15 October 2026; I verified the published binaries for 2.1.2 and 2.2.0 against their SHA256SUMS before reading their versions (2.1.2 built 6 October, 2.2.0 built 14 October). Its changelog lists an unusually coherent group of authorization fixes, and they share a shape: an access-control decision compared a name as a string without normalising it first, so a differently-cased or differently-terminated version of the same name was treated as a different name and slipped past a deny. These are the kind of bugs that pass every functional test, because the policy does exactly what it says for the exact string it was written with, and fails only for a variant an attacker supplies.
Why a deny on super-admin did not stop Super-Admin
The clearest example in the changelog is a privilege-escalation fix: a denied_parameters constraint on the policies request field could be bypassed by submitting a mixed-case policy name, such as Super-Admin instead of super-admin. The deny rule matched the lowercase string; the request carried a different-case string that named the same policy; Vault resolved the policy case-insensitively but had compared the deny constraint case-sensitively, so the constraint did not fire. 2.2.0 normalises the policies parameter before the check. The changelog lists sibling fixes in the same release.
| Fix (from the 2.2.0 changelog) | The bypass | What now happens |
|---|---|---|
| denied_parameters on policies | Mixed-case policy name evades the deny | Parameter is normalised before the ACL check |
| Exact-deny with case-variant role or user names | Case-variant AppRole, AWS, Azure, GCP, K8s, cert or userpass names evade a deny | Case variants no longer evade an exact-deny policy |
| LIST ACL with a trailing slash | A trailing-slash request skips a more-specific deny | Trailing-slash LIST no longer bypasses the deny |
| Wildcards in rendered identity templates | A template renders a wildcard into a path | Wildcards in rendered templates are rejected |
| Path-navigation segments in legacy policy names | Names containing . or .. are resolved | Traversal-style names are ignored at request-time ACL construction |
The trailing-slash LIST bypass
A second instance is worth calling out because it is so easy to miss in a policy review. Vault paths distinguish a key from a prefix by a trailing slash, and LIST operates on prefixes. The changelog records a fix for a LIST ACL bypass where a trailing-slash request could skip a more-specific deny rule. If a policy denied listing a specific path but the request added or omitted the trailing slash in a way the matcher treated as a different path, the deny did not apply. The lesson for policy authors is that path matching, case folding and separators are all part of the authorization surface, and a deny is only as strong as the normalisation that happens before it.
Illustrative hcl, checked for syntax; adapt names and storage to your system.
# A policy that denies a sensitive list. Before 2.2.0 a trailing-slash
# variant of the request path could skip a more-specific deny like this one.
path "secret/metadata/super-admin" {
capabilities = ["deny"]
}
# After 2.2.0, the LIST matching no longer lets a trailing-slash request
# evade the more-specific deny, and a mixed-case policy name no longer
# evades a denied_parameters constraint on the policies field.What this means for an upgrade
These are server-side fixes, so upgrading the Vault binaries is what closes them; no policy rewrite is required to get the corrected behaviour. But the fixes also tell you where to look in your own policies, because they reveal assumptions that may be load-bearing elsewhere. Note that the same release carries operational breaking changes unrelated to these ACL fixes: the container-image change around cap_ipc_lock is listed both ways in the 2.2.0 changelog (one entry removes the capability at build time so Vault runs in common runtimes, another sets it so runtimes must add IPC_LOCK), and the net effect for you is the same action: Vault in a container that cannot mlock() needs either disable_mlock = true in its config or the IPC_LOCK capability granted by the runtime, so confirm which your image ships. ACME finalization with the default sign-verbatim policy now also rejects CSRs that carry URI, email or Other SANs. Read the breaking-changes section before upgrading a production cluster.
A worked audit after upgrading
- Find every deny rule that names a policy, role, user or group, and confirm none of your own tooling relies on case to distinguish two of them; the server now folds case, and a name you treated as distinct by case may now collide.
- Review LIST denies for path separators: make sure a deny on a prefix is written so the corrected matcher covers the variants you intend, and test both the slash and no-slash forms.
- Search identity templates for anything that could render a wildcard, which 2.2.0 now rejects; a template that silently produced a broad path before will now fail, which is the safe outcome but may surprise a caller.
- If you run Vault in containers, set disable_mlock = true or add the IPC_LOCK capability, because the image no longer carries it.
- If you use ACME with sign-verbatim, remove URI, email and Other SANs from CSRs, which were never validated and are now rejected.
When this is low urgency
If every identity in your Vault is lowercase and you never rely on case or trailing slashes to distinguish names, these specific bypasses may not have been reachable in your deployment, and the upgrade is ordinary hygiene. The urgency rises with the number of distinct principals, the use of exact-deny rules as a security boundary, and any policy authored by generated or user-supplied names where case and separators are not under your control. Upgrade to the patched release as the recommended remediation. Restricting affected functionality or exposure may reduce interim risk but is not evidence that every authorization bypass has been removed.
Failure modes
- Assuming a lowercase deny also blocked the mixed-case variant before 2.2.0; it did not, which is the whole point of the fix.
- Upgrading the binary but leaving container mlock unaddressed, so Vault fails to start without disable_mlock or the IPC_LOCK capability.
- Relying on a LIST deny whose path separators do not cover the request variants, and not testing both slash forms after upgrading.
- Treating these as a configuration problem and rewriting policies instead of upgrading, which cannot close a server-side ACL bypass.
- Missing the ACME sign-verbatim change and having certificate issuance start to fail for CSRs that carry now-rejected SAN types.
Verification
After upgrading, verify the version from the running binary rather than the package name, and check the changelog entries against your own policy set. For the case-variant fix, confirm in a staging Vault that a deny written in lowercase now also blocks the mixed-case form of the same name, and that it did not on the prior version. For the LIST fix, test a denied prefix with and without a trailing slash and confirm both are denied. Confirm Vault starts in your container runtime with the mlock setting you chose, and that your ACME issuance still succeeds with SANs limited to DNS names and IP addresses. Keep the Vault version and the upgrade date in your change log so the fix is auditable later.
Sources and scope
Checked against these sources on 23 October 2026. Event: HashiCorp Vault 2.2.0 changelog, 15 October 2026; recheck it before acting. Examples and figures are illustrative, not measurements.
Upgrade the binaries because these are server-side ACL fixes, then audit deny rules that rely on case or trailing slashes, reject wildcard-rendering identity templates, set disable_mlock or add IPC_LOCK for containers, and drop URI, email and Other SANs from ACME sign-verbatim CSRs.