Skip to content

HBASE-29368 [Feature] Key management for encryption at rest (MVP changes) - #7618

Draft
haridsv wants to merge 17 commits into
apache:masterfrom
haridsv:HBASE-29368-feature
Draft

HBASE-29368 [Feature] Key management for encryption at rest (MVP changes)#7618
haridsv wants to merge 17 commits into
apache:masterfrom
haridsv:HBASE-29368-feature

Conversation

@haridsv

@haridsvharidsv commented Jan 12, 2026

Copy link
Copy Markdown
Contributor

This PR implements the key management feature for HBase encryption at rest, building on the API surface and refactoring introduced in the precursor PR (#7584). It supersedes PR #7421 which originally had most of the changes from this PR as well PR #7584.

Jira: HBASE-29368
Design doc: https://docs.google.com/document/d/1ToW_rveXHXUc1F6eFNQfu5LOeMAjzgq6FcYUDbdZrSM/edit?usp=sharing
Discussion thread: https://lists.apache.org/thread/q7g2rr2xcgl64rkn9j3mnokf6fvohp2y

Cumulative changes from feature branch corresponding to the following sub-tasks:

  1. Phase 1: Key caching and minimal service
  2. Phase 2: Integrate key management with existing encryption
  3. Phase 2: Migration path from current encryption to managed encryption
  4. Phase 2: Admin API to trigger for System Key rotation detection as an alternative to failover.
  5. Phase 3: Additional key management APIs
  6. Significant optimizations, tweaks and cleanup 083df81

This feature introduces a comprehensive key management system that extends HBase's existing encryption-at-rest capabilities. The implementation provides enterprise-grade key lifecycle management with support for key rotation, hierarchical namespace resolution for key lookup, key caching and improved integration with key management systems to handle key life cycles and external key changes.

1. Managed Keys Infrastructure

  • Introduction of ManagedKeyProvider interface for pluggable key provider implementations on the lines of the existing KeyProvider interface.
  • The new interface can also return Data Encryption Keys (DEKs) and a lot more details on the keys.
  • Comes with the default ManagedKeyStoreKeyProvider implementation using Java KeyStore, similar to the existing KeyStoreKeyProvider.
  • Enables logical key isolation for multi-tenant scenarios through custodian identifiers (future use cases) and the special default global custodian.
  • CF level namespace attribute to resolve a different DEK for each CF.

2. System Key (STK) Management

  • Cluster-wide system key for wrapping data encryption keys (DEKs). This is equivalent to the existing master key, but better managed and operation friendly.
  • Secure storage in HDFS with support for automatic key rotation during boot up.
  • Internal API to trigger key rotation and propagation to all RegionServers without needing to do a rolling restart.
  • Preserves the current double-wrapping architecture: DEKs wrapped by STK, STK sourced from external KMS

3. Server-Side KeymetaAdmin API

The KeymetaAdmin interface provides server (internal) key management operations (implemented by KeymetaAdminImpl):

  • enableKeyManagement(keyCust, keyNamespace) - Enable key management for a custodian/namespace pair
  • getManagedKeys(keyCust, keyNamespace) - Query key status and metadata
  • rotateSTK() - Check for and propagate new system keys
  • disableKeyManagement(keyCust, keyNamespace) - Disable all the keys for a custodian/namespace
  • disableManagedKey(keyCust, keyNamespace, keyMetadataHash) - Disable a specific key
  • rotateManagedKey(keyCust, keyNamespace) - Rotate the active key
  • refreshManagedKeys(keyCust, keyNamespace) - Refresh from external KMS to validate all the keys.
  • setManagedKey(keyCust, keyNamespace) - Set specified key as ACTIVE key.
  • Internal cache management operations for convenience and meeting SLAs.

4. Persistent Key Metadata Storage

  • New system table hbase:keymeta for storing key metadata and state which acts as an L2 cache.
  • Tracks key lifecycle: ACTIVE, INACTIVE, DISABLED, FAILED states
  • Stores wrapped DEKs and metadata for key lookup without depending on external KMS.
  • Optimized for high-priority access with in-memory column families
  • Key metadata tracking with cryptographic hashes for integrity verification

5. Multi-Layer Caching

  • L1: In-memory Caffeine cache on RegionServers for hot key data

  • L2: Keymeta table for persistent key metadata that is shared across all RegionServers.

  • L3: Dynamic lookup from external KMS as fallback when not found in L2.

  • Cache invalidation mechanism for key rotation scenarios

  • Backward Compatibility: Changes are fully compatible with existing encryption-at-rest configuration

  • Gradual step-by-step migration: Well defined migration path from existing configuration to new configuration

  • Performance: Minimal overhead through efficient caching and lazy key loading

  • Security: Cryptographic verification of key metadata, secure key wrapping

  • Extensibility: Plugin architecture for custom key provider implementations

  • Testing: Comprehensive unit and integration tests coverage

The implementation follows a layered architecture:

  1. Provider Layer: Pluggable ManagedKeyProvider for KMS integration
  2. Management Layer:KeymetaAdmin API for server-side administrative operations
  3. Persistence Layer:KeymetaTableAccessor for metadata storage
  4. Cache Layer:ManagedKeyDataCache and SystemKeyCache for performance

I would particularly appreciate feedback on:

  1. API Design: Is the KeymetaAdmin API intuitive and complete for common key management scenarios?
  2. Security Model: Does the double-wrapping architecture (DEK wrapped by STK, STK from KMS) provide appropriate security guarantees?
  3. Performance: Are there potential bottlenecks in the caching strategy or table access patterns?
  4. Testing Coverage: Are there additional test scenarios we should cover?
  5. Documentation: Is the design document clear? What additional documentation would be helpful?
  6. Compatibility: Any concerns about interaction with existing HBase features?

After incorporating community feedback, I plan to:

  1. Address any issues identified during review
  2. Implement the work identified for future phases
  3. Add additional documentation to the reference guide

This PR introduces changes across multiple modules, so I recommend focusing on these core components first:

Core Architecture:

  1. Design document (linked above) - architectural overview
  2. ManagedKeyProvider, KeymetaAdmin, ManagedKeyData interfaces (hbase-common)
  3. ManagedKeys.proto - protocol definitions
  4. HMaster and misc. procedure changes - initialization of keymeta in a predictable order
  5. FixedFileTrailer + reader/writer changes - encode/decode additional encryption key in store files

Key Implementation:

  1. KeymetaAdminImpl, KeymetaTableAccessor, KeyManagementUtils, SystemKeyManager, SystemKeyAccessor - admin operations and persistence
  2. ManagedKeyDataCache, SystemKeyCache - caching layer
  3. SecurityUtil - encryption context creation
  4. TestKeymetaAdminImpl - for usage patterns of the server-side API

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@virajjasani
virajjasani self-requested a review January 13, 2026 05:16
@Apache-HBase

Copy link
Copy Markdown

💔 -1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec0m 30sDocker mode activated.
_ Prechecks _
+1 💚dupname0m 0sNo case conflicting files found.
+0 🆗codespell0m 0scodespell was not available.
+0 🆗detsecrets0m 0sdetect-secrets was not available.
+0 🆗yamllint0m 0syamllint was not available.
+1 💚@author0m 0sThe patch does not contain any @author tags.
+1 💚hbaseanti0m 0sPatch does not have any anti-patterns.
_ master Compile Tests _
+0 🆗mvndep0m 15sMaven dependency ordering for branch
+1 💚mvninstall3m 15smaster passed
+1 💚compile8m 29smaster passed
+1 💚checkstyle2m 17smaster passed
+1 💚spotbugs11m 40smaster passed
+1 💚spotless0m 49sbranch has no errors when running spotless:check.
_ Patch Compile Tests _
+0 🆗mvndep0m 11sMaven dependency ordering for patch
+1 💚mvninstall3m 7sthe patch passed
+1 💚compile8m 27sthe patch passed
-0 ⚠️javac8m 27s/results-compile-javac-root.txtroot generated 3 new + 1887 unchanged - 1 fixed = 1890 total (was 1888)
+1 💚blanks0m 0sThe patch has no blanks issues.
-0 ⚠️checkstyle2m 17s/results-checkstyle-root.txtroot: The patch generated 1 new + 41 unchanged - 2 fixed = 42 total (was 43)
-0 ⚠️rubocop0m 30s/results-rubocop.txtThe patch generated 99 new + 71 unchanged - 13 fixed = 170 total (was 84)
+1 💚spotbugs12m 13sthe patch passed
+1 💚hadoopcheck11m 57sPatch does not cause any errors with Hadoop 3.3.6 3.4.1.
-1 ❌spotless0m 13s/patch-spotless.txtpatch has 21 errors when running spotless:check, run spotless:apply to fix.
_ Other Tests _
+1 💚asflicense0m 54sThe patch does not generate ASF License warnings.
75m 54s
SubsystemReport/Notes
DockerClientAPI=1.43 ServerAPI=1.43 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7618/2/artifact/yetus-general-check/output/Dockerfile
GITHUB PR#7618
Optional Testsdupname asflicense javac spotbugs checkstyle codespell detsecrets compile hadoopcheck hbaseanti spotless rubocop yamllint
unameLinux a0fef130e4ae 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionmaster / 9a89bf2
Default JavaEclipse Adoptium-17.0.11+9
Max. process+thread count192 (vs. ulimit of 30000)
modulesC: hbase-common hbase-client hbase-server hbase-thrift hbase-shell . U: .
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7618/2/console
versionsgit=2.34.1 maven=3.9.8 spotbugs=4.7.3 rubocop=1.37.1
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@Apache-HBase

Copy link
Copy Markdown

💔 -1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec0m 13sDocker mode activated.
-0 ⚠️yetus0m 4sUnprocessed flag(s): --brief-report-file --spotbugs-strict-precheck --author-ignore-list --blanks-eol-ignore-file --blanks-tabs-ignore-file --quick-hadoopcheck
_ Prechecks _
_ master Compile Tests _
+0 🆗mvndep0m 10sMaven dependency ordering for branch
+1 💚mvninstall2m 32smaster passed
+1 💚compile1m 41smaster passed
+1 💚javadoc2m 47smaster passed
+1 💚shadedjars4m 26sbranch has no errors when building our shaded downstream artifacts.
_ Patch Compile Tests _
+0 🆗mvndep0m 10sMaven dependency ordering for patch
+1 💚mvninstall2m 17sthe patch passed
+1 💚compile1m 40sthe patch passed
+1 💚javac1m 40sthe patch passed
-0 ⚠️javadoc0m 12s/results-javadoc-javadoc-hbase-common.txthbase-common generated 1 new + 4 unchanged - 0 fixed = 5 total (was 4)
-0 ⚠️javadoc1m 30s/results-javadoc-javadoc-root.txtroot generated 1 new + 212 unchanged - 0 fixed = 213 total (was 212)
+1 💚shadedjars4m 27spatch has no errors when building our shaded downstream artifacts.
_ Other Tests _
-1 ❌unit243m 7s/patch-unit-root.txtroot in the patch failed.
272m 7s
SubsystemReport/Notes
DockerClientAPI=1.53 ServerAPI=1.53 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7618/2/artifact/yetus-jdk17-hadoop3-check/output/Dockerfile
GITHUB PR#7618
Optional Testsjavac javadoc unit compile shadedjars
unameLinux 0b78b0ba17aa 6.14.0-1018-aws #18~24.04.1-Ubuntu SMP Mon Nov 24 19:46:27 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionmaster / 9a89bf2
Default JavaEclipse Adoptium-17.0.11+9
Test Resultshttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7618/2/testReport/
Max. process+thread count5401 (vs. ulimit of 30000)
modulesC: hbase-common hbase-client hbase-server hbase-thrift hbase-shell . U: .
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7618/2/console
versionsgit=2.34.1 maven=3.9.8
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@haridsv
haridsv marked this pull request as draft March 17, 2026 15:16
This PR implements the key management feature for HBase encryption at rest,
building on the API surface and refactoring introduced in the precursor PR (apache#7584).
Jira: [HBASE-29368](https://issues.apache.org/jira/browse/HBASE-29368)
Design doc: https://docs.google.com/document/d/1ToW_rveXHXUc1F6eFNQfu5LOeMAjzgq6FcYUDbdZrSM/edit?usp=sharing
Discussion thread: https://lists.apache.org/thread/q7g2rr2xcgl64rkn9j3mnokf6fvohp2y
Cumulative changes from feature branch corresponding to the following sub-tasks:
1. [Phase 1: Key caching and minimal service](https://issues.apache.org/jira/browse/HBASE-29402)
2. [Phase 2: Integrate key management with existing encryption](https://issues.apache.org/jira/browse/HBASE-29495)
3. [Phase 2: Migration path from current encryption to managed encryption](https://issues.apache.org/jira/browse/HBASE-29617)
4. [Phase 2: Admin API to trigger for System Key rotation detection as an alternative to failover.](https://issues.apache.org/jira/browse/HBASE-29643)
5. [Phase 3: Additional key management APIs](https://issues.apache.org/jira/browse/HBASE-29666)
This feature introduces a comprehensive key management system that extends HBase's existing encryption-at-rest capabilities. The implementation provides enterprise-grade key lifecycle management with support for key rotation, hierarchical namespace resolution for key lookup, key caching and improved integration with key management systems to handle key life cycles and external key changes.
**1. Managed Keys Infrastructure**
- Introduction of `ManagedKeyProvider` interface for pluggable key provider implementations on the lines of the existing `KeyProvider` interface.
- The new interface can also return Data Encryption Keys (DEKs) and a lot more details on the keys.
- Comes with the default `ManagedKeyStoreKeyProvider` implementation using Java KeyStore, similar to the existing `KeyStoreKeyProvider`.
- Enables logical key isolation for multi-tenant scenarios through custodian identifiers (future use cases) and the special default global custodian.
- Hierarchical namespace resolution for DEKs with automatic fallback: explicit CF namespace attribute → constructed `table/family` namespace → table name → global namespace
**2. System Key (STK) Management**
- Cluster-wide system key for wrapping data encryption keys (DEKs). This is equivalent to the existing master key, but better managed and operation friendly.
- Secure storage in HDFS with support for automatic key rotation during boot up.
- Admin API to trigger key rotation and propagation to all RegionServers without needing to do a rolling restart.
- Preserves the current double-wrapping architecture: DEKs wrapped by STK, STK sourced from external KMS
**3. KeymetaAdmin API**
- `enableKeyManagement(keyCust, keyNamespace)` - Enable key management for a custodian/namespace pair
- `getManagedKeys(keyCust, keyNamespace)` - Query key status and metadata
- `rotateSTK()` - Check for and propagate new system keys
- `disableKeyManagement(keyCust, keyNamespace)` - Disable all the keys for a custodian/namespace
- `disableManagedKey(keyCust, keyNamespace, keyMetadataHash)` - Disable a specific key
- `rotateManagedKey(keyCust, keyNamespace)` - Rotate the active key
- `refreshManagedKeys(keyCust, keyNamespace)` - Refresh from external KMS to validate all the keys.
- Internal cache management operations for convenience and meeting SLAs.
**4. Persistent Key Metadata Storage**
- New system table `hbase:keymeta` for storing key metadata and state which acts as an `L2` cache.
- Tracks key lifecycle: `ACTIVE`, `INACTIVE`, `DISABLED`, `FAILED` states
- Stores wrapped DEKs and metadata for key lookup without depending on external KMS.
- Optimized for high-priority access with in-memory column families
- Key metadata tracking with cryptographic hashes for integrity verification
**5. Multi-Layer Caching**
- L1: In-memory Caffeine cache on RegionServers for hot key data
- L2: Keymeta table for persistent key metadata that is shared across all RegionServers.
- L3: Dynamic lookup from external KMS as fallback when not found in L2.
- Cache invalidation mechanism for key rotation scenarios
**6. HBase Shell Integration**
- `enable_key_management` - Enable key management for a custodian and namespace
- `show_key_status` - Display key status and metadata
- `rotate_stk` - Trigger system key rotation
- `disable_key_management` - Disable key management for a custodian and namespace
- `disable_managed_key` - Disable a specific key
- `rotate_managed_key` - Rotate the active key
- `refresh_managed_keys` - Refresh all keys for a custodian and namespace
- **Backward Compatibility:** Changes are fully compatible with existing encryption-at-rest configuration
- **Gradual step-by-step migration**: Well defined migration path from existing configuration to new configuration
- **Performance:** Minimal overhead through efficient caching and lazy key loading
- **Security:** Cryptographic verification of key metadata, secure key wrapping
- **Operability:** Administrative tools for key life cycle and cache management
- **Extensibility:** Plugin architecture for custom key provider implementations
- **Testing:** Comprehensive unit and integration tests coverage
The implementation follows a layered architecture:
1. **Provider Layer:** Pluggable `ManagedKeyProvider` for KMS integration
2. **Management Layer:** `KeyMetaAdmin` API for administrative operations
3. **Persistence Layer:** `KeymetaTableAccessor` for metadata storage
4. **Cache Layer:** `ManagedKeyDataCache` and `SystemKeyCache` for performance
5. **Service Layer:** Coprocessor endpoints for client-server communication
I would particularly appreciate feedback on:
1. **API Design:** Is the `KeymetaAdmin` API intuitive and complete for common key management scenarios?
2. **Security Model:** Does the double-wrapping architecture (DEK wrapped by STK, STK from KMS) provide appropriate security guarantees?
3. **Performance:** Are there potential bottlenecks in the caching strategy or table access patterns?
4. **Operational Aspects:** Are the administrative commands sufficient for the needs of operations and monitoring?
5. **Testing Coverage:** Are there additional test scenarios we should cover?
6. **Documentation:** Is the design document clear? What additional documentation would be helpful?
7. **Compatibility:** Any concerns about interaction with existing HBase features?
After incorporating community feedback, I plan to:
1. Address any issues identified during review
2. Implement the work identified for future phases
3. Add additional documentation to the reference guide
This PR introduces changes across multiple modules, so I recommend focusing on these **core components** first:
**Core Architecture:**
1. Design document (linked above) - architectural overview
2. `ManagedKeyProvider`, `KeymetaAdmin`, `ManagedKeyData` interfaces (hbase-common)
3. `ManagedKeys.proto` - protocol definitions
4. `HMaster` and misc. procedure changes - initialization of `keymeta` in a predictable order
5. `FixedFileTrailer` + reader/writer changes - encode/decode additional encryption key in store files
**Key Implementation:**
1. `KeymetaAdminImpl`, `KeymetaTableAccessor`, `ManagedKeyUtils`, `SystemKeyManager`, `SystemKeyAccessor` - admin operations and persistence
2. `ManagedKeyDataCache`, `SystemKeyCache` - caching layer
3. `SecurityUtil` - encryption context creation
**Client & Shell:**
1. `KeymetaAdminClient` - client API
2. Shell commands and Ruby wrappers
**Tests & Examples:**
1. `TestKeymetaAdminImpl`, `TestManagedKeymeta` - for usage patterns
2. `key_provider_keymeta_migration_test.rb` - E2E migration steps
Main purpose was to avoid byte[] garbage as much as possible. The following describe the overall changes:
- Removed key namespace from trailer in favor of key identity.
- Removed the support for dynamic key namespace based on table and CF names to avoid -ve key lookup buildup in the cache
- Optimization to reduce byte[] garbage due to key namespace handling
- Refactor caches and facilitate more efficient lookups with reduced garbage generation
- Streamline the cache usage as part of making cache lookups more efficient
- Consolidate managed key identity types and shared row-key encoding so hot paths reuse backing byte[] and avoid redundant copies, further reducing allocation on lookups
- Also updated the disabledKeyManagement to update all key states to INACTIVE.
- Change ManagedKeyProvider interface to take identity where it makes sense and avoid byte[] copy
- Added a new admin API setManagedKey
- Changed KeymetaAdminImpl -> KeymetaTableAccessor relationship as composition for a cleaner relationship
- More consistent exception handling
- Refactor ManagedKeyData and keymeta to configurable digest and partial/full identity and defaulted to a hash that uses 8 bytes instead of 16.
@haridsv
haridsvforce-pushed the HBASE-29368-feature branch from 9a89bf2 to 083df81CompareApril 3, 2026 14:56
@haridsv
haridsv marked this pull request as ready for review April 3, 2026 17:01
@haridsv
haridsvforce-pushed the HBASE-29368-feature branch 3 times, most recently from 4689acd to 9a43107CompareApril 9, 2026 16:29
@haridsv
haridsv marked this pull request as draft April 14, 2026 16:56
… and gaps.
Also updated disableManagedKey to take metadata. This makes it consistent with that of setManagedKey
@haridsv
haridsvforce-pushed the HBASE-29368-feature branch from 9a43107 to dcec79bCompareApril 27, 2026 14:25
haridsvand others added 8 commits April 27, 2026 21:02
The SecureRandom is only used on the encrypt path (getEncryptor() and
getRandomKey()); the decrypt/unwrap path never touches it. Building it
eagerly in the constructor wasted a SecureRandom.getInstance() provider
lookup on every Cipher instantiation, including the per-key DEK unwrap in
the keymeta read path (parseFromResult -> SecurityUtil.unwrapKey).
Defer construction to getRNG(), reading the RNG config lazily off the
retained provider. The field is volatile and uses a benign-race single
check (no locking): a race builds at most one extra RNG that is harmlessly
discarded. getRandomKey() now routes through getRNG() instead of the field.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@haridsv@Apache-HBase@hdara-sfdc