mikebridge opened a new pull request, #43827:
URL: https://github.com/apache/superset/pull/43827

   ### SUMMARY
   
   Hardening follow-up to **#43474**, which added masking of write-only
   configuration fields on the semantic-layer read endpoints. That masker scans
   only the schema's **top-level** `properties`, so a secret nested inside an
   object, a discriminated union, or a list is still returned in the clear — for
   example a Snowflake `auth.password` `SecretStr` inside a `password`/`key` 
auth
   union leaks on `GET /api/v1/semantic_layer/<uuid>`.
   
   This extends #43474 (it does not replace it): the masking now walks the
   connector's published `get_configuration_schema()` **recursively**, keeping
   #43474's established behavior — mask only fields the schema marks secret
   (`writeOnly` / `SecretStr`), reveal everything else, and fail closed by 
masking
   the whole payload when the schema can't be loaded — while catching secrets at
   any depth.
   
   **What changed**
   
   - New `superset/semantic_layers/masking.py`: a schema-directed walker
     (`mask_configuration` / `unmask_configuration`) that resolves `$ref` into
     `$defs` and descends objects, unions (`anyOf`/`oneOf`/`allOf`), and lists.
     For a key described by several union variants it masks the key if **any**
     variant marks it secret.
   - `_serialize_layer` (read) and `UpdateSemanticLayerCommand`'s round-trip
     (write) now delegate to it, so masking and the masked-value passthrough
     become recursive together: a nested masked value a client echoes back on
     update is restored from the stored config, not written as the mask string.
   - **Review Finding 1**: free-form keys governed by `additionalProperties` are
     classified against every union variant, not just the first, so a variant
     marking such a key secret can't be overridden by an earlier variant that
     would reveal it.
   - **Review Finding 5**: the module docstring records the provider contract 
that
     `get_configuration_schema` / `get_runtime_schema` responses (returned to
     clients verbatim, e.g. the `runtime_schema` endpoint) must not echo
     configuration values back into the schema — masking covers the stored
     payload, not a schema built from it.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A — API masking change, no UI surface.
   
   Before: a nested/union secret (e.g. `configuration.auth.password`) is 
returned
   in the clear by the read endpoints. After: it is `XXXXXXXXXX`, like the
   top-level secrets #43474 already masked.
   
   ### TESTING INSTRUCTIONS
   
   ```
   pytest tests/unit_tests/semantic_layers/
   ```
   
   New/adapted masking unit tests to 100% package coverage: nested/union/list
   secret masking (the closed gap), reveal of undescribed and non-secret fields
   (matching #43474), the `additionalProperties`-divergence case (Finding 1), 
and
   every fail-closed path (unregistered type, schema raises, non-dict schema,
   pathological recursion depth). #43474's own `api_test`/`update_test` pass
   unchanged against the delegating functions.
   
   ### ADDITIONAL INFORMATION
   
   - [x] Required feature flags: `SEMANTIC_LAYERS` (development, default off)
   - [ ] Changes UI
   - [ ] Includes DB Migration
   - [x] Bugfix (security hardening; extends #43474)
   
   Credit: builds directly on the masking pattern and provider-schema source
   established in #43474.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to