返回正文目录

type: optimization version: 9.2.0 ticket: MODEL-field-permissions severity: medium status: local-verified test_strategy: unit-and-integration-test owner: foggy-dataset-model created_at: 2026-06-13 updated_at: 2026-06-13 owner_repo: foggy-data-mcp-bridge-wt-dev-compose owner_module: foggy-dataset-model

Declarative TM/QM Field Permissions

Background

Before this work, field visibility was mainly controlled by runtime fieldAccess and physical-column deniedColumns. That works for request-time enforcement, but model authors had no stable TM/QM-level contract for hiding sensitive semantic fields from metadata and query execution by user role, group, permission, namespace, or security context.

This work adds a declarative fieldPermissions layer to both TableModel and QueryModel definitions. The resolved output is still fed into the existing fieldAccess enforcement path, so SQL/query behavior and metadata visibility share the same effective allowlist.

Contract

fieldPermissions supports:

{
  defaultVisible: false,
  visibleFields: [
    {
      when: { hasAnyRole: ['finance-manager'] },
      fields: ['orderId', 'salesAmount', 'grossMargin']
    }
  ],
  hiddenFields: [
    {
      when: { namespaceIn: ['public'] },
      fields: ['grossMargin']
    }
  ]
}

Resolution rules:

Supported when predicates:

Code Inventory

Path Change
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/def/permission/FieldPermissionsDef.java Adds the declarative permission block.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/def/permission/FieldPermissionRuleDef.java Adds one conditional visible/hidden rule.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/def/DbModelDef.java Loads TM-level fieldPermissions.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/def/query/DbQueryModelDef.java Loads QM-level fieldPermissions.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/spi/TableModel.java Exposes TM-level permissions through the SPI.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/spi/QueryModel.java Exposes QM-level permissions through the SPI.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/semantic/permission/FieldPermissionResolver.java Resolves TM, QM, runtime, and physical-column permission layers into one effective allowlist.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/plugins/result_set_filter/ModelFieldPermissionResolveStep.java Applies the resolved allowlist before existing query field-access enforcement.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/semantic/service/impl/SemanticServiceV3Impl.java Uses the same resolved allowlist for semantic metadata output.
foggy-dataset-model/src/main/java/com/foggyframework/dataset/db/model/semantic/service/impl/SemanticQueryServiceV3Impl.java Carries security context into the semantic query path.
foggy-dataset-model/src/test/java/com/foggyframework/dataset/db/model/semantic/permission/FieldPermissionResolverTest.java Unit coverage for resolver contracts and fail-closed cases.
foggy-dataset-model/src/test/java/com/foggyframework/dataset/db/model/plugins/result_set_filter/FieldAccessPermissionStepTest.java Regression coverage for normalized field-access enforcement.
foggy-dataset-model/src/test/java/com/foggyframework/dataset/db/model/ecommerce/FieldAccessPermissionIntegrationTest.java Integration coverage for query execution permission behavior.
foggy-dataset-model/src/test/java/com/foggyframework/dataset/db/model/semantic/SemanticServiceV3Test.java Metadata coverage for TM/QM field permission filtering.

Verification

2026-06-13 local gate:

mvn test -pl foggy-dataset-model -Dspring.profiles.active=sqlite -P'!multi-db' '-Dtest=FieldPermissionResolverTest,FieldAccessPermissionStepTest,FieldAccessPermissionIntegrationTest,SemanticServiceV3Test,PivotOuterResponseCacheTest,PivotOuterCacheTelemetryTest,PivotIntegrationTest,PivotCascadeGenerateSqlParityIntegrationTest'

Result:

2026-06-13 deniedColumns precedence regression:

mvn test -pl foggy-dataset-model -Dspring.profiles.active=sqlite -P'!multi-db' '-Dtest=FieldAccessPermissionIntegrationTest$ModelPermissionAndDeniedColumnsTests#modelFieldPermissionsAllowedButDeniedColumnsRejected'
mvn test -pl foggy-dataset-model -Dspring.profiles.active=sqlite -P'!multi-db' '-Dtest=FieldAccessPermissionIntegrationTest'

Result:

Remaining Boundary