feat: add OpenBao provider implementation - #101
Merged
alanshaw merged 2 commits intoAug 28, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the regionkey package to match the amended regional key-management RFC by introducing an OpenBao Transit–backed Provider (AES-256-GCM with derived, context-bound keys) and refactoring the in-process implementation and API to use an explicit (space, blob digest) binding context rather than the prior scope/KEK-source model.
Changes:
- Add
OpenBaoProvider(Transit encrypt/decrypt) and corresponding unit + optional live tests. - Replace the old in-process A256KW/KEK-source design with
InProcessProviderusing AES-256-GCM and a(Space, Digest)BindingContext. - Remove the in-memory KEK custody and mlock-based machinery (StaticKEKSource, SoftwareProvider, KEK, mlock helpers) and update deps accordingly.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| regionkey/static.go | Removed in-memory KEK source implementation. |
| regionkey/software.go | Removed prior A256KW-based software provider. |
| regionkey/regionkey.go | Updates package docs/API: introduces BindingContext, ErrAuthentication, and binding encoding helper. |
| regionkey/regionkey_test.go | Updates tests to BindingContext, AES-GCM semantics, rotation via InProcessProvider. |
| regionkey/openbao.go | Adds OpenBao Transit-backed provider implementation. |
| regionkey/openbao_test.go | Adds httptest-based request/response shape + error-mapping tests. |
| regionkey/openbao_live_test.go | Adds optional live integration test (skipped unless env vars are set). |
| regionkey/mlock_unix.go | Removed (no longer locking KEKs in-process). |
| regionkey/mlock_other.go | Removed (no longer locking KEKs in-process). |
| regionkey/kek.go | Removed (no longer storing KEKs in locked buffers). |
| regionkey/kek_internal_test.go | Removed (tests for KEK locking/zeroing no longer apply). |
| regionkey/inprocess.go | Adds InProcessProvider (AES-256-GCM + HKDF binding) for tests/dev. |
| go.mod | Drops go-fee, adds OpenBao API dependency, adjusts indirect deps. |
| go.sum | Updates sums for dependency changes. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+57
to
+66
| // Wrap implements [Provider.Wrap]: a transit encrypt of cek under the key's | ||
| // current version, with the binding as the derivation context. The returned | ||
| // ciphertext is transit's "vault:vN:…" string, which embeds the version it | ||
| // was wrapped under; WrappedKey.Version records the same version ("vN") for | ||
| // the provider-agnostic bookkeeping column. | ||
| func (p *OpenBaoProvider) Wrap(ctx context.Context, binding BindingContext, cek []byte) (WrappedKey, error) { | ||
| secret, err := p.logical.WriteWithContext(ctx, p.mount+"/encrypt/"+p.key, map[string]interface{}{ | ||
| "plaintext": base64.StdEncoding.EncodeToString(cek), | ||
| "context": base64.StdEncoding.EncodeToString(bindingBytes(binding)), | ||
| }) |
Comment on lines
+92
to
+110
| // Wrap implements [Provider.Wrap]: it seals cek with AES-256-GCM under the | ||
| // binding-derived subkey of the current region KEK, prepends the fresh random | ||
| // nonce, and tags the result with the KEK's version. | ||
| func (p *InProcessProvider) Wrap(_ context.Context, binding BindingContext, cek []byte) (WrappedKey, error) { | ||
| p.mu.RLock() | ||
| version := p.current | ||
| kek := p.keys[version] | ||
| p.mu.RUnlock() | ||
|
|
||
| aead, err := boundAEAD(kek, binding) | ||
| if err != nil { | ||
| return WrappedKey{}, err | ||
| } | ||
| nonce := make([]byte, gcmNonceLen) | ||
| if _, err := rand.Read(nonce); err != nil { | ||
| return WrappedKey{}, fmt.Errorf("regionkey: generating nonce: %w", err) | ||
| } | ||
| return WrappedKey{Version: version, Ciphertext: aead.Seal(nonce, nonce, cek, nil)}, nil | ||
| } |
alanshaw
force-pushed
the
ash/feat/openbao-provider-impl
branch
3 times, most recently
from
August 27, 2026 08:47
10dbf98 to
9aa765b
Compare
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
alanshaw
force-pushed
the
ash/feat/openbao-provider-impl
branch
from
August 28, 2026 11:11
9aa765b to
1c30f05
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds an OpenBao
Providerimplementation for wrapping and unwrapping CEKs.The code related to holding the KEK in memory has been removed per the RFC amendment fil-one/RFC#21
The regional KEK is expected to be present in OpenBao under the key name passed to the constructor and it MUST be created with
derived=true, exportable=false.Additionally:
SoftwareProvidertoInProcessProviderand removes theKEKSourceinterface as it would only have been implemented bySoftwareProvider.ScopetoBindingContextsince it is the context bound for key derivation.