Change history — barbican — branch stable/2026.2
Branch
stable/2026.2@de32745a7a4f— repository https://opendev.org/openstack/barbican — analysed on 2026-10-29
- Range:
22.0.0..stable/2026.2(f8a331a40eb2..de32745a7a4f), i.e. the whole 2026.2 (Hibiscus) development cycle since the 2026.1 release, 47 non-merge commits. The automatic range (since the branch leftmaster,1efe16cd73b6..de32745a7a4f) holds only the two release-bot commits (.gitreview,tox.ini); there are no backports on the branch yet. - Target: none given, so presence in a target is not computed. The carry-over plan below orders the commits for a fork of 2026.1 (
stable/2026.1); for OpenKeel the column "Impact on the Go rewrite" is the useful one. - Raw facts:
_inventory/history_stable-2026.2.md/.json(trailers, files, release notes, earlier commits on the same files). - Categories (heuristic, corrected after reading the diffs): security 1, upgrade 4, feature 3, fix 10, deprecation 1, dependencies/packaging 4, refactor 4, maintenance 20.
Summary
| # | Commit | Date | Category | Change | Bug | Impact | Impact on the Go rewrite |
|---|---|---|---|---|---|---|---|
| 42 | be7d8103db9f | 2026-04-13 | security / upgrade | Secure RBAC enforced by default (enforce_scope, enforce_new_defaults no longer forced to False) | — | all policies; 07 § 6 | implement new defaults as the default; legacy rules only behind the flag |
| 19 | 9f28ddb9248c | 2025-09-18 | feature (API) | microversion 1.2: refuse to delete a secret with consumers unless force | — | DELETE /v1/secrets/{id}, versions | required (barbicanclient and castellan use it) |
| 30 | c370f7991a35 | 2026-05-11 | fix (policy) | ACL endpoints now pass read_project_access and ACL flags to the policy | 2069378 | …/acl operations | build the full target for ACL endpoints |
| 34 | 70b20d3f9616 | 2026-03-01 | upgrade | [DEFAULT] host_href defaults to unset: references derived from the request | — | every *_ref, container validation | derive base URL from request by default |
| 2 | efe7040bca08 | 2025-04-12 | fix (API) | secret list next/previous links keep the query filters | 2064583 | GET /v1/secrets | keep filters in links |
| 5 | aeec1611f602 | 2025-06-08 | fix | binary payloads that are not base64 (Vault/castellan) returned as-is instead of 500 | 2113749 | GET …/payload | same fallback when reading external stores |
| 38 | 65a1dc983400 | 2026-04-03 | fix (validation) | EC orders accept bit_length 256/384/521 | 2147221 | POST /v1/orders | same validation |
| 9 | de534b60d7f9 | 2025-01-03 | fix (KMIP) | KMIP objects registered with a UUID Name attribute | 2084691 | KMIP store | only if KMIP is supported |
| 24–26 | 7eeb9a0f3560, 7371127192e5, f846df774d1b | 2026-01-29 | feature / deprecation | Vault: new kv_path, kv_version; vault_url validated as http(s) URI; use_ssl deprecated | — | [vault_plugin] | config surface of the Vault store |
| 37 | a28ddb94c353 | 2026-06-03 | fix (ops) | db clean deletes in committed batches of 10,000 | 2155108 | barbican-manage db clean, barbican-db-manage clean --batch-size | batch purges |
| 4, 22 | fa35b14f9931, a9f7478e3629 | 2025-08-05, 2026-04-03 | fix | missing [simple_crypto_plugin] kek gives a clear ValueError instead of TypeError | 2119531, 2147167 | start-up | fail clearly without a master KEK |
| 20 | 96b3e462f7c1 | 2026-04-03 | fix (CLI) | pkcs11_migrate_kek_signatures import fixed | 2143752 | HSM tooling | none |
| 36 | 27e3961bf1fa | 2026-05-26 | fix (runtime) | threading backend selected before any oslo.service import | 2152897 | worker, listener | none (Go) |
| 6 | b8743d37f695 | 2024-10-12 | feature (ops) | Guru Meditation Reports in worker, retry, listener | — | daemons | optional (Go has its own diagnostics) |
| 28, 29, 27, 12 | 69614993e78b, 160f0dd26e58, 7680e9b37139, 27daa9183279 | 2026 | upgrade / packaging | Python ≥ 3.11; barbican-wsgi-api script removed (use barbican.wsgi.api); pyproject.toml | — | packaging | none |
Change specifications
42. Enforce Secure RBAC by default — security, upgrade
- Before:
barbican/common/policy.pyforced[oslo_policy] enforce_scope = Falseandenforce_new_defaults = False, so only the legacy roles (admin,creator,observer,audit,key-manager:service-admin) mattered. After: the override is removed (barbican/common/policy.py:25is now the first function), oslo.policy's defaults apply: project-scoped tokens withreader/member/admin; system- and domain-scoped tokens are refused. The new rules are guarded byTrue:%(enforce_new_defaults)s(barbican/common/policies/secrets.py:66), the flag being injected in the policy target (barbican/api/controllers/__init__.py:61). - Why: the community "consistent and secure RBAC" goal; oslo.policy is removing
enforce_scope. - Impact on the spec: 07 § 6. The functional suite of the repository still uses legacy roles; this reverse-spec ran it with
enforce_new_defaults = False(07 § 8.1). - Upgrade: operators who relied on
creator/observer/auditmust grantmember/readeror set both options toFalse(release notereleasenotes/notes/enable-srbac-new-defaults-e22cd5c5f1b3a29c.yaml). This is the biggest behaviour change of the release: users with onlycreatorget403after the upgrade. - Carrying it over: one-file change plus test updates; depends on #30 (ACL target) to avoid spurious 403s for non-owner members. Easy.
19. Microversion 1.2: no deletion of a secret that has consumers — feature
- Before:
DELETE /v1/secrets/{id}always deleted the secret and silently removed its consumers. After (microversion ≥ 1.2):400 Secret cannot be deleted as it has consumers.unlessforceis a true boolean string (barbican/api/controllers/secrets.py:264); invalidforce→400 URI provided invalid query string parameters.._MAX_MICROVERSIONgoes from 1 to 2 and_LAST_UPDATEDto2025-09-18T00:00:00Z(barbican/api/controllers/versions.py:30); new exceptionSecretHasConsumers(barbican/common/exception.py:171). - Why: users deleting keys that Nova/Cinder volumes depend on; the safety net belongs in the API, not in each client.
- Impact on the spec: 01 (DELETE secret, microversions), 02, 04 § 3. Clients: python-barbicanclient sends
force=1only at ≥ 1.2 (python-barbicanclient:barbicanclient/v1/secrets.py:600); castellan exposesdelete(force). - Upgrade: none for 1.0/1.1 clients (behaviour unchanged); clients negotiating 1.2 must handle the new
400. - Carrying it over: self-contained; tests in
barbican/tests/api/controllers/test_secrets.py. Easy.
30. ACL endpoints build the full policy target — fix
- Before:
SecretACLsControllerandContainerACLsControlleroverrodeget_acl_tuplewith onlyproject_idandcreator_id, sosecret_is_not_private(True:%(target.secret.read_project_access)s) was always false on…/aclcalls: with the new defaults, a project member who was not the owner got403onGET /v1/secrets/{id}/acl. After: the overrides are removed; the inheritedACLMixin.get_acl_tupleadds the user's ACL operations andread_project_access(barbican/api/controllers/__init__.py:185). - Impact: 01 § ACLs, 07 § 6 (policy target). Carrying it over: deletion of 10 lines; must come with or before #42.
34. host_href unset by default — upgrade
- Before:
host_hrefdefaulted tohttp://localhost:9311, so every reference returned by a deployment that did not set it pointed to localhost. After: the option has no default; when unset, the base URL is derived from the request (Host,X-Forwarded-Proto, path prefix) (barbican/common/config.py:72,barbican/common/utils.py:79); an empty string is still accepted but deprecated (barbican/common/config.py:61); outside a request context and without the option,ValueError('host_href cannot be determined'). - Impact: all
*_refvalues andLocationheaders; container creation, whosesecret_refsmust start with that base URL (barbican/common/validators.py:713). Behind a TLS proxy,[oslo_middleware] enable_proxy_headers_parsingbecomes necessary (devstack sets it). - Upgrade: deployments that relied on the default keep working only if clients reach Barbican with the same host they want in references; set
host_hrefexplicitly otherwise (releasenotes/notes/update-default-host_ref-26c6fa050dc847e3.yaml).
2. Secret list pagination keeps the filters — fix
- Before:
next/previousofGET /v1/secrets?secret_type=passphrasewere…/v1/secrets?limit=10&offset=10, dropping the filters. After: every query parameter exceptlimit/offsetis URL-encoded and appended (barbican/api/controllers/secrets.py:436,barbican/common/hrefs.py:88). Only the secrets list does this; containers, orders, consumers and transport keys still drop extra parameters. - Carrying it over: two files; easy.
5. Non-base64 binary payloads — fix
- Before:
GET …/payloadwith a binaryAcceptfailed with 500 when the store returned raw (not base64) data, as legacy castellan/Vault rows do. After: if base64 decoding fails, the data is returned as-is (barbican/plugin/util/translations.py:107). Ambiguous by nature: raw data that happens to be valid base64 is still decoded. - Impact: 07 § 3.7 (Vault legacy rows).
38. EC key sizes in orders — fix
TypeOrderValidatoraccepted only multiples of 8, rejecting P-521. Nowalgorithm: ecrequires 256, 384 or 521 and any other value is400 Provided field value is not supported(barbican/common/validators.py:531,barbican/common/validators.py:543). Note that no bundled store can generate EC keys (simple_crypto supports RSA/DSA only), so such orders still end inERRORunless a KMIP/Vault store generates them [inferred].
9. KMIP object names — fix
- PyKMIP does not enforce unique
Nameattributes and some KMIP servers reject duplicates or unnamed objects; every registered object now getsname = uuid4(barbican/plugin/kmip_secret_store.py:471). Barbican still identifies objects bykey_uuid.
24–26. Vault options — feature, deprecation
- New
[vault_plugin] kv_path(sub-path inside the KV mount) andkv_version(1 or 2, default 2) passed to castellan (barbican/plugin/vault_secret_store.py:44); castellan requirement raised to ≥ 4.2.0.vault_urlis now aURIOptlimited to http/https (barbican/plugin/vault_secret_store.py:50): an invalid URL fails at start-up.use_ssldeprecated for removal because it never had any effect (barbican/plugin/vault_secret_store.py:58). - Impact on data: changing
kv_pathorkv_versionmoves where new secrets are written and where existing ones are looked up (castellan builds the URL from them): existing secrets become unreadable unless they are moved (07 § 3.7) [inferred fromcastellan:castellan/key_manager/vault_key_manager.py:202].
37. Batched database clean-up — fix
cleanup_softdeletes,cleanup_parent_with_no_child,cleanup_unassociated_projectsand the expired-secret soft delete now select ids and delete/update in batches ofDEFAULT_CLEANUP_BATCH_SIZE= 10,000 rows, committing each batch (barbican/model/clean.py:31,barbican/model/clean.py:458).barbican-db-manage clean --batch-size/-bsets it (barbican/cmd/db_manage.py:131);barbican-manage db cleanhas no such option and always uses 10,000 (barbican/cmd/barbican_manage.py:83).- Operational impact: a failure mid-run leaves the earlier batches committed (the run is no longer all-or-nothing).
4, 22. Missing master KEK — fix
[simple_crypto_plugin] kekgetsdefault=[]and the constructor tests truthiness (barbican/plugin/crypto/simple_crypto.py:37,barbican/plugin/crypto/simple_crypto.py:59), so an unconfigured KEK raisesValueError("SimpleCrypto KEK is undefined"), logged when plugins load; requests then fail with500 … failure seen(CryptoPluginNotFound) as observed during this analysis (02 § 2.3).
Other changes
| # | Commit | Change |
|---|---|---|
| 20 | 96b3e462f7c1 | barbican/cmd/pkcs11_migrate_kek_signatures.py:24 imported P11CryptoPluginException from the wrong module (the HSM signature migration script crashed with ImportError) |
| 36 | 27e3961bf1fa | init_backend(THREADING) moved to barbican/cmd/__init__.py:16 so the worker and listener never start on eventlet by accident |
| 6 | b8743d37f695 | oslo.reports Guru Meditation Report on signal for worker, retry and listener (barbican/cmd/worker.py:47); new oslo.reports config namespace |
| 7 | c9f42aa0150a | config sample: cotyledon options replace oslo.service.service (threading backend) |
| 28 | 69614993e78b | Python 3.9/3.10 dropped (≥ 3.11), 3.14 declared |
| 29 | 160f0dd26e58 | pbr wsgi_scripts removed: no barbican-wsgi-api binary; deploy barbican.wsgi.api (uWSGI/gunicorn module) |
| 27 | 7680e9b37139 | packaging metadata, entry points and scripts moved to pyproject.toml (same names) |
| 12 | 27daa9183279 | Python 3.13 declared |
| 1, 3, 8 | e8c077abdcc4, b2ca3c4dddea, 8e2d2474e66d | refactors: dead Dogtag check, orm.declarative_base, direct uuidutils (no behaviour change) |
| 16 | 6eacf8d4ad7c | CI: functional job for the Vault plugin against OpenBao (Vault fork) — useful evidence that the Vault store works with OpenBao |
Maintenance-only changes
| Commit | Subject | Why it is usually not carried over |
|---|---|---|
9ef6d15f124a, 883354a757eb, 206022b307e5, 2cce0e85ae09, ffb922aeed66 | devstack plugin changes | deployment tooling only |
00d72d1c70c5, 7be9ee472414 | Vault/OpenBao CI job settings | CI |
15bac42b70a0, a5f939989605 | unused doc/test dependencies removed | dependencies of docs/tests |
ed57ec423b9c, 9c0931065be6, de32745a7a4f | release-bot branch updates | branch bookkeeping |
54e313ed25ca, 6fc5e2ff991c, 510b69abd0a0 | documentation (api-ref, enforce_new_defaults note) | docs |
95b3d37e624f, f53acbcd4b61, f96e68006c2a, 04acd70dc081 | test assertion, whitespace, shebangs | cosmetic |
196d77a6ee54, e2b8884acd97 | translations | i18n |
Carry-over plan (onto stable/2026.1, oldest first)
Apply with git cherry-pick -x. Order matters for the policy pair: #30 before #42.
efe7040bca08pagination filters (#2)aeec1611f602binary payload fallback (#5)de534b60d7f9KMIP names (#9)fa35b14f9931thena9f7478e3629simple_crypto KEK checks (#4, #22)9f28ddb9248cmicroversion 1.2 (#19) — API change; carry only if clients may negotiate 1.27eeb9a0f3560,7371127192e5,f846df774d1bVault options (#24–26) — needs castellan ≥ 4.2.096b3e462f7c1PKCS#11 migration script (#20)65a1dc983400EC bit lengths (#38)70b20d3f9616host_hrefdefault (#34) — upgrade note requiredc370f7991a35ACL policy target (#30)be7d8103db9fSecure RBAC by default (#42) — upgrade note required; usually not backported to a stable branch because it changes authorisation27e3961bf1fathreading backend order (#36) — only if the target already uses the oslo.service threading backenda28ddb94c353batched clean-up (#37)
Packaging changes (#27–29) and GMR (#6) are release-level and not worth backporting.
Source: reverse-spec-barbican/06-change-history_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.