Skip to content

feat: enforce trusted Iceberg metadata pointers#4

Draft
hkwi wants to merge 1 commit into
feat/encrypted-table-server-purge-squashedfrom
trusted-metadata-pointer-on-encrypted-purge
Draft

feat: enforce trusted Iceberg metadata pointers#4
hkwi wants to merge 1 commit into
feat/encrypted-table-server-purge-squashedfrom
trusted-metadata-pointer-on-encrypted-purge

Conversation

@hkwi

@hkwi hkwi commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • Persist a versioned, server-computed SHA-256 metadata digest, table UUID, and explicit encryption-key state in the same Polaris entity revision as every Iceberg metadata location.
  • Route table creation, commits, register-table overwrite, and CREATE/UPDATE notifications through one TableMetadataAdmission gateway, with a persistence guard against bare metadata locations.
  • Verify object-store metadata before table loads and cleanup, reject table UUID or encryption-key transitions, and fail closed for unattested legacy entities.
  • Bind purge to the exact entity revision whose metadata was verified, and make stale-drop rejection consistent across persistence backends.

Motivation

This patch is stacked on apache#5060 and supersedes the narrower design in #3.

Unlike #3, this does not limit integrity protection to encrypted tables or lazily backfill trust during an ordinary read. Plaintext and encrypted metadata use the same trusted-pointer invariant, and every metadata-location mutation must atomically replace the complete pointer.

Design

TableMetadataAdmission owns the trusted-pointer format and all metadata transition checks:

  • integrity format version
  • canonical metadata SHA-256 digest encoded as Base64
  • table UUID
  • explicit encryption-key state (none or present)
  • encryption key ID when present
  • existing metadata-derived internal properties

Normal commits and notifications reject legacy entities without a complete pointer. The existing explicit registerTable(..., overwrite=true) operation is the only attestation ceremony for such tables, and it still requires any stored UUID to match. Loads and cleanup tasks never infer or repair trust from object storage.

For purge, table operations retain the exact entity revision used for the successful metadata verification. The drop uses that revision as its compare-and-set precondition, so a concurrent metadata pointer change prevents both the drop and cleanup scheduling.

Compatibility notes

  • Tables created or admitted by this patch have trusted pointers immediately.
  • Existing tables without a complete pointer fail closed until explicitly attested with register-table overwrite.
  • Pre-existing cleanup tasks without a complete pointer also fail closed.
  • Table UUID and encryption key ID are immutable after initial admission.

Tests

  • ./gradlew format compileAll
  • ./gradlew :polaris-core:check
  • ./gradlew :polaris-runtime-service:check -x :polaris-runtime-service:intTest

The runtime intTest task was not run.

AI assistance

AI assistance was used to analyze, implement, and test this change.

Sign up for free to 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.

1 participant